use anyhow::Result;
use zbus::{blocking::Connection, dbus_proxy};
use crate::Options;
#[dbus_proxy(
interface = "org.freedesktop.login1.Manager",
default_service = "org.freedesktop.login1",
default_path = "/org/freedesktop/login1"
)]
trait Manager {
fn inhibit(
&self,
what: &str,
who: &str,
why: &str,
mode: &str,
) -> zbus::Result<zbus::zvariant::OwnedFd>;
}
#[dbus_proxy(assume_defaults = true)]
trait ScreenSaver {
fn inhibit(&self, application_name: &str, reason_for_inhibit: &str) -> zbus::Result<u32>;
fn un_inhibit(&self, cookie: u32) -> zbus::Result<()>;
}
pub struct KeepActive {
options: Options,
session_conn: Option<Connection>,
screensaver_proxy: Option<ScreenSaverProxyBlocking<'static>>,
cookie: Option<u32>,
system_conn: Option<Connection>,
manager_proxy: Option<ManagerProxyBlocking<'static>>,
idle_fd: Option<zbus::zvariant::OwnedFd>,
sleep_fd: Option<zbus::zvariant::OwnedFd>,
}
impl KeepActive {
pub fn new(options: Options) -> Result<Self> {
let mut awake = Self {
options,
session_conn: None,
screensaver_proxy: None,
cookie: None,
system_conn: None,
manager_proxy: None,
idle_fd: None,
sleep_fd: None,
};
awake.set()?;
Ok(awake)
}
fn set(&mut self) -> Result<(), zbus::Error> {
self.cookie = if self.options.display {
self.session_conn = Some(Connection::session()?);
self.screensaver_proxy = Some(ScreenSaverProxyBlocking::new(
self.session_conn.as_ref().unwrap(),
)?);
Some(
self.screensaver_proxy
.as_ref()
.unwrap()
.inhibit(&self.options.app_reverse_domain, &self.options.reason)?,
)
} else {
None
};
if self.options.idle || self.options.sleep {
self.system_conn = Some(Connection::system()?);
self.manager_proxy = Some(ManagerProxyBlocking::new(
self.system_conn.as_ref().unwrap(),
)?);
}
self.idle_fd = if self.options.idle {
Some(self.manager_proxy.as_ref().unwrap().inhibit(
"idle",
&self.options.app_name,
&self.options.reason,
"block",
)?)
} else {
None
};
self.sleep_fd = if self.options.sleep {
Some(self.manager_proxy.as_ref().unwrap().inhibit(
"sleep",
&self.options.app_name,
&self.options.reason,
"block",
)?)
} else {
None
};
Ok(())
}
}
impl Drop for KeepActive {
fn drop(&mut self) {
if self.options.display {
if let (Some(p), Some(cookie)) = (self.screensaver_proxy.as_ref(), self.cookie) {
p.un_inhibit(cookie).unwrap()
}
}
}
}