From 0af3d12e9e1dda98ac348e7de52734fea9cb7e2d Mon Sep 17 00:00:00 2001 From: nilltadios Date: Wed, 17 Dec 2025 09:46:57 -0500 Subject: [PATCH] fix: support absolute paths in .desktop file Icon field Per the FreeDesktop Desktop Entry spec, the Icon field can be either an icon name (looked up in the theme) or an absolute path to an image. Previously, all Icon values were passed to `widget::icon::from_name()`, which only works for icon names. This adds a `desktop_icon_handle()` helper that checks if the path is absolute and exists, using `widget::icon::from_path()` for absolute paths and `widget::icon::from_name()` for icon names. Fixes: https://github.com/pop-os/cosmic-epoch/issues/2697 --- src/tab.rs | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/tab.rs b/src/tab.rs index c744608..ffde2ac 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -630,6 +630,17 @@ fn get_desktop_file_icon(path: &Path) -> Option { .map(str::to_string) } +/// Creates an icon handle from a desktop file's Icon field value. +/// Supports both icon names (looked up in theme) and absolute paths (used directly). +fn desktop_icon_handle(icon: &str, size: u16) -> widget::icon::Handle { + let icon_path = Path::new(icon); + if icon_path.is_absolute() && icon_path.exists() { + widget::icon::from_path(icon_path.to_path_buf()) + } else { + widget::icon::from_name(icon).size(size).handle() + } +} + pub fn parse_desktop_file(path: &Path) -> (Option, Option) { let entry = match freedesktop_entry_parser::parse_entry(path) { Ok(ok) => ok, @@ -693,15 +704,9 @@ pub fn item_from_gvfs_info(path: PathBuf, file_info: gio::FileInfo, sizes: IconS if let Some(icon_name) = icon_name_opt { ( mime, - widget::icon::from_name(&*icon_name) - .size(sizes.grid()) - .handle(), - widget::icon::from_name(&*icon_name) - .size(sizes.list()) - .handle(), - widget::icon::from_name(&*icon_name) - .size(sizes.list_condensed()) - .handle(), + desktop_icon_handle(&icon_name, sizes.grid()), + desktop_icon_handle(&icon_name, sizes.list()), + desktop_icon_handle(&icon_name, sizes.list_condensed()), ) } else { ( @@ -828,15 +833,9 @@ pub fn item_from_entry( if let Some(icon_name) = icon_name_opt { ( mime, - widget::icon::from_name(&*icon_name) - .size(sizes.grid()) - .handle(), - widget::icon::from_name(&*icon_name) - .size(sizes.list()) - .handle(), - widget::icon::from_name(icon_name) - .size(sizes.list_condensed()) - .handle(), + desktop_icon_handle(&icon_name, sizes.grid()), + desktop_icon_handle(&icon_name, sizes.list()), + desktop_icon_handle(&icon_name, sizes.list_condensed()), ) } else { (