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
This commit is contained in:
Claude committed 2026-06-12 11:39:28 +00:00
1 parent 37ef813814
commit 73cb0b7e21
1 file changed
+31
+31
View File
@@ -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<PathBuf, String> {
std::env::var_os("XDG_DATA_HOME")
.map(PathBuf::from)