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
This commit is contained in:
nilltadios 2025-12-17 09:46:57 -05:00 committed by Jacob Kauffmann
parent d9b6404f1b
commit 0af3d12e9e

View file

@ -630,6 +630,17 @@ fn get_desktop_file_icon(path: &Path) -> Option<String> {
.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<String>, Option<String>) {
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 {
(