Add autostart manager with XDG autostart support
This commit is contained in:
@@ -1744,6 +1744,16 @@ impl Database {
|
|||||||
Ok(self.conn.last_insert_rowid())
|
Ok(self.conn.last_insert_rowid())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Autostart ---
|
||||||
|
|
||||||
|
pub fn set_autostart(&self, id: i64, enabled: bool) -> SqlResult<()> {
|
||||||
|
self.conn.execute(
|
||||||
|
"UPDATE appimages SET autostart = ?2 WHERE id = ?1",
|
||||||
|
params![id, enabled as i32],
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// --- Launch statistics ---
|
// --- Launch statistics ---
|
||||||
|
|
||||||
pub fn get_top_launched(&self, limit: i32) -> SqlResult<Vec<(String, u64)>> {
|
pub fn get_top_launched(&self, limit: i32) -> SqlResult<Vec<(String, u64)>> {
|
||||||
|
|||||||
@@ -245,6 +245,61 @@ pub fn integrate_tracked(record: &AppImageRecord, db: &Database) -> Result<Integ
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn autostart_dir() -> PathBuf {
|
||||||
|
dirs::config_dir()
|
||||||
|
.unwrap_or_else(|| PathBuf::from("/tmp"))
|
||||||
|
.join("autostart")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable_autostart(db: &Database, record: &AppImageRecord) -> Result<PathBuf, String> {
|
||||||
|
let dir = autostart_dir();
|
||||||
|
fs::create_dir_all(&dir).map_err(|e| format!("Failed to create autostart dir: {}", e))?;
|
||||||
|
|
||||||
|
let app_id = record.app_name.as_deref()
|
||||||
|
.map(|n| make_app_id(n))
|
||||||
|
.unwrap_or_else(|| format!("appimage-{}", record.id));
|
||||||
|
let desktop_filename = format!("driftwood-{}.desktop", app_id);
|
||||||
|
let desktop_path = dir.join(&desktop_filename);
|
||||||
|
|
||||||
|
let app_name = record.app_name.as_deref().unwrap_or(&record.filename);
|
||||||
|
let icon = record.icon_path.as_deref().unwrap_or("application-x-executable");
|
||||||
|
|
||||||
|
let content = format!("\
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Name={}
|
||||||
|
Exec=\"{}\" %U
|
||||||
|
Icon={}
|
||||||
|
X-GNOME-Autostart-enabled=true
|
||||||
|
X-Driftwood-AppImage-ID={}
|
||||||
|
", app_name, escape_exec_arg(&record.path), icon, record.id);
|
||||||
|
|
||||||
|
fs::write(&desktop_path, &content)
|
||||||
|
.map_err(|e| format!("Failed to write autostart file: {}", e))?;
|
||||||
|
|
||||||
|
db.register_modification(record.id, "autostart", &desktop_path.to_string_lossy(), None)
|
||||||
|
.map_err(|e| format!("Failed to register modification: {}", e))?;
|
||||||
|
|
||||||
|
db.set_autostart(record.id, true).ok();
|
||||||
|
|
||||||
|
Ok(desktop_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disable_autostart(db: &Database, record_id: i64) -> Result<(), String> {
|
||||||
|
let mods = db.get_modifications(record_id).unwrap_or_default();
|
||||||
|
for m in &mods {
|
||||||
|
if m.mod_type == "autostart" {
|
||||||
|
let path = Path::new(&m.file_path);
|
||||||
|
if path.exists() {
|
||||||
|
fs::remove_file(path).ok();
|
||||||
|
}
|
||||||
|
db.remove_modification(m.id).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
db.set_autostart(record_id, false).ok();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Undo all tracked system modifications for an AppImage.
|
/// Undo all tracked system modifications for an AppImage.
|
||||||
pub fn undo_all_modifications(db: &Database, appimage_id: i64) -> Result<(), String> {
|
pub fn undo_all_modifications(db: &Database, appimage_id: i64) -> Result<(), String> {
|
||||||
let mods = db.get_modifications(appimage_id)
|
let mods = db.get_modifications(appimage_id)
|
||||||
|
|||||||
@@ -990,6 +990,39 @@ fn build_system_tab(record: &AppImageRecord, db: &Rc<Database>, toast_overlay: &
|
|||||||
integration_group.add(&row);
|
integration_group.add(&row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Autostart toggle
|
||||||
|
let autostart_row = adw::SwitchRow::builder()
|
||||||
|
.title("Start at login")
|
||||||
|
.subtitle("Launch this app automatically when you log in")
|
||||||
|
.active(record.autostart)
|
||||||
|
.tooltip_text(
|
||||||
|
"Creates an autostart entry so this app launches \
|
||||||
|
when you log in to your desktop."
|
||||||
|
)
|
||||||
|
.build();
|
||||||
|
let record_autostart = record.clone();
|
||||||
|
let db_autostart = db.clone();
|
||||||
|
let toast_autostart = toast_overlay.clone();
|
||||||
|
let record_id_as = record.id;
|
||||||
|
autostart_row.connect_active_notify(move |row| {
|
||||||
|
if row.is_active() {
|
||||||
|
match integrator::enable_autostart(&db_autostart, &record_autostart) {
|
||||||
|
Ok(path) => {
|
||||||
|
log::info!("Autostart enabled: {}", path.display());
|
||||||
|
toast_autostart.add_toast(adw::Toast::new("Will start at login"));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Failed to enable autostart: {}", e);
|
||||||
|
toast_autostart.add_toast(adw::Toast::new("Failed to enable autostart"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
integrator::disable_autostart(&db_autostart, record_id_as).ok();
|
||||||
|
toast_autostart.add_toast(adw::Toast::new("Autostart disabled"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
integration_group.add(&autostart_row);
|
||||||
|
|
||||||
inner.append(&integration_group);
|
inner.append(&integration_group);
|
||||||
|
|
||||||
// Version Rollback group
|
// Version Rollback group
|
||||||
|
|||||||
Reference in New Issue
Block a user