Merge pull request #88 from HakanSeven12/claude/fix-open-with-icon-linux

fix(linux): show app icon in "Open with" picker
This commit is contained in:
Hakan Seven authored and GitHub committed 2026-06-12 14:44:05 +03:00
commit e07aae60f0
2 files changed
+71 -2

No files matched your search

+37 -2
View File
@@ -112,13 +112,48 @@
next association query without a forced refresh.
-->
<Component Id='DefaultPrograms' Guid='6f3e9b2a-1c4d-4f8a-9b7e-2d5a8c1f0e63' Win64='yes'>
<!--
Applications\<exename>\DefaultIcon is what Windows shows in the
"Open with" context-menu list and "Choose another app" picker.
Without it the entry appears with a blank generic document icon.
-->
<RegistryValue
Root='HKLM'
Key='SOFTWARE\Classes\Applications\OpenCADStudio.exe\DefaultIcon'
Name=''
Type='string'
Value='[APPLICATIONROOTDIRECTORY]OpenCADStudio.exe,0'
KeyPath='yes' />
<RegistryValue
Root='HKLM'
Key='SOFTWARE\Classes\Applications\OpenCADStudio.exe'
Name='FriendlyAppName'
Type='string'
Value='Open CAD Studio' />
<RegistryValue
Root='HKLM'
Key='SOFTWARE\Classes\Applications\OpenCADStudio.exe\shell\open\command'
Name=''
Type='string'
Value='"[APPLICATIONROOTDIRECTORY]OpenCADStudio.exe" "%1"' />
<RegistryValue
Root='HKLM'
Key='SOFTWARE\Classes\Applications\OpenCADStudio.exe\SupportedTypes'
Name='.dwg'
Type='string'
Value='' />
<RegistryValue
Root='HKLM'
Key='SOFTWARE\Classes\Applications\OpenCADStudio.exe\SupportedTypes'
Name='.dxf'
Type='string'
Value='' />
<RegistryValue
Root='HKLM'
Key='Software\Open CAD Studio\Capabilities'
Name='ApplicationName'
Type='string'
Value='Open CAD Studio'
KeyPath='yes' />
Value='Open CAD Studio' />
<RegistryValue
Root='HKLM'
Key='Software\Open CAD Studio\Capabilities'
+34
View File
@@ -264,6 +264,9 @@ mod windows_impl {
&format!("\"{exe}\" \"%1\""),
)?;
set_string(APP_BASE, Some("FriendlyAppName"), "Open CAD Studio")?;
// DefaultIcon is what Windows uses to show the app icon in the
// "Open with" context-menu list and the "Choose another app" picker.
set_string(&format!(r"{APP_BASE}\DefaultIcon"), None, &format!("\"{exe}\",0"))?;
// Listing the extensions under SupportedTypes is what makes the app
// appear in the "Open with → Choose another app" picker for them.
set_string(&format!(r"{APP_BASE}\SupportedTypes"), Some(".dwg"), "")?;
@@ -367,6 +370,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 +380,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)