From 84f827e7e2bb51c95c83c5236f9603b92f003553 Mon Sep 17 00:00:00 2001 From: Simon Garnier Date: Wed, 4 Feb 2026 20:07:21 -0800 Subject: [PATCH] deps: use freedesktop-icons instead of tux-icons ### Problem I tried this plugin on my nixos desktop and while the app opening worked correctly, the icon for the app was not showing correctly. ### Solution using the freedesktop version makes it so we get standard handling of icons for desktop entry. By leveraging the standard, we get wider support out of the box (which means that the plugins works on nixos). We also can now select the preferred dimension for the icon, which tux-icons did not offer. This lead to some icons being pixelated since tux-icons returned the first match. I chose 256 as the resolution because it looked correct on my stream deck, but I'm happy to tweak this or even expose it as a setting down the line. ### Testing - Tested and working on my physical stream deck hooked to my nixos desktop. --- Cargo.toml | 2 +- src/main.rs | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a334204..05ea875 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,6 @@ serde_json = "1.0" tokio = { version = "1.48", features = ["rt-multi-thread", "macros"] } base64 = "0.22" freedesktop-desktop-entry = "0.8" -tux-icons = "0.4" +freedesktop-icons = "0.4.0" log = "0.4" simplelog = "0.12" diff --git a/src/main.rs b/src/main.rs index 3c6d24d..b5b2b5e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,12 @@ use std::fs; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use base64::{Engine as _, engine::general_purpose}; use freedesktop_desktop_entry::{DesktopEntry, Iter, default_paths}; +use freedesktop_icons::lookup; use openaction::*; use serde::{Deserialize, Serialize}; -use tux_icons::icon_fetcher::IconFetcher; fn is_flatpak() -> bool { use std::env::var; @@ -70,12 +70,19 @@ impl Action for LaunchAppAction { } } +fn get_icon_path_from_desktop_entry(desktop_entry_path: impl Into) -> Option { + let locales: &[&str] = &[]; + let entry = DesktopEntry::from_path(desktop_entry_path, locales.into()).ok()?; + let icon = entry.icon()?.to_owned(); + lookup(&icon).with_size(256).find() +} + async fn update_icon(instance: &Instance, settings: &LaunchAppSettings) -> OpenActionResult<()> { let icon = settings .app .as_deref() .filter(|s| !s.is_empty()) - .and_then(|path| IconFetcher::new().get_icon_path_from_desktop(path)) + .and_then(get_icon_path_from_desktop_entry) .and_then(|path| icon_to_base64(&path)) .unwrap_or_else(|| "icon".to_owned());