From ab4c57b8e416c6af9297cb04d101889896fd9a92 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 10 Jun 2026 04:12:22 +0200 Subject: [PATCH] fix: wrong icons selected on size mismatch This will notably fix Firefox and Thunderbird returning a 16 px icon instead of a 48 px icon when requesting a 24 px icon --- src/lib.rs | 62 ++++++++++++++++++---------------------- src/theme/directories.rs | 4 +-- src/theme/mod.rs | 28 ++++++++++++------ 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 71a55b1..127c236 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -471,38 +471,41 @@ mod test { use std::path::PathBuf; #[test] - fn hicolor_firefox_24_png() { - let firefox = lookup("firefox").find(); + fn hicolor_thunderbird_48_png() { + let thunderbird = lookup("thunderbird").with_size(24).find(); - asserting!("Firefox contains only a 16x16 and 32x32 icon, so 16x16 should be returned") - .that(&firefox) + asserting!("thunderbird lacks a 24x24 icon, but a 48x48 icon is an ideal replacement") + .that(&thunderbird) .is_some() .is_equal_to(PathBuf::from( - "/usr/share/icons/hicolor/16x16/apps/firefox.png", + "/usr/share/icons/hicolor/48x48/apps/thunderbird.png", )); } #[test] - fn hicolor_firefox_48_png() { - let firefox = lookup("firefox").with_size(48).find(); - - asserting!("Firefox has a 48x48 icon, so that should be returned") - .that(&firefox) - .is_some() - .is_equal_to(PathBuf::from( - "/usr/share/icons/hicolor/48x48/apps/firefox.png", - )); - } - - #[test] - fn hicolor_firefox_svg_fallback_to_png() { - let firefox = lookup("firefox").force_svg().find(); + fn hicolor_libreoffice_svg() { + let libreoffice_writer = lookup("libreoffice-writer").force_svg().find(); asserting!("Lookup with no parameters should return an existing icon") - .that(&firefox) + .that(&libreoffice_writer) .is_some() .is_equal_to(PathBuf::from( - "/usr/share/icons/hicolor/16x16/apps/firefox.png", + "/usr/share/icons/hicolor/scalable/apps/libreoffice-writer.svg", + )); + } + + #[test] + fn gnome_preferences_desktop_theme() { + let preferences_desktop_theme = lookup("preferences-desktop-theme") + .force_svg() + .with_size(128) + .find(); + + asserting!("Lookup with no parameters should return an existing icon") + .that(&preferences_desktop_theme) + .is_some() + .is_equal_to(PathBuf::from( + "/usr/share/icons/gnome/256x256/apps/preferences-desktop-theme.png", )); } @@ -544,11 +547,11 @@ mod test { } #[test] - fn vscode_pixmap() { + fn local_slack() { assert_eq!( - lookup("vscode").find(), - Some(PathBuf::from("/usr/share/pixmaps/vscode.png")), - "Is VS Code installed locally on the host?" + lookup("slack").find(), + Some(PathBuf::from("/usr/share/pixmaps/slack.png")), + "Is slack installed locally on the host?" ); } @@ -574,15 +577,6 @@ mod test { ); } - #[test] - fn ubuntu_additional_drivers() { - assert_eq!( - lookup("jockey").find(), - Some(PathBuf::from("/usr/share/icons/Yaru/24x24/apps/jockey.png")), - "Is the gnome icon theme installed?" - ); - } - #[test] #[cfg(feature = "local_tests")] fn theme_lookup() { diff --git a/src/theme/directories.rs b/src/theme/directories.rs index ca38f94..7ab7d80 100644 --- a/src/theme/directories.rs +++ b/src/theme/directories.rs @@ -12,7 +12,7 @@ pub struct Directory<'a> { impl Directory<'_> { pub fn directory_size_distance(&self, size: i16, scale: i16) -> i16 { match self.type_ { - DirectoryType::Fixed => self.size * self.scale - size * scale, + DirectoryType::Fixed => (self.size * self.scale) - (size * scale), DirectoryType::Scalable => { let scaled_requested_size = size * scale; @@ -22,7 +22,7 @@ impl Directory<'_> { } else { let max_scaled_size = self.maxsize * self.scale; if scaled_requested_size < max_scaled_size { - scaled_requested_size - max_scaled_size + max_scaled_size - scaled_requested_size } else { 0 } diff --git a/src/theme/mod.rs b/src/theme/mod.rs index a73bf3c..5ae0e2d 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -55,9 +55,9 @@ impl Theme { ) } - fn try_fold_icon_path<'a>( + fn try_fold_icon_path( &self, - dir_names: Vec<(&'a str, i16, bool)>, + dir_names: Vec<(&str, i16, bool)>, name: &str, prefer_svg: bool, ) -> Option { @@ -114,14 +114,24 @@ impl Theme { ); unsorted.sort_by(|a, b| { - let ordering = if prefer_svg { - b.2.cmp(&a.2) + if prefer_svg && (a.2 || b.2) { + if a.2 == b.2 { + a.1.cmp(&b.1) + } else { + b.2.cmp(&a.2) + } + } else if a.1 == b.1 { + Ordering::Equal + } else if a.1 == 0 { + Ordering::Less + } else if b.1 == 0 { + Ordering::Greater + } else if a.1 == (size * scale) as i16 { + Ordering::Less + } else if b.1 == (size * scale) as i16 { + Ordering::Greater } else { - a.2.cmp(&b.2) - }; - match ordering { - Ordering::Equal => a.1.cmp(&b.1), - _ => ordering, + a.1.cmp(&b.1) } });