replace homebrewn image lookup with freedesktop_icon

This commit is contained in:
Alexander Mohr 2025-05-24 20:49:48 +02:00
parent 0001c2f14a
commit e39b006f71
5 changed files with 197 additions and 117 deletions

245
Cargo.lock generated
View file

@ -47,7 +47,7 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -58,7 +58,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -121,7 +121,7 @@ dependencies = [
"rustix 0.38.44",
"slab",
"tracing",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -180,7 +180,7 @@ dependencies = [
"rustix 0.38.44",
"signal-hook-registry",
"slab",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -414,13 +414,34 @@ dependencies = [
"powerfmt",
]
[[package]]
name = "dirs"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
"dirs-sys 0.4.1",
]
[[package]]
name = "dirs"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
"dirs-sys",
"dirs-sys 0.5.0",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users 0.4.6",
"windows-sys 0.48.0",
]
[[package]]
@ -431,8 +452,8 @@ checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys",
"redox_users 0.5.0",
"windows-sys 0.59.0",
]
[[package]]
@ -538,7 +559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -599,10 +620,24 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "freedesktop-file-parser"
version = "0.1.3"
source = "git+https://github.com/alexmohr/desktop_file_parser?branch=update-xdgkit#092ca1e86456099593da5d984bd6508ce0f2eba7"
source = "git+https://github.com/alexmohr/desktop_file_parser?branch=fix-format-and-clippy#2c42c2ce28f474b7b663037b344b2bee9be21ef1"
dependencies = [
"thiserror",
"xdgkit",
"freedesktop-icons",
"thiserror 2.0.12",
]
[[package]]
name = "freedesktop-icons"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95f87364ea709292a3b3f74014ce3ee78412c89807eea75a358c8e029b000994"
dependencies = [
"dirs 5.0.1",
"ini_core",
"once_cell",
"thiserror 1.0.69",
"tracing",
"xdg",
]
[[package]]
@ -809,7 +844,7 @@ dependencies = [
"gobject-sys",
"libc",
"system-deps",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -1055,6 +1090,15 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "ini_core"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a467a31a9f439b5262fa99c17084537bff57f24703d5a09a2b5c9657ec73a61"
dependencies = [
"cfg-if",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@ -1302,7 +1346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -1430,7 +1474,7 @@ dependencies = [
"pin-project-lite",
"rustix 0.38.44",
"tracing",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -1494,7 +1538,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
"serde",
]
[[package]]
@ -1583,6 +1626,17 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "redox_users"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom 0.2.16",
"libredox",
"thiserror 1.0.69",
]
[[package]]
name = "redox_users"
version = "0.5.0"
@ -1591,7 +1645,7 @@ checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [
"getrandom 0.2.16",
"libredox",
"thiserror",
"thiserror 2.0.12",
]
[[package]]
@ -1642,7 +1696,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -1655,7 +1709,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -1722,19 +1776,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_yaml"
version = "0.9.34+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
dependencies = [
"indexmap",
"itoa",
"ryu",
"serde",
"unsafe-libyaml",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -1831,7 +1872,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
dependencies = [
"quick-xml",
"thiserror",
"thiserror 2.0.12",
"windows",
"windows-version",
]
@ -1846,7 +1887,16 @@ dependencies = [
"getrandom 0.3.2",
"once_cell",
"rustix 1.0.7",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]]
@ -1855,7 +1905,18 @@ version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
"thiserror-impl 2.0.12",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
@ -1898,11 +1959,6 @@ version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
[[package]]
name = "tini"
version = "1.3.0"
source = "git+https://github.com/1sra3l/tini.git#e4169395fb5f79e8f346d9334c18e0a6496c1b9f"
[[package]]
name = "toml"
version = "0.8.22"
@ -2005,12 +2061,6 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
[[package]]
name = "utf8parse"
version = "0.2.2"
@ -2249,13 +2299,37 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
"windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
@ -2264,14 +2338,14 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
[[package]]
@ -2283,18 +2357,36 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@ -2307,24 +2399,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
@ -2366,7 +2482,7 @@ dependencies = [
"os_pipe",
"rustix 0.38.44",
"tempfile",
"thiserror",
"thiserror 2.0.12",
"tree_magic_mini",
"wayland-backend",
"wayland-client",
@ -2381,11 +2497,12 @@ dependencies = [
"anyhow",
"clap",
"crossbeam",
"dirs",
"dirs 6.0.0",
"emoji",
"env_logger",
"fasteval3",
"freedesktop-file-parser",
"freedesktop-icons",
"gdk4",
"gtk4",
"gtk4-layer-shell",
@ -2398,7 +2515,7 @@ dependencies = [
"serde",
"serde_json",
"strsim",
"thiserror",
"thiserror 2.0.12",
"toml",
"tree_magic_mini",
"which",
@ -2415,16 +2532,10 @@ dependencies = [
]
[[package]]
name = "xdgkit"
version = "3.2.3"
source = "git+https://github.com/alexmohr/xdgkit?branch=update-dependencies-and-cleanup#73599411f080df99868852494773e77177b32c29"
dependencies = [
"clap",
"quick-xml",
"serde",
"serde_yaml",
"tini",
]
name = "xdg"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546"
[[package]]
name = "xml-rs"
@ -2458,7 +2569,7 @@ dependencies = [
"serde_repr",
"tracing",
"uds_windows",
"windows-sys",
"windows-sys 0.59.0",
"winnow",
"zbus_macros",
"zbus_names",

View file

@ -35,13 +35,13 @@ env_logger = "0.11.8"
log = "0.4.27"
regex = "1.11.1"
clap = { version = "4.5.38", features = ["derive"] }
thiserror = "2.0.12"
freedesktop-icons = "0.4.0"
serde = { version = "1.0.219", features = ["derive"] }
toml = "0.8.20"
serde_json = "1.0.140"
crossbeam = "0.8.4"
libc = "0.2.171"
freedesktop-file-parser = { git = "https://github.com/alexmohr/desktop_file_parser", branch = "update-xdgkit" }
freedesktop-file-parser = { git = "https://github.com/alexmohr/desktop_file_parser", branch = "fix-format-and-clippy" }
# freedesktop-file-parser = "0.1.3"
strsim = "0.11.1"
dirs = "6.0.0"
@ -53,3 +53,4 @@ nix = { version = "0.30.0", features = ["process"] }
emoji = "0.2.1"
wl-clipboard-rs = "0.9.2"
notify-rust="4.11.7"
thiserror = "2.0.12"

View file

@ -316,7 +316,7 @@ pub struct Config {
/// Defines the image size in pixels
#[clap(long = "image-size")]
image_size: Option<i32>,
image_size: Option<u16>,
key_up: Option<String>, // todo support this
key_down: Option<String>, // todo support this
@ -367,7 +367,7 @@ pub struct Config {
impl Config {
#[must_use]
pub fn image_size(&self) -> i32 {
pub fn image_size(&self) -> u16 {
self.image_size.unwrap_or(32)
}

View file

@ -26,46 +26,8 @@ pub fn known_image_extension_regex_pattern() -> Regex {
.expect("Internal image regex is not valid anymore.")
}
/// Read an icon from a shared directory
/// * /usr/local/share/icon
/// * /usr/share/icons
/// * /usr/share/pixmaps
/// * $HOME/.local/share/icon (if exists)
/// # Errors
///
/// Will return `Err`
/// * if it was not able to find any icon
pub fn fetch_icon_from_common_dirs(icon_name: &str) -> Result<String, Error> {
let mut paths = vec![
PathBuf::from("/usr/local/share/icons"),
PathBuf::from("/usr/share/icons"),
PathBuf::from("/usr/share/pixmaps"),
];
if let Some(home) = dirs::home_dir() {
paths.push(home.join(".local/share/icons"));
}
let formatted_name = Regex::new(icon_name);
if let Ok(formatted_name) = formatted_name {
paths
.into_iter()
.filter(|dir| dir.exists())
.find_map(|dir| {
find_file_via_regex(dir.as_path(), &formatted_name)
.and_then(|files| files.first().map(|f| f.to_string_lossy().into_owned()))
})
.ok_or(Error::MissingIcon)
} else {
Err(Error::ParsingError(
"Failed to get formatted icon, likely the internal regex did not parse properly"
.to_string(),
))
}
}
/// Helper function to retrieve a file with given regex.
fn find_file_via_regex(folder: &Path, file_name: &Regex) -> Option<Vec<PathBuf>> {
fn find_files(folder: &Path, file_name: &Regex) -> Option<Vec<PathBuf>> {
if !folder.exists() || !folder.is_dir() {
return None;
}
@ -120,7 +82,7 @@ pub fn find_desktop_files() -> Vec<DesktopFile> {
let p: Vec<_> = paths
.into_par_iter()
.filter(|desktop_dir| desktop_dir.exists())
.filter_map(|icon_dir| find_file_via_regex(&icon_dir, regex))
.filter_map(|desktop_dir| find_files(&desktop_dir, regex))
.flat_map(|desktop_files| {
desktop_files.into_par_iter().filter_map(|desktop_file| {
fs::read_to_string(desktop_file)

View file

@ -25,11 +25,13 @@ use gtk4_layer_shell::{Edge, KeyboardMode, LayerShell};
use log;
use regex::Regex;
use crate::config::{
Anchor, Config, CustomKeyHintLocation, KeyDetectionType, MatchMethod, SortOrder, WrapMode,
use crate::{
Error, config,
config::{
Anchor, Config, CustomKeyHintLocation, KeyDetectionType, MatchMethod, SortOrder, WrapMode,
},
desktop::known_image_extension_regex_pattern,
};
use crate::desktop::known_image_extension_regex_pattern;
use crate::{Error, config, desktop};
type ArcMenuMap<T> = Arc<RwLock<HashMap<FlowBoxChild, MenuItem<T>>>>;
type ArcProvider<T> = Arc<Mutex<dyn ItemProvider<T> + Send>>;
@ -1386,7 +1388,11 @@ fn lookup_icon(icon_path: Option<&str>, config: &Config) -> Option<Image> {
let image = if image_path.starts_with('/') {
Image::from_file(image_path)
} else if img_regex.unwrap().is_match(image_path) {
if let Ok(img) = desktop::fetch_icon_from_common_dirs(image_path) {
if let Some(img) = freedesktop_icons::lookup(image_path)
.with_size(config.image_size())
.with_scale(1)
.find()
{
Image::from_file(img)
} else {
Image::from_icon_name(image_path)
@ -1395,7 +1401,7 @@ fn lookup_icon(icon_path: Option<&str>, config: &Config) -> Option<Image> {
Image::from_icon_name(image_path)
};
image.set_pixel_size(config.image_size());
image.set_pixel_size(i32::from(config.image_size()));
Some(image)
} else {
None