Extract and apply StartupWMClass for proper taskbar icons
Parse StartupWMClass from embedded .desktop entries during analysis, store in DB, include in generated .desktop files. Detail view shows an editable WM class field with apply button for manual override.
This commit is contained in:
@@ -133,6 +133,11 @@ pub fn run_background_analysis(id: i64, path: PathBuf, appimage_type: AppImageTy
|
||||
Some(meta.screenshot_urls.join("\n"))
|
||||
};
|
||||
|
||||
// Store StartupWMClass
|
||||
if let Some(ref wm_class) = meta.startup_wm_class {
|
||||
db.set_startup_wm_class(id, Some(wm_class)).ok();
|
||||
}
|
||||
|
||||
if let Err(e) = db.update_appstream_metadata(
|
||||
id,
|
||||
meta.appstream_id.as_deref(),
|
||||
|
||||
@@ -1754,6 +1754,14 @@ impl Database {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_startup_wm_class(&self, id: i64, wm_class: Option<&str>) -> SqlResult<()> {
|
||||
self.conn.execute(
|
||||
"UPDATE appimages SET startup_wm_class = ?2 WHERE id = ?1",
|
||||
params![id, wm_class],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// --- Launch statistics ---
|
||||
|
||||
pub fn get_top_launched(&self, limit: i32) -> SqlResult<Vec<(String, u64)>> {
|
||||
|
||||
@@ -61,6 +61,7 @@ pub struct AppImageMetadata {
|
||||
pub desktop_actions: Vec<String>,
|
||||
pub has_signature: bool,
|
||||
pub screenshot_urls: Vec<String>,
|
||||
pub startup_wm_class: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -76,6 +77,7 @@ struct DesktopEntryFields {
|
||||
mime_types: Vec<String>,
|
||||
terminal: bool,
|
||||
x_appimage_name: Option<String>,
|
||||
startup_wm_class: Option<String>,
|
||||
actions: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -367,6 +369,7 @@ fn parse_desktop_entry(content: &str) -> DesktopEntryFields {
|
||||
}
|
||||
"Terminal" => fields.terminal = value == "true",
|
||||
"X-AppImage-Name" => fields.x_appimage_name = Some(value.to_string()),
|
||||
"StartupWMClass" => fields.startup_wm_class = Some(value.to_string()),
|
||||
"Actions" => {
|
||||
fields.actions = value
|
||||
.split(';')
|
||||
@@ -814,6 +817,7 @@ pub fn inspect_appimage(
|
||||
.as_ref()
|
||||
.map(|a| a.screenshot_urls.clone())
|
||||
.unwrap_or_default(),
|
||||
startup_wm_class: fields.startup_wm_class,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1033,6 +1033,28 @@ fn build_system_tab(record: &AppImageRecord, db: &Rc<Database>, toast_overlay: &
|
||||
});
|
||||
integration_group.add(&autostart_row);
|
||||
|
||||
// StartupWMClass row with editable override
|
||||
let wm_class_row = adw::EntryRow::builder()
|
||||
.title("StartupWMClass")
|
||||
.text(record.startup_wm_class.as_deref().unwrap_or(""))
|
||||
.show_apply_button(true)
|
||||
.build();
|
||||
let db_wm = db.clone();
|
||||
let record_id_wm = record.id;
|
||||
let toast_wm = toast_overlay.clone();
|
||||
wm_class_row.connect_apply(move |row| {
|
||||
let text = row.text().to_string();
|
||||
let value = if text.is_empty() { None } else { Some(text.as_str()) };
|
||||
match db_wm.set_startup_wm_class(record_id_wm, value) {
|
||||
Ok(()) => toast_wm.add_toast(adw::Toast::new("WM class updated")),
|
||||
Err(e) => {
|
||||
log::error!("Failed to set WM class: {}", e);
|
||||
toast_wm.add_toast(adw::Toast::new("Failed to update WM class"));
|
||||
}
|
||||
}
|
||||
});
|
||||
integration_group.add(&wm_class_row);
|
||||
|
||||
inner.append(&integration_group);
|
||||
|
||||
// Version Rollback group
|
||||
|
||||
Reference in New Issue
Block a user