diff --git a/Cargo.lock b/Cargo.lock index 53a9d26..2540815 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1964,6 +1964,7 @@ dependencies = [ "alsa", "anyhow", "env_logger", + "futures", "futures-util", "gio", "iced", diff --git a/Cargo.toml b/Cargo.toml index f5f094f..4c26275 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,3 +34,4 @@ gio = "0.20.0" regex = "1.10.5" xdg = "2.5.2" url = "2.5.2" +futures = "0.3.30" diff --git a/src/main.rs b/src/main.rs index d9aa395..8614772 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use iced_layershell::actions::{ LayershellCustomActionsWithIdAndInfo, LayershellCustomActionsWithInfo, }; use launcher::Launcher; +use notifications::{start_server, NotifyMessage}; use zbus_mpirs::ServiceInfo; use iced_layershell::reexport::{Anchor, KeyboardInteractivity, Layer, NewLayerShellSettings}; @@ -181,6 +182,7 @@ enum Message { SearchSubmit, Launch(usize), IcedEvent(Event), + Notify(NotifyMessage), } async fn get_metadata_initial() -> Option { @@ -463,6 +465,12 @@ impl MultiApplication for LalaMusicBar { ), self.launcher.as_ref().unwrap().focus_input(), ]); + } + Message::Notify(NotifyMessage::UnitAdd(notify)) => { + println!("{notify:?}"); + } + Message::Notify(NotifyMessage::UnitRemove(id)) => { + } _ => { if let Some(launcher) = self.launcher.as_mut() { @@ -494,6 +502,7 @@ impl MultiApplication for LalaMusicBar { .map(|_| Message::RequestDBusInfoUpdate), iced::time::every(std::time::Duration::from_secs(5)).map(|_| Message::UpdateBalance), iced::event::listen().map(Message::IcedEvent), + iced::subscription::channel(std::any::TypeId::of::<()>(), 100, start_server), ]) } diff --git a/src/notifications.rs b/src/notifications.rs index eeeb1d0..0a44f86 100644 --- a/src/notifications.rs +++ b/src/notifications.rs @@ -21,28 +21,55 @@ //! [D-Bus standard interfaces]: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces, use zbus::{interface, object_server::SignalContext, zvariant::OwnedValue}; +use futures::{channel::mpsc::Sender, never::Never}; +use zbus::ConnectionBuilder; + +use super::Message; + +use std::future::pending; + +#[allow(unused)] const NOTIFICATION_DELETED_BY_EXPIRED: u32 = 1; const NOTIFICATION_DELETED_BY_USER: u32 = 2; + +#[allow(unused)] const NOTIFICATION_CLOSED_BY_DBUS: u32 = 3; +#[allow(unused)] const NOTIFICATION_CLOSED_BY_UNKNOWN_REASON: u32 = 4; -pub struct NotifyUnit { - app_name: String, - id: u32, - icon: String, - summery: String, - actions: Vec, - timeout: i32, +#[derive(Debug, Clone)] +pub enum NotifyMessage { + UnitAdd(NotifyUnit), + UnitRemove(u32), } -pub struct LaLaMako { - units: Vec, +#[derive(Debug, Clone)] +pub struct NotifyUnit { + pub app_name: String, + pub id: u32, + pub icon: String, + pub summery: String, + pub body: String, + pub actions: Vec, + pub timeout: i32, } +pub struct LaLaMako(Sender); + #[interface(name = "org.freedesktop.Notifications")] impl LaLaMako { // CloseNotification method - async fn close_notification(&mut self, id: u32) -> zbus::fdo::Result<()> { + async fn close_notification( + &mut self, + #[zbus(signal_context)] ctx: SignalContext<'_>, + id: u32, + ) -> zbus::fdo::Result<()> { + self.notification_closed(&ctx, id, NOTIFICATION_DELETED_BY_USER) + .await + .ok(); + self.0 + .try_send(Message::Notify(NotifyMessage::UnitRemove(id))) + .ok(); Ok(()) } @@ -78,9 +105,20 @@ impl LaLaMako { summery: &str, body: &str, actions: Vec<&str>, - hints: std::collections::HashMap<&str, OwnedValue>, + _hints: std::collections::HashMap<&str, OwnedValue>, timeout: i32, ) -> zbus::fdo::Result { + self.0 + .try_send(Message::Notify(NotifyMessage::UnitAdd(NotifyUnit { + app_name: app_name.to_string(), + id, + icon: icon.to_string(), + summery: summery.to_string(), + body: body.to_string(), + actions: actions.iter().map(|a| a.to_string()).collect(), + timeout, + }))) + .ok(); Ok(0) } @@ -101,3 +139,18 @@ impl LaLaMako { reason: u32, ) -> zbus::Result<()>; } + +pub async fn start_server(sender: Sender) -> Never { + let _conn = async { + ConnectionBuilder::session()? + .name("org.freedesktop.Notifications")? + .serve_at("/org/freedesktop/Notifications", LaLaMako(sender))? + .build() + .await + } + .await; + + pending::<()>().await; + + loop {} +}