use std::time::Duration;
use tracing::debug;
use zbus::blocking::Connection;
use zbus::blocking::connection::Builder;
use zbus::proxy;
use super::FrontmostSource;
const METHOD_TIMEOUT: Duration = Duration::from_secs(5);
#[proxy(
interface = "org.openlogi.Frontmost",
default_service = "org.openlogi.Frontmost",
default_path = "/org/openlogi/Frontmost",
gen_async = false
)]
trait Frontmost {
#[zbus(name = "GetFocusedWmClass")]
fn get_focused_wm_class(&self) -> zbus::Result<String>;
}
struct GnomeShellSource {
conn: Connection,
}
impl GnomeShellSource {
fn connect() -> Option<Self> {
let conn = Builder::session()
.map_err(|e| debug!("gnome-shell: no session bus: {e}"))
.ok()?
.method_timeout(METHOD_TIMEOUT)
.build()
.map_err(|e| debug!("gnome-shell: connection build failed: {e}"))
.ok()?;
let proxy = FrontmostProxy::new(&conn)
.map_err(|e| debug!("gnome-shell: proxy build failed: {e}"))
.ok()?;
proxy
.get_focused_wm_class()
.map_err(|e| debug!("gnome-shell: OpenLogi extension not reachable: {e}"))
.ok()?;
Some(Self { conn })
}
}
impl FrontmostSource for GnomeShellSource {
fn frontmost_bundle_id(&self) -> Option<String> {
let proxy = FrontmostProxy::new(&self.conn)
.map_err(|e| debug!("gnome-shell: proxy build failed: {e}"))
.ok()?;
let wm_class = proxy
.get_focused_wm_class()
.map_err(|e| debug!("gnome-shell: poll failed (extension gone or bus down?): {e}"))
.ok()?;
(!wm_class.is_empty()).then_some(wm_class)
}
fn name(&self) -> &'static str {
"gnome-shell"
}
}
pub(super) fn candidate() -> Option<Box<dyn FrontmostSource>> {
GnomeShellSource::connect().map(|s| Box::new(s) as Box<dyn FrontmostSource>)
}