diff --git a/Cargo.lock b/Cargo.lock index 794b5ce..a84404d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2453,9 +2453,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stray" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e467969fcbf600ebb8d302aa6f2ee6cdf65d2a4c642844632bbdbcaf9c9e2b3e" +checksum = "358c1637c5ba4ccf1b6a0698de81454db644866cc426d1abc6d357b2efede511" dependencies = [ "anyhow", "byteorder", diff --git a/Cargo.toml b/Cargo.toml index 6d8d25a..a28cf91 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ futures-util = "0.3.21" chrono = "0.4.19" reqwest = {version = "0.11.14" } regex = { version = "1.6.0", default-features = false, features = ["std"] } -stray = { version = "0.1.2" } +stray = { version = "0.1.3" } dirs = "4.0.0" walkdir = "2.3.2" notify = { version = "5.0.0", default-features = false } @@ -39,4 +39,4 @@ hyprland = "0.3.0" sysinfo = "0.27.0" wayland-client = "0.29.5" wayland-protocols = { version = "0.29.5", features = ["unstable_protocols", "client"] } -smithay-client-toolkit = { version = "0.16.0", default-features = false, features = ["calloop"] } +smithay-client-toolkit = { version = "0.16.0", default-features = false, features = ["calloop"] } \ No newline at end of file diff --git a/src/clients/system_tray.rs b/src/clients/system_tray.rs index d1fb2bb..a494a10 100644 --- a/src/clients/system_tray.rs +++ b/src/clients/system_tray.rs @@ -1,15 +1,25 @@ +use crate::{lock, send}; use async_once::AsyncOnce; +use color_eyre::Report; use lazy_static::lazy_static; +use std::collections::BTreeMap; +use std::sync::{Arc, Mutex}; +use stray::message::menu::TrayMenu; +use stray::message::tray::StatusNotifierItem; use stray::message::{NotifierItemCommand, NotifierItemMessage}; use stray::StatusNotifierWatcher; use tokio::spawn; use tokio::sync::{broadcast, mpsc}; -use tracing::debug; +use tracing::error; + +type Tray = BTreeMap, Option)>; pub struct TrayEventReceiver { tx: mpsc::Sender, b_tx: broadcast::Sender, _b_rx: broadcast::Receiver, + + tray: Arc>, } impl TrayEventReceiver { @@ -20,19 +30,39 @@ impl TrayEventReceiver { let tray = StatusNotifierWatcher::new(rx).await?; let mut host = tray.create_notifier_host("ironbar").await?; - let b_tx2 = b_tx.clone(); - spawn(async move { - while let Ok(message) = host.recv().await { - b_tx2.send(message)?; - } + let tray = Arc::new(Mutex::new(BTreeMap::new())); - Ok::<(), broadcast::error::SendError>(()) - }); + { + let b_tx = b_tx.clone(); + let tray = tray.clone(); + + spawn(async move { + while let Ok(message) = host.recv().await { + send!(b_tx, message.clone()); + let mut tray = lock!(tray); + match message { + NotifierItemMessage::Update { + address, + item, + menu, + } => { + tray.insert(address, (item, menu)); + } + NotifierItemMessage::Remove { address } => { + tray.remove(&address); + } + } + } + + Ok::<(), broadcast::error::SendError>(()) + }); + } Ok(Self { tx, b_tx, _b_rx: b_rx, + tray, }) } @@ -42,7 +72,20 @@ impl TrayEventReceiver { mpsc::Sender, broadcast::Receiver, ) { - (self.tx.clone(), self.b_tx.subscribe()) + let tx = self.tx.clone(); + let b_rx = self.b_tx.subscribe(); + + let tray = lock!(self.tray).clone(); + for (address, (item, menu)) in tray { + let update = NotifierItemMessage::Update { + address, + item, + menu, + }; + send!(self.b_tx, update); + } + + (tx, b_rx) } } @@ -58,11 +101,14 @@ lazy_static! { let tray = TrayEventReceiver::new().await; - if tray.is_ok() || retries == MAX_RETRIES { - break tray; + match tray { + Ok(tray) => break Some(tray), + Err(err) => error!("{:?}", Report::new(err).wrap_err(format!("Failed to create StatusNotifierWatcher (attempt {retries})"))) } - debug!("Failed to create StatusNotifierWatcher (attempt {retries})"); + if retries == MAX_RETRIES { + break None; + } }; value.expect("Failed to create StatusNotifierWatcher")