Implement Driftwood AppImage manager - Phases 1 and 2

Phase 1 - Application scaffolding:
- GTK4/libadwaita application window with AdwNavigationView
- GSettings-backed window state persistence
- GResource-compiled CSS and schema
- Library view with grid/list toggle, search, sorting, filtering
- Detail view with file info, desktop integration controls
- Preferences window with scan directories, theme, behavior settings
- CLI with list, scan, integrate, remove, clean, inspect commands
- AppImage discovery, metadata extraction, desktop integration
- Orphaned desktop entry detection and cleanup
- AppImage packaging script

Phase 2 - Intelligence layer:
- Database schema v2 with migration for status tracking columns
- FUSE detection engine (libfuse2/3, fusermount, /dev/fuse, AppImageLauncher)
- Wayland awareness engine (session type, toolkit detection, XWayland)
- Update info parsing from AppImage ELF sections (.upd_info)
- GitHub/GitLab Releases API integration for update checking
- Update download with progress tracking and atomic apply
- Launch wrapper with FUSE auto-detection and usage tracking
- Duplicate and multi-version detection with recommendations
- Dashboard with system health, library stats, disk usage
- Update check dialog (single and batch)
- Duplicate resolution dialog
- Status badges on library cards and detail view
- Extended CLI: status, check-updates, duplicates, launch commands

49 tests passing across all modules.
This commit is contained in:
lashman
2026-02-26 23:04:27 +02:00
parent 588b1b1525
commit fa28955919
33 changed files with 10401 additions and 0 deletions

35
src/main.rs Normal file
View File

@@ -0,0 +1,35 @@
mod application;
mod cli;
mod config;
mod core;
mod ui;
mod window;
use clap::Parser;
use glib::ExitCode;
use gtk::prelude::*;
use application::DriftwoodApplication;
use config::{APP_ID, GSETTINGS_SCHEMA_DIR};
fn main() -> ExitCode {
// Point GSettings at our compiled schema directory (dev builds)
std::env::set_var("GSETTINGS_SCHEMA_DIR", GSETTINGS_SCHEMA_DIR);
// Parse CLI arguments
let parsed = cli::Cli::parse();
// If a subcommand was given, run in CLI mode (no GUI)
if let Some(command) = parsed.command {
// Initialize GTK minimally for GSettings access
gtk::init().expect("Failed to initialize GTK");
return cli::run_command(command);
}
// Otherwise, launch the full GUI application
gio::resources_register_include!("driftwood.gresource")
.expect("Failed to register resources");
let app = DriftwoodApplication::new(APP_ID, &gio::ApplicationFlags::empty());
app.run()
}