use std::path::PathBuf; use zbus::dbus_interface; use zbus::fdo::{self, RequestNameFlags}; use super::Start; pub struct Screenshot { to_niri: calloop::channel::Sender, from_niri: async_channel::Receiver, } pub enum ScreenshotToNiri { TakeScreenshot { include_cursor: bool }, } pub enum NiriToScreenshot { ScreenshotResult(Option), } #[dbus_interface(name = "org.gnome.Shell.Screenshot")] impl Screenshot { async fn screenshot( &self, include_cursor: bool, _flash: bool, _filename: PathBuf, ) -> fdo::Result<(bool, PathBuf)> { if let Err(err) = self .to_niri .send(ScreenshotToNiri::TakeScreenshot { include_cursor }) { warn!("error sending message to niri: {err:?}"); return Err(fdo::Error::Failed("internal error".to_owned())); } let filename = match self.from_niri.recv().await { Ok(NiriToScreenshot::ScreenshotResult(Some(filename))) => filename, Ok(NiriToScreenshot::ScreenshotResult(None)) => { return Err(fdo::Error::Failed("internal error".to_owned())); } Err(err) => { warn!("error receiving message from niri: {err:?}"); return Err(fdo::Error::Failed("internal error".to_owned())); } }; Ok((true, filename)) } } impl Screenshot { pub fn new( to_niri: calloop::channel::Sender, from_niri: async_channel::Receiver, ) -> Self { Self { to_niri, from_niri } } } impl Start for Screenshot { fn start(self) -> anyhow::Result { let conn = zbus::blocking::Connection::session()?; let flags = RequestNameFlags::AllowReplacement | RequestNameFlags::ReplaceExisting | RequestNameFlags::DoNotQueue; conn.object_server() .at("/org/gnome/Shell/Screenshot", self)?; conn.request_name_with_flags("org.gnome.Shell.Screenshot", flags)?; Ok(conn) } }