diff --git a/Cargo.lock b/Cargo.lock index c3b30bf0..7bb5bf71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1297,6 +1297,7 @@ dependencies = [ "i18n-embed-fl", "icu", "libcosmic", + "logind-zbus", "once_cell", "rust-embed", "serde", diff --git a/cosmic-applet-time/Cargo.toml b/cosmic-applet-time/Cargo.toml index 4d57fb75..fbeec768 100644 --- a/cosmic-applet-time/Cargo.toml +++ b/cosmic-applet-time/Cargo.toml @@ -26,3 +26,4 @@ icu = { version = "1.5.0", features = [ serde.workspace = true zbus.workspace = true timedate-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" } +logind-zbus = "5.3.2" diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index f150a6b4..7fe294b0 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -25,6 +25,7 @@ use cosmic::{ }, Element, Task, }; +use logind_zbus::manager::ManagerProxy; use once_cell::sync::Lazy; use timedate_zbus::TimeDateProxy; use tokio::{sync::watch, time}; @@ -278,12 +279,40 @@ impl cosmic::Application for Window { ) } + // Update the time when waking from sleep, so it doesn't need to wait until the next + // scheduled tick to update. + async fn wake_from_sleep(output: &mut mpsc::Sender) -> zbus::Result<()> { + let connection = zbus::Connection::system().await?; + let proxy = ManagerProxy::new(&connection).await?; + + while let Some(property) = proxy.receive_prepare_for_sleep().await?.next().await { + let waking = !property.args()?.start(); + if waking { + let _ = output.send(Message::Tick).await; + } + } + + Ok(()) + } + + fn wake_from_sleep_subscription() -> Subscription { + Subscription::run_with_id( + "wake-from-suspend-sub", + stream::channel(1, |mut output| async move { + if let Err(err) = wake_from_sleep(&mut output).await { + tracing::error!(?err, "Failed to subscribe to wake-from-sleep signal"); + } + }), + ) + } + let show_seconds_rx = self.show_seconds_tx.subscribe(); Subscription::batch(vec![ rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)), time_subscription(show_seconds_rx), activation_token_subscription(0).map(Message::Token), timezone_subscription(), + wake_from_sleep_subscription(), self.core.watch_config(Self::APP_ID).map(|u| { for err in u.errors { tracing::error!(?err, "Error watching config");