fix(default-apps): additional missing apps
This commit is contained in:
parent
2e83e56c09
commit
de5e16d360
3 changed files with 93 additions and 123 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
|
@ -288,7 +288,7 @@ version = "1.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -299,7 +299,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstyle",
|
"anstyle",
|
||||||
"once_cell_polyfill",
|
"once_cell_polyfill",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1471,7 +1471,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cosmic-mime-apps"
|
name = "cosmic-mime-apps"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/pop-os/cosmic-mime-apps#a95c8043a7b41ca3c143a1fad5b3b8a5a3411008"
|
source = "git+https://github.com/pop-os/cosmic-mime-apps#8fc81e8857e46c018ea21ab985aaf30ac853c007"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"freedesktop-desktop-entry",
|
"freedesktop-desktop-entry",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
|
@ -2173,7 +2173,7 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -2357,7 +2357,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4148,7 +4148,7 @@ dependencies = [
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
"portable-atomic-util",
|
"portable-atomic-util",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -4490,7 +4490,7 @@ version = "1.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a1886916523694cd6ea3d175f03a1e5010699a2a4cc13696d83d7bea1d80638"
|
checksum = "7a1886916523694cd6ea3d175f03a1e5010699a2a4cc13696d83d7bea1d80638"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -5188,7 +5188,7 @@ version = "0.50.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -6564,7 +6564,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.12.1",
|
"linux-raw-sys 0.12.1",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -6994,7 +6994,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
|
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -7236,7 +7236,7 @@ dependencies = [
|
||||||
"getrandom 0.4.2",
|
"getrandom 0.4.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.1.4",
|
"rustix 1.1.4",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -7636,7 +7636,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -8353,7 +8353,7 @@ version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,6 @@ iced_winit.workspace = true
|
||||||
locale1 = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
locale1 = { git = "https://github.com/pop-os/dbus-settings-bindings", optional = true }
|
||||||
sysinfo = { version = "=0.38.0", optional = true }
|
sysinfo = { version = "=0.38.0", optional = true }
|
||||||
mime-apps = { package = "cosmic-mime-apps", git = "https://github.com/pop-os/cosmic-mime-apps", features = ["tokio"], optional = true }
|
mime-apps = { package = "cosmic-mime-apps", git = "https://github.com/pop-os/cosmic-mime-apps", features = ["tokio"], optional = true }
|
||||||
# mime-apps = { package = "cosmic-mime-apps", path = "../../../cosmic-mime-apps", features = ["tokio"], optional = true }
|
|
||||||
notify = "8.2.0"
|
notify = "8.2.0"
|
||||||
regex = "1.12.3"
|
regex = "1.12.3"
|
||||||
ron = "0.12"
|
ron = "0.12"
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,11 @@ use cosmic_config::{ConfigGet, ConfigSet};
|
||||||
use cosmic_settings_config::shortcuts::SystemActions;
|
use cosmic_settings_config::shortcuts::SystemActions;
|
||||||
use cosmic_settings_config::shortcuts::action::System;
|
use cosmic_settings_config::shortcuts::action::System;
|
||||||
use cosmic_settings_page::{self as page, Section, section};
|
use cosmic_settings_page::{self as page, Section, section};
|
||||||
use freedesktop_desktop_entry::{
|
use freedesktop_desktop_entry::{DesktopEntry, default_paths, get_languages_from_env};
|
||||||
DesktopEntry, Iter as DesktopEntryIter, default_paths, get_languages_from_env,
|
|
||||||
};
|
|
||||||
use mime::Mime;
|
use mime::Mime;
|
||||||
use mime_apps::App;
|
|
||||||
use slotmap::SlotMap;
|
use slotmap::SlotMap;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::BTreeSet;
|
||||||
use std::io::SeekFrom;
|
use std::io::SeekFrom;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
@ -76,7 +73,7 @@ pub struct CachedMimeApps {
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AppMeta {
|
pub struct AppMeta {
|
||||||
selected: Option<usize>,
|
selected: Option<usize>,
|
||||||
app_ids: Vec<String>,
|
app_ids: Vec<Box<str>>,
|
||||||
apps: Vec<String>,
|
apps: Vec<String>,
|
||||||
icons: Vec<icon::Handle>,
|
icons: Vec<icon::Handle>,
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +123,7 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
|
|
||||||
let mut list = mime_apps::List::default();
|
let mut list = mime_apps::List::default();
|
||||||
list.load_from_paths(&mime_apps::list_paths());
|
list.load_from_paths(&mime_apps::list_paths());
|
||||||
let assocs = mime_apps::associations::by_app(&list);
|
let assocs = mime_apps::associations::load_from_disk(&list);
|
||||||
|
|
||||||
let apps = vec![
|
let apps = vec![
|
||||||
load_defaults(&list, &assocs, &["x-scheme-handler/http"]),
|
load_defaults(&list, &assocs, &["x-scheme-handler/http"]),
|
||||||
|
|
@ -135,12 +132,12 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
load_defaults(
|
load_defaults(
|
||||||
&list,
|
&list,
|
||||||
&assocs,
|
&assocs,
|
||||||
&["audio/mpeg", "application/ogg", "audio/x-flac"],
|
&["audio/mpeg", "application/ogg", "audio/x-flac", "video/mp4"],
|
||||||
),
|
),
|
||||||
load_defaults(&list, &assocs, &["video/mp4"]),
|
load_defaults(&list, &assocs, &["video/mp4"]),
|
||||||
load_defaults(&list, &assocs, &["image/png"]),
|
load_defaults(&list, &assocs, &["image/png"]),
|
||||||
load_defaults(&list, &assocs, &["text/calendar"]),
|
load_defaults(&list, &assocs, &["text/calendar"]),
|
||||||
load_terminal_apps(&assocs).await,
|
load_terminal_apps(&list, &assocs).await,
|
||||||
load_defaults(&list, &assocs, &["text/plain"]),
|
load_defaults(&list, &assocs, &["text/plain"]),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -413,64 +410,69 @@ fn assign_default_terminal(config: &cosmic_config::Config, appid: &str) {
|
||||||
|
|
||||||
fn load_defaults(
|
fn load_defaults(
|
||||||
list: &mime_apps::List,
|
list: &mime_apps::List,
|
||||||
assocs: &BTreeMap<Arc<str>, Arc<App>>,
|
assocs: &mime_apps::Associations,
|
||||||
for_mimes: &[&str],
|
for_mimes: &[&str],
|
||||||
) -> AppMeta {
|
) -> AppMeta {
|
||||||
let mut unsorted = Vec::new();
|
let mut unsorted = Vec::new();
|
||||||
let mut current_app = None;
|
let mut default_app = None;
|
||||||
|
|
||||||
for for_mime in for_mimes {
|
for for_mime in for_mimes {
|
||||||
let Ok(mime) = Mime::from_str(for_mime) else {
|
let Ok(mime) = Mime::from_str(for_mime) else {
|
||||||
return AppMeta {
|
continue;
|
||||||
selected: None,
|
|
||||||
app_ids: Vec::new(),
|
|
||||||
apps: Vec::new(),
|
|
||||||
icons: Vec::new(),
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_app_entry = dbg!(
|
for default in list.default_app_for(&mime).into_iter().flatten() {
|
||||||
list.default_app_for(&mime)
|
let appid = default.strip_suffix(".desktop").unwrap_or(default.as_ref());
|
||||||
.and_then(|entries| entries.first())
|
|
||||||
);
|
|
||||||
|
|
||||||
tracing::info!(target: "default-apps", ?mime, ?current_app_entry, "entry for mime");
|
tracing::info!(target: "default-apps", ?mime, appid, "entry for mime");
|
||||||
let current_appid = current_app_entry
|
if default_app.is_none() {
|
||||||
.as_ref()
|
default_app = assocs.by_app_id.get(appid);
|
||||||
.and_then(|entry| entry.strip_suffix(".desktop"));
|
if default_app.is_some() {
|
||||||
|
break;
|
||||||
if unsorted.is_empty() {
|
}
|
||||||
current_app = current_appid.and_then(|appid| assocs.get(appid));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsorted.extend(
|
for (appid, app) in mime_apps::apps_for_mime(&mime, assocs) {
|
||||||
mime_apps::apps_for_mime(&mime, assocs)
|
if app.icon.is_none() {
|
||||||
.map(|(app_id, app)| (app_id.clone(), app.clone())),
|
continue;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
if unsorted.iter().any(|(id, _)| id == appid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsorted.push((appid.clone(), app.clone()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsorted.sort_unstable_by_key(|(_, app)| app.name.clone());
|
unsorted.sort_unstable_by_key(|(_, app)| app.name.clone());
|
||||||
unsorted.dedup_by_key(|(app_id, _)| app_id.clone());
|
|
||||||
|
|
||||||
let mut selected = None;
|
let mut selected = None;
|
||||||
let mut app_ids = Vec::new();
|
let mut app_ids = Vec::new();
|
||||||
let mut apps = Vec::new();
|
let mut apps = Vec::new();
|
||||||
let mut icons = Vec::new();
|
let mut icons = Vec::new();
|
||||||
|
|
||||||
for (id, (appid, app)) in unsorted.iter().enumerate() {
|
let mut id = 0;
|
||||||
if let Some(current_app) = current_app
|
for (appid, app) in unsorted.iter() {
|
||||||
&& app.name.as_ref() == current_app.name.as_ref()
|
let Some(icon) = app.icon.as_deref() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if let Some(default_app) = default_app
|
||||||
|
&& app.name.as_ref() == default_app.name.as_ref()
|
||||||
{
|
{
|
||||||
selected = Some(id);
|
selected = Some(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
app_ids.push(appid.as_ref().into());
|
app_ids.push(appid.as_ref().into());
|
||||||
apps.push(app.name.as_ref().into());
|
apps.push(app.name.as_ref().into());
|
||||||
icons.push(if app.icon.starts_with('/') {
|
icons.push(if icon.starts_with('/') {
|
||||||
icon::from_path(PathBuf::from(app.icon.as_ref()))
|
icon::from_path(PathBuf::from(icon))
|
||||||
} else {
|
} else {
|
||||||
icon::from_name(app.icon.as_ref()).size(20).handle()
|
icon::from_name(icon).size(20).handle()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
id += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppMeta {
|
AppMeta {
|
||||||
|
|
@ -481,86 +483,55 @@ fn load_defaults(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn xdg_mime_query_default(mime_type: &str) -> Option<String> {
|
async fn load_terminal_apps(list: &mime_apps::List, assocs: &mime_apps::Associations) -> AppMeta {
|
||||||
let output = tokio::process::Command::new("xdg-mime")
|
|
||||||
.args(["query", "default", mime_type])
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
.ok()?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
String::from_utf8(output.stdout)
|
|
||||||
.ok()
|
|
||||||
.map(|string| string.trim().to_owned())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn load_terminal_apps(assocs: &BTreeMap<Arc<str>, Arc<App>>) -> AppMeta {
|
|
||||||
let mut terminals = Vec::new();
|
|
||||||
let mut current_app = None;
|
|
||||||
|
|
||||||
// Get the current default terminal if set
|
|
||||||
let current_entry = xdg_mime_query_default("x-scheme-handler/terminal").await;
|
|
||||||
let current_appid = current_entry
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|entry| entry.strip_suffix(".desktop"));
|
|
||||||
|
|
||||||
// Also check x-terminal-emulator
|
|
||||||
if current_app.is_none() {
|
|
||||||
let current_entry = xdg_mime_query_default("application/x-terminal-emulator").await;
|
|
||||||
let current_appid = current_entry
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|entry| entry.strip_suffix(".desktop"));
|
|
||||||
if let Some(appid) = current_appid {
|
|
||||||
current_app = assocs.get(appid).cloned();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan desktop entries for terminal applications
|
|
||||||
for path in DesktopEntryIter::new(default_paths()) {
|
|
||||||
if let Ok(bytes) = std::fs::read_to_string(&path)
|
|
||||||
&& let Ok(entry) = DesktopEntry::from_str(&path, &bytes, None::<&[&str]>)
|
|
||||||
{
|
|
||||||
// Check if it's a terminal application
|
|
||||||
if entry
|
|
||||||
.categories()
|
|
||||||
.map(|cats| cats.contains(&"TerminalEmulator"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
let id = entry.id();
|
|
||||||
if let Some(app) = assocs.get(id) {
|
|
||||||
if current_appid.as_ref().map(|c| *c == id).unwrap_or(false) {
|
|
||||||
current_app = Some(app.clone());
|
|
||||||
}
|
|
||||||
terminals.push((Arc::from(id), app.clone()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
terminals.sort_unstable_by_key(|(_, app): &(Arc<str>, Arc<App>)| app.name.clone());
|
|
||||||
terminals.dedup_by(|a, b| a.0 == b.0);
|
|
||||||
|
|
||||||
let mut selected = None;
|
let mut selected = None;
|
||||||
let mut app_ids = Vec::new();
|
let mut app_ids = Vec::new();
|
||||||
let mut apps = Vec::new();
|
let mut apps = Vec::new();
|
||||||
let mut icons = Vec::new();
|
let mut icons = Vec::new();
|
||||||
|
|
||||||
for (id, (appid, app)) in terminals.iter().enumerate() {
|
let mut terminals: Vec<_> = assocs
|
||||||
if let Some(ref current_app) = current_app
|
.apps
|
||||||
&& app.name.as_ref() == current_app.name.as_ref()
|
.iter()
|
||||||
{
|
.filter(|app| app.is_terminal && app.icon.is_some())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
terminals.sort_unstable_by_key(|app| app.name.clone());
|
||||||
|
|
||||||
|
'outer: for for_mime in [
|
||||||
|
"x-scheme-handler/terminal",
|
||||||
|
"application/x-terminal-emulator",
|
||||||
|
] {
|
||||||
|
let Ok(mime) = Mime::from_str(for_mime) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
for default in list.default_app_for(&mime).into_iter().flatten() {
|
||||||
|
let appid = default.strip_suffix(".desktop").unwrap_or(default.as_ref());
|
||||||
|
|
||||||
|
for (id, app) in terminals.iter().enumerate() {
|
||||||
|
if app.appid.as_ref() == appid {
|
||||||
|
selected = Some(id);
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (id, app) in terminals.into_iter().enumerate() {
|
||||||
|
let Some(icon) = app.icon.as_deref() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if selected.is_none() && app.appid.as_ref() == "com.system76.CosmicTerm" {
|
||||||
selected = Some(id);
|
selected = Some(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
app_ids.push(appid.to_string());
|
app_ids.push(app.appid.clone());
|
||||||
apps.push(app.name.as_ref().into());
|
apps.push(app.name.as_ref().into());
|
||||||
icons.push(if app.icon.starts_with('/') {
|
icons.push(if icon.starts_with('/') {
|
||||||
icon::from_path(PathBuf::from(app.icon.as_ref()))
|
icon::from_path(PathBuf::from(icon))
|
||||||
} else {
|
} else {
|
||||||
icon::from_name(app.icon.as_ref()).size(20).handle()
|
icon::from_name(icon).size(20).handle()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue