feat(mime_app): show related apps in open with dropdown in preview

This commit is contained in:
Michael Aaron Murphy 2026-06-11 18:45:49 +02:00
parent eda8291678
commit e8fdb28a24
No known key found for this signature in database
GPG key ID: B2732D4240C9212C
3 changed files with 55 additions and 34 deletions

View file

@ -3180,7 +3180,7 @@ impl Application for App {
selected,
..
} => {
let available_apps = self.mime_app_cache.get_apps_for_mime(&mime);
let available_apps = self.mime_app_cache.get_apps_for_mime(&mime, true);
if let Some((app, _)) = available_apps.get(selected) {
if let Some(mut command) =
@ -5918,7 +5918,7 @@ impl Application for App {
};
let mut column = widget::list_column();
let available_apps = self.mime_app_cache.get_apps_for_mime(mime);
let available_apps = self.mime_app_cache.get_apps_for_mime(mime, true);
let item_height = 32.0;
let mut displayed_default = false;
let mut last_kind = MimeAppMatch::Exact;

View file

@ -252,7 +252,11 @@ impl MimeAppCache {
mime_app_cache
}
pub fn get_apps_for_mime(&self, mime_type: &Mime) -> Vec<(&Arc<MimeApp>, MimeAppMatch)> {
pub fn get_apps_for_mime(
&self,
mime_type: &Mime,
include_other: bool,
) -> Vec<(&Arc<MimeApp>, MimeAppMatch)> {
let mut results = Vec::new();
let mut dedupe = FxHashSet::default();
@ -291,6 +295,7 @@ impl MimeAppCache {
}
}
if include_other {
results.extend({
let mut apps = self
.apps()
@ -304,6 +309,7 @@ impl MimeAppCache {
});
apps
});
}
results
}
@ -411,15 +417,28 @@ impl MimeAppCache {
// Sort cached apps for this mime by default precedence.
for default in defaults.into_iter().flatten() {
let default = default.strip_suffix(".desktop").unwrap_or(default.as_ref());
let mut found_any = false;
apps.retain(|app| {
let found = app.id.as_str() == default;
if found {
app.is_default.write().unwrap().insert(default.into());
app.is_default
.write()
.unwrap()
.insert(mime.essence_str().into());
cache.push(app.clone());
found_any = true;
}
!found
});
if !found_any && let Some(app) = self.apps.iter().find(|app| app.id == default) {
app.is_default
.write()
.unwrap()
.insert(mime.essence_str().into());
cache.push(app.clone());
}
}
// Sort remaining apps by name

View file

@ -2368,23 +2368,24 @@ impl Item {
)));
let mut settings = Vec::new();
if let Some(mime_app_cache) = mime_app_cache_opt {
let mime_apps = mime_app_cache.get(&self.mime);
let mime_apps = mime_app_cache.get_apps_for_mime(&self.mime, false);
if !mime_apps.is_empty() {
let (names, icons) = mime_apps
.iter()
.map(|(app, _)| (Cow::Owned(app.name.clone()), app.icon()))
.collect::<(Vec<_>, Vec<_>)>();
settings.push(
widget::settings::item::builder(fl!("open-with")).control(
Element::from(
widget::dropdown(
mime_apps
.iter()
.map(|app| Cow::Owned(app.name.clone()))
.collect::<Vec<Cow<'static, str>>>(),
mime_apps.iter().position(|x| x.is_default(&self.mime)),
names,
mime_apps.iter().position(|(x, _)| x.is_default(&self.mime)),
move |index| index,
)
.icons(Cow::Owned(mime_app_cache.icons(&self.mime))),
.icons(Cow::Owned(icons)),
)
.map(|index| {
let mime_app = &mime_apps[index];
.map(move |index| {
let mime_app = &mime_apps[index].0;
Message::SetOpenWith(self.mime.clone(), mime_app.id.clone())
}),
),
@ -6451,24 +6452,25 @@ impl Tab {
.and_then(|(mime, _)| mime.parse::<Mime>().ok())
&& let Some(mime_app_cache) = mime_app_cache_opt
{
let mime_apps = mime_app_cache.get(&mime);
let mime_apps = mime_app_cache.get_apps_for_mime(&mime, false);
if !mime_apps.is_empty() {
let mime_closure = mime.clone();
let (names, icons) = mime_apps
.iter()
.map(|(app, _)| (Cow::Owned(app.name.clone()), app.icon()))
.collect::<(Vec<_>, Vec<_>)>();
settings.push(
widget::settings::item::builder(fl!("open-with")).control(
Element::from(
widget::dropdown(
mime_apps
.iter()
.map(|app| Cow::Owned(app.name.clone()))
.collect::<Vec<Cow<'static, str>>>(),
mime_apps.iter().position(|x| x.is_default(&mime)),
names,
mime_apps.iter().position(|(x, _)| x.is_default(&mime)),
move |index| (index, mime_closure.clone()),
)
.icons(Cow::Owned(mime_app_cache.icons(&mime))),
.icons(Cow::Owned(icons)),
)
.map(|(index, mime)| {
let mime_app = &mime_apps[index];
.map(move |(index, mime)| {
let mime_app = &mime_apps[index].0;
Message::SetOpenWith(mime, mime_app.id.clone())
}),
),