Add default application selector for browsers, email, and file managers

This commit is contained in:
lashman
2026-02-28 00:10:39 +02:00
parent 585320b363
commit c622057830
2 changed files with 196 additions and 0 deletions

View File

@@ -332,6 +332,28 @@ pub fn undo_all_modifications(db: &Database, appimage_id: i64) -> Result<(), Str
.status();
}
}
"default_app" => {
if let Some(ref prev) = m.previous_value {
match m.file_path.as_str() {
"web-browser" => {
let _ = Command::new("xdg-settings")
.args(["set", "default-web-browser", prev])
.status();
}
"email-client" => {
let _ = Command::new("xdg-settings")
.args(["set", "default-url-scheme-handler", "mailto", prev])
.status();
}
"file-manager" => {
let _ = Command::new("xdg-mime")
.args(["default", prev, "inode/directory"])
.status();
}
_ => {}
}
}
}
"system_desktop" | "system_icon" | "system_binary" => {
let _ = Command::new("pkexec")
.args(["rm", "-f", &m.file_path])
@@ -395,6 +417,124 @@ pub fn set_mime_default(
Ok(())
}
/// A system-level default application type that an AppImage can serve as.
#[derive(Debug, Clone, PartialEq)]
pub enum DefaultAppType {
WebBrowser,
EmailClient,
FileManager,
}
impl DefaultAppType {
pub fn label(&self) -> &'static str {
match self {
Self::WebBrowser => "Web browser",
Self::EmailClient => "Email client",
Self::FileManager => "File manager",
}
}
}
/// Detect which system-default roles an AppImage can fill based on its categories.
pub fn detect_default_capabilities(categories: &str) -> Vec<DefaultAppType> {
let mut caps = Vec::new();
if categories.contains("WebBrowser") {
caps.push(DefaultAppType::WebBrowser);
}
if categories.contains("Email") {
caps.push(DefaultAppType::EmailClient);
}
if categories.contains("FileManager") {
caps.push(DefaultAppType::FileManager);
}
caps
}
/// Set an AppImage as a system-default application for the given role.
/// Stores the previous default in system_modifications for reversal.
pub fn set_default_app(
db: &Database,
appimage_id: i64,
app_id: &str,
cap: &DefaultAppType,
) -> Result<(), String> {
let desktop_filename = format!("driftwood-{}.desktop", app_id);
match cap {
DefaultAppType::WebBrowser => {
let prev = Command::new("xdg-settings")
.args(["get", "default-web-browser"])
.output()
.ok()
.and_then(|o| {
if o.status.success() {
let s = String::from_utf8_lossy(&o.stdout).trim().to_string();
if s.is_empty() { None } else { Some(s) }
} else {
None
}
});
let status = Command::new("xdg-settings")
.args(["set", "default-web-browser", &desktop_filename])
.status()
.map_err(|e| format!("xdg-settings failed: {}", e))?;
if !status.success() {
return Err("xdg-settings returned non-zero".to_string());
}
db.register_modification(appimage_id, "default_app", "web-browser", prev.as_deref()).ok();
}
DefaultAppType::EmailClient => {
let prev = Command::new("xdg-settings")
.args(["get", "default-url-scheme-handler", "mailto"])
.output()
.ok()
.and_then(|o| {
if o.status.success() {
let s = String::from_utf8_lossy(&o.stdout).trim().to_string();
if s.is_empty() { None } else { Some(s) }
} else {
None
}
});
let status = Command::new("xdg-settings")
.args(["set", "default-url-scheme-handler", "mailto", &desktop_filename])
.status()
.map_err(|e| format!("xdg-settings failed: {}", e))?;
if !status.success() {
return Err("xdg-settings returned non-zero".to_string());
}
db.register_modification(appimage_id, "default_app", "email-client", prev.as_deref()).ok();
}
DefaultAppType::FileManager => {
let prev = Command::new("xdg-mime")
.args(["query", "default", "inode/directory"])
.output()
.ok()
.and_then(|o| {
if o.status.success() {
let s = String::from_utf8_lossy(&o.stdout).trim().to_string();
if s.is_empty() { None } else { Some(s) }
} else {
None
}
});
let status = Command::new("xdg-mime")
.args(["default", &desktop_filename, "inode/directory"])
.status()
.map_err(|e| format!("xdg-mime failed: {}", e))?;
if !status.success() {
return Err("xdg-mime returned non-zero".to_string());
}
db.register_modification(appimage_id, "default_app", "file-manager", prev.as_deref()).ok();
}
}
Ok(())
}
fn update_desktop_database() {
let apps_dir = applications_dir();
Command::new("update-desktop-database")