diff --git a/src/client.rs b/src/client.rs index 2ab5f09..666d2cd 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,4 +1,4 @@ -use zbus::{dbus_proxy, Connection, Result}; +use zbus::{dbus_proxy, export::ordered_stream::OrderedStreamExt, Connection, Result}; use crate::{notification::Notification, Format}; @@ -9,6 +9,29 @@ use crate::{notification::Notification, Format}; )] trait Manager { fn list(&self) -> Result>; + + #[dbus_proxy(signal)] + fn new_notification(&self, notif: Notification) -> fdo::Result; +} + +pub async fn listen(format: Format) -> Result<()> { + let connection = Connection::session().await?; + let manager = ManagerProxy::new(&connection).await?; + // let props = zbus::fdo::PropertiesProxy::builder(&connection) + // .destination("org.freedesktop.Notifications")? + // .path("/org/freedesktop/Notifications")? + // .build() + // .await?; + let mut stream = manager.receive_new_notification().await?; + while let Some(notif) = stream.next().await { + let notif = notif.args()?.notif; + match format { + Format::Json => println!("{}", serde_json::to_string(¬if).unwrap()), + Format::Short => println!("{}: {}", notif.summary, notif.body), + }; + } + + Ok(()) } // TODO: strip \n on the short format. diff --git a/src/daemon.rs b/src/daemon.rs index 9d8de5f..c47f130 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -2,9 +2,11 @@ use crate::notification::Hints; use crate::notification::Notification; use crate::notification::ServerInformation; use std::collections::HashMap; -use std::error::Error; use zbus::dbus_interface; use zbus::Connection; +use zbus::Result; +use zbus::SignalContext; +use zbus::fdo; pub struct NotifyManager { next_id: u32, @@ -19,7 +21,7 @@ impl NotifyManager { } } - pub async fn start(self) -> Result<(), Box> { + pub async fn start(self) -> Result<()> { let connection = Connection::session().await?; connection @@ -36,8 +38,9 @@ impl NotifyManager { #[dbus_interface(name = "org.freedesktop.Notifications")] impl NotifyManager { - fn notify( + async fn notify( &mut self, + #[zbus(signal_context)] ctxt: SignalContext<'_>, app_name: String, replaces_id: u32, app_icon: String, @@ -46,25 +49,24 @@ impl NotifyManager { actions: Vec, hints: Hints, expire_timeout: i32, - ) -> u32 { + ) -> fdo::Result { println!("{}: {}", summary, body); - self.pendings.insert( - self.next_id, - Notification { - id: self.next_id, - app_name, - app_icon, - summary, - body, - actions, - hints, - }, - ); + let notif = Notification { + id: self.next_id, + app_name, + app_icon, + summary, + body, + actions, + hints, + }; + Self::new_notification(&ctxt, ¬if).await?; + self.pendings.insert(self.next_id, notif); if replaces_id == 0 { self.next_id += 1; - self.next_id + Ok(self.next_id) } else { - replaces_id + Ok(replaces_id) } } @@ -87,6 +89,9 @@ impl NotifyManager { } } + #[dbus_interface(signal)] + async fn new_notification(ctxt: &SignalContext<'_>, notif: &Notification) -> Result<()>; + fn list(&self) -> Vec<&Notification> { let mut ret: Vec<&Notification> = self.pendings.values().collect(); ret.sort_by(|a, b| a.id.cmp(&b.id)); diff --git a/src/main.rs b/src/main.rs index 3c1e8ec..1d4c05e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ mod notification; use clap::{Parser, Subcommand, ValueEnum}; use daemon::NotifyManager; -use std::error::Error; +use zbus::Result; #[derive(Parser)] #[command(author, version, about, long_about = None)] @@ -20,6 +20,10 @@ enum Command { /// Listen to new notifications. Listen { + /// Select the format to display notifications. + #[arg(short, long, default_value = "short")] + format: Format, + /// Use json instead of plain-text #[arg(short, long)] json: bool, @@ -46,12 +50,12 @@ pub enum Format { } #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { let cli = Args::parse(); match cli.command { Command::Daemon => NotifyManager::new().start().await, Command::List { format } => client::list(format).await, - Command::Listen { .. } => unimplemented!(), + Command::Listen { format, .. } => client::listen(format).await, } } diff --git a/src/notification.rs b/src/notification.rs index e00be0a..8b3a2ae 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use zbus::zvariant::{DeserializeDict, SerializeDict, Type}; -#[derive(Deserialize, Serialize, Type)] +#[derive(Debug, Deserialize, Serialize, Type)] pub struct Notification { pub id: u32, pub app_name: String, @@ -12,7 +12,7 @@ pub struct Notification { pub hints: Hints, } -#[derive(DeserializeDict, SerializeDict, Type)] +#[derive(Debug, DeserializeDict, SerializeDict, Type)] #[zvariant(signature = "dict")] pub struct Hints { category: Option,