From 73cb0b7e21331c07b7db680e6063b66c534367f7 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 12 Jun 2026 11:39:28 +0000 Subject: [PATCH] fix(linux): install SVG icon to XDG hicolor theme so "Open with" shows the icon The .desktop file used a named icon (Icon=io.github.HakanSeven12.OpenCadStudio) but the icon file was never written to the XDG icon theme directory, so file managers and the "Open with" picker fell back to a generic blank document icon. install_icon() now writes assets/logo.svg (embedded at compile time) to ~/.local/share/icons/hicolor/scalable/apps/{APP_ID}.svg alongside the .desktop file, and runs gtk-update-icon-cache so the change is picked up immediately. The write is skipped when the on-disk file is already identical. https://claude.ai/code/session_01DFVSKgViFaxEjZD2KsTdtt --- src/io/file_association.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/io/file_association.rs b/src/io/file_association.rs index 722da5202..c9e85b45d 100644 --- a/src/io/file_association.rs +++ b/src/io/file_association.rs @@ -367,6 +367,9 @@ mod linux_impl { std::fs::create_dir_all(&apps).map_err(|e| e.to_string())?; std::fs::write(&desktop_path, &contents).map_err(|e| e.to_string())?; + + install_icon()?; + // Best-effort: refresh the MIME→app cache. Absent on minimal systems. let _ = std::process::Command::new("update-desktop-database") .arg(&apps) @@ -374,6 +377,34 @@ mod linux_impl { Ok(()) } + /// Write the app SVG icon into the user's hicolor icon theme so that the + /// named `Icon={APP_ID}` entry in the .desktop file resolves correctly in + /// file managers and the "Open with" picker. Skipped when the icon is + /// already up-to-date; best-effort icon-cache refresh afterwards. + fn install_icon() -> Result<(), String> { + static LOGO_SVG: &[u8] = include_bytes!("../../assets/logo.svg"); + + let icon_dir = data_home()?.join("icons/hicolor/scalable/apps"); + let icon_path = icon_dir.join(format!("{APP_ID}.svg")); + + // Skip write when the on-disk file is already identical. + if std::fs::read(&icon_path).ok().as_deref() == Some(LOGO_SVG) { + return Ok(()); + } + + std::fs::create_dir_all(&icon_dir).map_err(|e| e.to_string())?; + std::fs::write(&icon_path, LOGO_SVG).map_err(|e| e.to_string())?; + + // Refresh the icon cache so desktop environments pick up the new file. + let hicolor = data_home() + .map(|d| d.join("icons/hicolor")) + .unwrap_or_default(); + let _ = std::process::Command::new("gtk-update-icon-cache") + .args(["--force", "--quiet", &hicolor.to_string_lossy()]) + .status(); + Ok(()) + } + fn data_home() -> Result { std::env::var_os("XDG_DATA_HOME") .map(PathBuf::from)