diff --git a/Cargo.lock b/Cargo.lock index 3c9c7304..3740d897 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1387,12 +1387,13 @@ dependencies = [ [[package]] name = "cosmic-client-toolkit" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=c8d3a1c#c8d3a1c3d40d16235f4720969a54ed570ec7a976" +source = "git+https://github.com/pop-os/cosmic-protocols//?rev=d218c76#d218c76b58c7a3b20dd5e7943f93fc306a1b81b8" dependencies = [ "cosmic-protocols", "libc", "smithay-client-toolkit", "wayland-client", + "wayland-protocols", ] [[package]] @@ -1408,7 +1409,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -1430,7 +1431,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40" dependencies = [ "quote", "syn 1.0.109", @@ -1458,10 +1459,23 @@ dependencies = [ "zvariant 4.2.0", ] +[[package]] +name = "cosmic-freedesktop-icons" +version = "0.2.6" +source = "git+https://github.com/pop-os/freedesktop-icons#3a202b17c8d4d63e2f073210260773855276c604" +dependencies = [ + "dirs 5.0.1", + "once_cell", + "rust-ini", + "thiserror", + "tracing", + "xdg", +] + [[package]] name = "cosmic-notifications-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-notifications#d4d5f429337004c1721e0072ad1c25509229586f" +source = "git+https://github.com/pop-os/cosmic-notifications#76c237b0509ea6f724076db2195a7fab6942f33c" dependencies = [ "cosmic-config", "serde", @@ -1470,7 +1484,7 @@ dependencies = [ [[package]] name = "cosmic-notifications-util" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-notifications#d4d5f429337004c1721e0072ad1c25509229586f" +source = "git+https://github.com/pop-os/cosmic-notifications#76c237b0509ea6f724076db2195a7fab6942f33c" dependencies = [ "bytemuck", "fast_image_resize", @@ -1497,7 +1511,7 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#734e3fafe2eafea1cb3cece7d0b4ddf72a2c4323" +source = "git+https://github.com/pop-os/cosmic-panel#1c9c4e2a2cf27efd0ca77b5ec21bc6f7fa92d9da" dependencies = [ "anyhow", "cosmic-config", @@ -1512,7 +1526,7 @@ dependencies = [ [[package]] name = "cosmic-protocols" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-protocols?rev=c8d3a1c#c8d3a1c3d40d16235f4720969a54ed570ec7a976" +source = "git+https://github.com/pop-os/cosmic-protocols//?rev=d218c76#d218c76b58c7a3b20dd5e7943f93fc306a1b81b8" dependencies = [ "bitflags 2.6.0", "wayland-backend", @@ -1526,7 +1540,7 @@ dependencies = [ [[package]] name = "cosmic-settings-daemon" version = "0.1.0" -source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de" +source = "git+https://github.com/pop-os/dbus-settings-bindings#0eee63a96c8b1f6555ca797b5c12545c372b1a1b" dependencies = [ "zbus 4.4.0", ] @@ -1578,7 +1592,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "almost", "cosmic-config", @@ -1595,7 +1609,7 @@ dependencies = [ [[package]] name = "cosmic-time" version = "0.4.0" -source = "git+https://github.com/pop-os/cosmic-time#b1816cd260e1517d40f39d5fbdee44cd825ebdde" +source = "git+https://github.com/pop-os/cosmic-time#565e6d805fdd7977a057aff012f4a20a366aceab" dependencies = [ "float-cmp", "libcosmic", @@ -2458,19 +2472,6 @@ dependencies = [ "xdg", ] -[[package]] -name = "freedesktop-icons" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8ef34245e0540c9a3ce7a28340b98d2c12b75da0d446da4e8224923fcaa0c16" -dependencies = [ - "dirs 5.0.1", - "once_cell", - "rust-ini", - "thiserror", - "xdg", -] - [[package]] name = "fsevent-sys" version = "4.1.0" @@ -2987,7 +2988,7 @@ dependencies = [ [[package]] name = "iced" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "dnd", "iced_accessibility", @@ -3005,7 +3006,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "accesskit", "accesskit_winit", @@ -3014,10 +3015,11 @@ dependencies = [ [[package]] name = "iced_core" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40" dependencies = [ "bitflags 2.6.0", "bytes", + "cosmic-client-toolkit", "dnd", "glam", "log", @@ -3028,7 +3030,6 @@ dependencies = [ "raw-window-handle", "rustc-hash 2.1.0", "serde", - "smithay-client-toolkit", "smol_str", "thiserror", "web-time", @@ -3038,7 +3039,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#5422ab3130a0f943c71fda558d61c815086e6f40" dependencies = [ "futures", "iced_core", @@ -3064,7 +3065,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "bitflags 2.6.0", "bytemuck", @@ -3086,7 +3087,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -3098,14 +3099,14 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "bytes", + "cosmic-client-toolkit", "dnd", "iced_core", "iced_futures", "raw-window-handle", - "smithay-client-toolkit", "thiserror", "window_clipboard", ] @@ -3113,7 +3114,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "bytemuck", "cosmic-text", @@ -3129,11 +3130,12 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "as-raw-xcb-connection", "bitflags 2.6.0", "bytemuck", + "cosmic-client-toolkit", "futures", "glam", "guillotiere", @@ -3146,7 +3148,6 @@ dependencies = [ "resvg", "rustc-hash 2.1.0", "rustix 0.38.41", - "smithay-client-toolkit", "thiserror", "tiny-xlib", "wayland-backend", @@ -3160,8 +3161,9 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ + "cosmic-client-toolkit", "dnd", "iced_renderer", "iced_runtime", @@ -3169,7 +3171,6 @@ dependencies = [ "once_cell", "ouroboros", "rustc-hash 2.1.0", - "smithay-client-toolkit", "thiserror", "unicode-segmentation", "window_clipboard", @@ -3178,8 +3179,9 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.14.0-dev" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ + "cosmic-client-toolkit", "dnd", "iced_futures", "iced_graphics", @@ -3187,7 +3189,6 @@ dependencies = [ "log", "raw-window-handle", "rustc-hash 2.1.0", - "smithay-client-toolkit", "thiserror", "tracing", "wasm-bindgen-futures", @@ -3931,20 +3932,20 @@ checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic#a6db807c1bbffc90b68513171348cad0b4469eac" +source = "git+https://github.com/pop-os/libcosmic#43e7213b705be39a213ab9b18a353912a7bc1e48" dependencies = [ "apply", "ashpd 0.9.2", "chrono", "cosmic-client-toolkit", "cosmic-config", + "cosmic-freedesktop-icons", "cosmic-panel-config", "cosmic-settings-daemon", "cosmic-theme", "css-color", "derive_setters", "freedesktop-desktop-entry 0.5.2", - "freedesktop-icons", "iced", "iced_core", "iced_futures", @@ -4527,7 +4528,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 3.2.0", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.90", @@ -7549,7 +7550,7 @@ dependencies = [ [[package]] name = "xdg-shell-wrapper-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel#734e3fafe2eafea1cb3cece7d0b4ddf72a2c4323" +source = "git+https://github.com/pop-os/cosmic-panel#1c9c4e2a2cf27efd0ca77b5ec21bc6f7fa92d9da" dependencies = [ "serde", "wayland-protocols-wlr", diff --git a/Cargo.toml b/Cargo.toml index 3defa10f..e1d85d66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ resolver = "2" [workspace.dependencies] anyhow = "1.0.81" -cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "c8d3a1c" } +cctk = { git = "https://github.com/pop-os/cosmic-protocols", package = "cosmic-client-toolkit", rev = "d218c76" } cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", default-features = false, features = [ "client", ], rev = "c8d3a1c" } @@ -83,3 +83,6 @@ ignored = ["libcosmic"] # winit = { path = "../winit" } [patch."https://github.com/smithay/client-toolkit.git"] sctk = { package = "smithay-client-toolkit", version = "=0.19.2" } +[patch.'https://github.com/pop-os/cosmic-protocols'] +cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols//", rev = "d218c76" } +cosmic-client-toolkit = { git = "https://github.com/pop-os/cosmic-protocols//", rev = "d218c76" } diff --git a/cosmic-applet-notifications/src/lib.rs b/cosmic-applet-notifications/src/lib.rs index 08c4d9d5..6b71abb6 100644 --- a/cosmic-applet-notifications/src/lib.rs +++ b/cosmic-applet-notifications/src/lib.rs @@ -25,10 +25,10 @@ use cosmic::{ use cosmic::iced_futures::futures::executor::block_on; use cosmic_notifications_config::NotificationsConfig; -use cosmic_notifications_util::{Image, Notification}; +use cosmic_notifications_util::{ActionId, Image, Notification}; use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline}; use std::{borrow::Cow, collections::HashMap, path::PathBuf}; -use subscriptions::notifications::NotificationsAppletProxy; +use subscriptions::notifications::{self, NotificationsAppletProxy}; use tokio::sync::mpsc::Sender; use tracing::info; @@ -51,6 +51,7 @@ struct Notifications { cards: Vec<(id::Cards, Vec, bool, String, String, String)>, token_tx: Option>, proxy: NotificationsAppletProxy<'static>, + notifications_tx: Option>, } impl Notifications { @@ -84,10 +85,11 @@ enum Message { CloseRequested(window::Id), DoNotDisturb(chain::Toggler, bool), Frame(Instant), - NotificationEvent(Notification), + NotificationEvent(notifications::Output), Config(NotificationsConfig), DbusEvent(subscriptions::dbus::Output), Dismissed(u32), + ActivateNotification(u32), ClearAll(Option), CardsToggled(String, bool), Token(TokenUpdate), @@ -136,6 +138,7 @@ impl cosmic::Application for Notifications { token_tx: Default::default(), proxy: block_on(crate::subscriptions::notifications::get_proxy()) .expect("Failed to get proxy"), + notifications_tx: None, }; _self.update_icon(); (_self, Task::none()) @@ -213,32 +216,37 @@ impl cosmic::Application for Notifications { } } } - Message::NotificationEvent(n) => { - if let Some(c) = self - .cards - .iter_mut() - .find(|c| c.1.iter().any(|notif| n.app_name == notif.app_name)) - { - if let Some(notif) = c.1.iter_mut().find(|notif| n.id == notif.id) { - *notif = n; + Message::NotificationEvent(event) => match event { + notifications::Output::Notification(n) => { + if let Some(c) = self + .cards + .iter_mut() + .find(|c| c.1.iter().any(|notif| n.app_name == notif.app_name)) + { + if let Some(notif) = c.1.iter_mut().find(|notif| n.id == notif.id) { + *notif = n; + } else { + c.1.push(n); + c.3 = fl!( + "show-more", + HashMap::from_iter(vec![("more", c.1.len().saturating_sub(1))]) + ); + } } else { - c.1.push(n); - c.3 = fl!( - "show-more", - HashMap::from_iter(vec![("more", c.1.len().saturating_sub(1))]) - ); + self.cards.push(( + id::Cards::new(n.app_name.clone()), + vec![n], + false, + fl!("show-more", HashMap::from_iter(vec![("more", "1")])), + fl!("show-less"), + fl!("clear-group"), + )); } - } else { - self.cards.push(( - id::Cards::new(n.app_name.clone()), - vec![n], - false, - fl!("show-more", HashMap::from_iter(vec![("more", "1")])), - fl!("show-less"), - fl!("clear-group"), - )); } - } + notifications::Output::Ready(tx) => { + self.notifications_tx = Some(tx); + } + }, Message::Config(config) => { self.config = config; } @@ -351,6 +359,46 @@ impl cosmic::Application for Notifications { tokio::spawn(cosmic::process::spawn(cmd)); } }, + Message::ActivateNotification(id) => { + tracing::error!("Received notification action Message"); + let Some(notification) = self + .cards + .iter() + .find_map(|list| list.1.iter().find(|n| n.id == id)) + else { + return cosmic::task::message(Message::Dismissed(id)); + }; + tracing::error!("Found notification for id"); + + let maybe_action = if notification + .actions + .iter() + .any(|a| matches!(a.0, ActionId::Default)) + { + Some(ActionId::Default.to_string()) + } else { + notification.actions.get(0).map(|a| a.0.to_string()) + }; + + let Some(action) = maybe_action else { + return cosmic::task::message(Message::Dismissed(id)); + }; + tracing::error!("Found default action for notification"); + + if let Some(tx) = &self.notifications_tx { + tracing::error!("Sending notification action"); + + let tx = tx.clone(); + tokio::spawn(async move { + if let Err(err) = tx.send(notifications::Input::Activated(id, action)).await + { + tracing::error!("{:?}", err); + } else { + tracing::error!("Sent notification action"); + } + }); + } + } }; self.update_icon(); Task::none() @@ -407,7 +455,7 @@ impl cosmic::Application for Notifications { continue; } let name = c.1[0].app_name.clone(); - let notif_elems: Vec<_> = c + let (ids, notif_elems): (Vec<_>, Vec<_>) = c .1 .iter() .rev() @@ -432,61 +480,70 @@ impl cosmic::Application for Notifications { ) .on_press(Message::Dismissed(n.id)) .class(cosmic::theme::Button::Text); - Element::from( - column!( - match n.image() { - Some(cosmic_notifications_util::Image::File(path)) => { - row![ - icon::from_path(PathBuf::from(path)).icon().size(16), - app_name, - duration_since, - close_notif - ] - .spacing(8) - .align_y(Alignment::Center) - } - Some(cosmic_notifications_util::Image::Name(name)) => { - row![ - icon::from_name(name.as_str()).size(16), - app_name, - duration_since, - close_notif - ] - .spacing(8) - .align_y(Alignment::Center) - } - Some(cosmic_notifications_util::Image::Data { - width, - height, - data, - }) => { - row![ - icon::from_raster_pixels(*width, *height, data.clone()) + ( + n.id, + Element::from( + column!( + match n.image() { + Some(cosmic_notifications_util::Image::File(path)) => { + row![ + icon::from_path(PathBuf::from(path)) + .icon() + .size(16), + app_name, + duration_since, + close_notif + ] + .spacing(8) + .align_y(Alignment::Center) + } + Some(cosmic_notifications_util::Image::Name(name)) => { + row![ + icon::from_name(name.as_str()).size(16), + app_name, + duration_since, + close_notif + ] + .spacing(8) + .align_y(Alignment::Center) + } + Some(cosmic_notifications_util::Image::Data { + width, + height, + data, + }) => { + row![ + icon::from_raster_pixels( + *width, + *height, + data.clone() + ) .icon() .size(16), - app_name, - duration_since, - close_notif - ] - .spacing(8) - .align_y(Alignment::Center) - } - None => row![app_name, duration_since, close_notif] - .spacing(8) - .align_y(Alignment::Center), - }, - column![ - text::body(n.summary.lines().next().unwrap_or_default()) - .width(Length::Fill), - text(n.body.lines().next().unwrap_or_default()) - .width(Length::Fill) - .size(12) - ] - ) - .width(Length::Fill), + app_name, + duration_since, + close_notif + ] + .spacing(8) + .align_y(Alignment::Center) + } + None => row![app_name, duration_since, close_notif] + .spacing(8) + .align_y(Alignment::Center), + }, + column![ + text::body(n.summary.lines().next().unwrap_or_default()) + .width(Length::Fill), + text(n.body.lines().next().unwrap_or_default()) + .width(Length::Fill) + .size(12) + ] + ) + .width(Length::Fill), + ), ) }) - .collect(); + .unzip(); let show_more_icon = c.1.last().and_then(|n| { info!("app_icon: {:?}", &n.app_icon); if n.app_icon.is_empty() { @@ -519,7 +576,8 @@ impl cosmic::Application for Notifications { &self.timeline, notif_elems, Message::ClearAll(Some(name.clone())), - move |_, e| Message::CardsToggled(name.clone(), e), + Some(move |_, e| Message::CardsToggled(name.clone(), e)), + Some(move |id| Message::ActivateNotification(ids[id])), &c.3, &c.4, &c.5, diff --git a/cosmic-applet-notifications/src/subscriptions/notifications.rs b/cosmic-applet-notifications/src/subscriptions/notifications.rs index 898b8348..285299c1 100644 --- a/cosmic-applet-notifications/src/subscriptions/notifications.rs +++ b/cosmic-applet-notifications/src/subscriptions/notifications.rs @@ -2,15 +2,20 @@ // SPDX-License-Identifier: GPL-3.0-only use cosmic::{ - iced::{futures, stream}, + iced::{ + futures::{self, FutureExt}, + stream, + }, iced_futures::Subscription, }; use cosmic_notifications_util::Notification; use std::{ collections::HashMap, + future::pending, os::unix::io::{FromRawFd, RawFd}, + pin::pin, }; - +use tokio::sync::mpsc; use tracing::{error, trace}; use zbus::{ connection::Builder, @@ -20,54 +25,95 @@ use zbus::{ #[derive(Debug)] pub enum State { - WaitingForNotificationEvent(u8), + WaitingForNotificationEvent, Finished, } -pub fn notifications(proxy: NotificationsAppletProxy<'static>) -> Subscription { +#[derive(Debug, Clone)] +pub enum Input { + Activated(u32, String), +} + +#[derive(Debug, Clone)] +pub enum Output { + Ready(mpsc::Sender), + Notification(Notification), +} + +pub fn notifications(proxy: NotificationsAppletProxy<'static>) -> Subscription { struct SomeWorker; Subscription::run_with_id( std::any::TypeId::of::(), stream::channel(50, |mut output| async move { - let mut state = State::WaitingForNotificationEvent(0); + let mut state = State::WaitingForNotificationEvent; + let (sender, mut receiver) = mpsc::channel(10); + _ = output.send(Output::Ready(sender)).await; + let mut signal; + let mut fail_count: u8 = 0; + loop { + match proxy.receive_notify().await { + Ok(s) => { + signal = s; + break; + } + Err(err) => { + error!( + "failed to get a stream of signals for notifications. {}", + err + ); + fail_count = fail_count.saturating_add(1); + if fail_count > 5 { + error!("Failed to receive notification events"); + _ = pending::<()>(); + } else { + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + }; + continue; + } + } + } loop { match &mut state { - State::WaitingForNotificationEvent(mut fail_count) => { + State::WaitingForNotificationEvent => { trace!("Waiting for notification events..."); - let mut signal = match proxy.receive_notify().await { - Ok(s) => s, - Err(err) => { - error!( - "failed to get a stream of signals for notifications. {}", - err - ); - fail_count = fail_count.saturating_add(1); - if fail_count > 5 { - error!("Failed to receive notification events"); - state = State::Finished; + let mut next_signal = signal.next(); + let mut next_input = pin!(receiver.recv().fuse()); + cosmic::iced::futures::select! { + v = next_signal => { + if let Some(msg) = v { + let Some(args) = msg.args().into_iter().next() else { + break; + }; + let notification = Notification::new( + args.app_name, + args.id, + args.app_icon, + args.summary, + args.body, + args.actions, + args.hints, + args.expire_timeout, + ); + _ = output.send(Output::Notification(notification)).await; } else { - tokio::time::sleep(std::time::Duration::from_secs(1)).await; - }; - continue; + tracing::error!("Signal stream closed, ending notifications subscription"); + state = State::Finished; + } + } + v = next_input => { + if let Some(Input::Activated(id, action)) = v { + if let Err(err) = proxy.invoke_action(id, action.clone()).await { + tracing::error!("Failed to invoke action {id} {action}"); + } else { + tracing::error!("Invoked {action} for {id}") + } + } else { + tracing::error!("Channel closed, ending notifications subscription"); + state = State::Finished; + } } - }; - while let Some(msg) = signal.next().await { - let Some(args) = msg.args().into_iter().next() else { - break; - }; - let notification = Notification::new( - args.app_name, - args.id, - args.app_icon, - args.summary, - args.body, - args.actions, - args.hints, - args.expire_timeout, - ); - _ = output.send(notification).await; } } State::Finished => { @@ -97,6 +143,8 @@ trait NotificationsApplet { hints: HashMap<&str, zbus::zvariant::Value<'_>>, expire_timeout: i32, ) -> zbus::Result<()>; + + fn invoke_action(&self, id: u32, action: String) -> zbus::Result<()>; } pub async fn get_proxy() -> anyhow::Result> {