Rust · 1682 bytes Raw Blame History
1 //! garfield-portal - XDG Desktop Portal backend for garfield file picker.
2 //!
3 //! This daemon implements the org.freedesktop.impl.portal.FileChooser interface,
4 //! spawning garfield in picker mode when applications request file dialogs.
5
6 mod file_chooser;
7 mod request;
8
9 use anyhow::Result;
10 use clap::Parser;
11 use tracing_subscriber::{fmt, EnvFilter};
12 use zbus::connection::Builder;
13
14 /// garfield-portal - XDG Desktop Portal backend
15 #[derive(Parser, Debug)]
16 #[command(name = "garfield-portal", about = "XDG Desktop Portal backend for garfield")]
17 struct Args {
18 /// Run in foreground (don't daemonize)
19 #[arg(long, short = 'f')]
20 foreground: bool,
21 }
22
23 #[tokio::main]
24 async fn main() -> Result<()> {
25 // Initialize logging
26 let filter = EnvFilter::try_from_default_env()
27 .unwrap_or_else(|_| EnvFilter::new("info"));
28
29 fmt()
30 .with_env_filter(filter)
31 .with_target(false)
32 .init();
33
34 let _args = Args::parse();
35
36 tracing::info!("Starting garfield-portal");
37
38 // Create the FileChooser interface
39 let file_chooser = file_chooser::FileChooser::new();
40
41 // Connect to session bus and serve the interface
42 let _connection = Builder::session()?
43 .name("org.freedesktop.impl.portal.desktop.garfield")?
44 .serve_at("/org/freedesktop/portal/desktop", file_chooser)?
45 .build()
46 .await?;
47
48 tracing::info!("garfield-portal listening on D-Bus session bus");
49
50 // Keep the service running
51 loop {
52 // The connection handles incoming method calls automatically
53 // We just need to keep the main task alive
54 tokio::time::sleep(std::time::Duration::from_secs(3600)).await;
55 }
56 }
57