feat: notification actions
This commit is contained in:
parent
104a608cf1
commit
ad656296e7
4 changed files with 269 additions and 159 deletions
87
Cargo.lock
generated
87
Cargo.lock
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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<Notification>, bool, String, String, String)>,
|
||||
token_tx: Option<calloop::channel::Sender<TokenRequest>>,
|
||||
proxy: NotificationsAppletProxy<'static>,
|
||||
notifications_tx: Option<Sender<notifications::Input>>,
|
||||
}
|
||||
|
||||
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<String>),
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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<Notification> {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Input {
|
||||
Activated(u32, String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Output {
|
||||
Ready(mpsc::Sender<Input>),
|
||||
Notification(Notification),
|
||||
}
|
||||
|
||||
pub fn notifications(proxy: NotificationsAppletProxy<'static>) -> Subscription<Output> {
|
||||
struct SomeWorker;
|
||||
|
||||
Subscription::run_with_id(
|
||||
std::any::TypeId::of::<SomeWorker>(),
|
||||
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<NotificationsAppletProxy<'static>> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue