diff --git a/src/app.rs b/src/app.rs index b00f719..292bb83 100644 --- a/src/app.rs +++ b/src/app.rs @@ -2307,7 +2307,7 @@ impl App { .mime_app_cache .apps() .iter() - .filter(|mime_app| !mime_app.no_display) + .filter(|mime_app| !mime_app.no_display()) .filter(|&mime_app| dedupe.insert(&mime_app.id)) .map(|mime_app| (mime_app, MimeAppMatch::Other)) .collect::>(); @@ -5992,7 +5992,7 @@ impl Application for App { widget::mouse_area( widget::button::custom( widget::row::with_children([ - icon(app.icon.clone()).size(32).into(), + icon(app.icon()).size(32).into(), if app.is_default() && !displayed_default { displayed_default = true; widget::text::body(fl!( diff --git a/src/mime_app.rs b/src/mime_app.rs index 6038149..f1f643c 100644 --- a/src/mime_app.rs +++ b/src/mime_app.rs @@ -182,9 +182,10 @@ pub struct MimeApp { pub path: Option, pub name: String, pub exec: Option, - pub icon: widget::icon::Handle, + icon_name: Box, + icon: std::sync::OnceLock, is_default: Arc, - pub no_display: bool, + no_display: Arc, } impl MimeApp { @@ -199,7 +200,24 @@ impl MimeApp { } pub fn is_default(&self) -> bool { - self.is_default.load(atomic::Ordering::SeqCst) + self.is_default.load(atomic::Ordering::Relaxed) + } + + pub fn no_display(&self) -> bool { + self.no_display.load(atomic::Ordering::Relaxed) + } + + pub fn icon(&self) -> widget::icon::Handle { + self.icon + .get_or_init(|| { + let name = &*self.icon_name; + if name.starts_with('/') { + cosmic::widget::icon::from_path(PathBuf::from(name)) + } else { + cosmic::widget::icon::from_name(name).size(32).handle() + } + }) + .clone() } } @@ -213,7 +231,6 @@ impl AsRef for MimeApp { pub struct MimeAppCache { apps: Vec>, cache: FxHashMap>>, - icons: FxHashMap>, terminals: Vec>, } @@ -222,7 +239,6 @@ impl MimeAppCache { let mut mime_app_cache = Self { apps: Vec::new(), cache: FxHashMap::default(), - icons: FxHashMap::default(), terminals: Vec::new(), }; mime_app_cache.reload(); @@ -243,7 +259,6 @@ impl MimeAppCache { self.apps.clear(); self.cache.clear(); - self.icons.clear(); self.terminals.clear(); let mut list = cosmic_mime_apps::List::default(); @@ -263,18 +278,10 @@ impl MimeAppCache { path: Some(desktop_entry.path.clone()), name: name.into(), exec: desktop_entry.exec().map(String::from), - icon: { - let icon = desktop_entry.icon().unwrap_or_default(); - if icon.starts_with('/') { - cosmic::widget::icon::from_path(PathBuf::from(icon)) - } else { - cosmic::widget::icon::from_name(icon).size(32).handle() - } - }, + icon_name: desktop_entry.icon().unwrap_or_default().into(), + icon: std::sync::OnceLock::new(), is_default: Arc::new(AtomicBool::new(false)), - no_display: desktop_entry - .mime_type() - .is_none_or(|supported| supported.is_empty()), + no_display: Arc::new(AtomicBool::new(false)), }); tracing::info!(target: "mime-apps", id = app.id, "detected desktop entry"); @@ -359,14 +366,18 @@ impl MimeAppCache { tracing::debug!(target: "mime-apps", mime = mime.essence_str(), apps = ?(cache.iter().map(|app| &*app.id).collect::>()), "mime defaults found") } - // Copy icons to special cache - //TODO: adjust dropdown API so this is no longer needed - self.icons.extend(self.cache.iter().map(|(mime, apps)| { - ( - mime.clone(), - apps.iter().map(|app| app.icon.clone()).collect(), - ) - })); + let associated: rustc_hash::FxHashSet<&str> = self + .cache + .values() + .flatten() + .map(|app| app.id.as_str()) + .collect(); + for app in &self.apps { + app.no_display.store( + !associated.contains(app.id.as_str()), + atomic::Ordering::Relaxed, + ); + } let elapsed = start.elapsed(); tracing::info!(target: "mime-apps", "loaded mime app cache in {elapsed:?}"); @@ -380,8 +391,10 @@ impl MimeAppCache { self.cache.get(key).map_or(&[], Vec::as_slice) } - pub fn icons(&self, key: &Mime) -> &[widget::icon::Handle] { - self.icons.get(key).map_or(&[], Box::as_ref) + pub fn icons(&self, key: &Mime) -> Vec { + self.cache + .get(key) + .map_or_else(Vec::new, |apps| apps.iter().map(|app| app.icon()).collect()) } fn get_default_terminal(&self) -> Option { diff --git a/src/tab.rs b/src/tab.rs index 185a258..0aaaddc 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -2381,7 +2381,7 @@ impl Item { mime_apps.iter().position(|x| x.is_default()), move |index| index, ) - .icons(Cow::Borrowed(mime_app_cache.icons(&self.mime))), + .icons(Cow::Owned(mime_app_cache.icons(&self.mime))), ) .map(|index| { let mime_app = &mime_apps[index]; @@ -6465,7 +6465,7 @@ impl Tab { mime_apps.iter().position(|x| x.is_default()), move |index| (index, mime_closure.clone()), ) - .icons(Cow::Borrowed(mime_app_cache.icons(&mime))), + .icons(Cow::Owned(mime_app_cache.icons(&mime))), ) .map(|(index, mime)| { let mime_app = &mime_apps[index];