From 94646f0124f3a40f6f22de752ce7d2e933e86b5b Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Fri, 29 Aug 2025 19:30:42 +0200 Subject: [PATCH] battery: Trigger dgpu refresh on toggle --- cosmic-applet-battery/src/app.rs | 9 +++++++++ cosmic-applet-battery/src/dgpu.rs | 24 +++++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/cosmic-applet-battery/src/app.rs b/cosmic-applet-battery/src/app.rs index 0e3fa86c..afc67da1 100644 --- a/cosmic-applet-battery/src/app.rs +++ b/cosmic-applet-battery/src/app.rs @@ -81,6 +81,7 @@ struct CosmicBatteryApplet { battery_percent: f64, on_battery: bool, gpus: HashMap, + update_trigger: Option>, time_remaining: Duration, max_kbd_brightness: Option, kbd_brightness: Option, @@ -180,6 +181,7 @@ enum Message { SetChargingLimit(chain::Toggler, bool), KeyboardBacklight(KeyboardBacklightUpdate), UpowerDevice(DeviceDbusEvent), + GpuInit(UnboundedSender<()>), GpuOn(PathBuf, String, Option>), GpuOff(PathBuf), ToggleGpuApps(PathBuf), @@ -338,6 +340,9 @@ impl cosmic::Application for CosmicBatteryApplet { if let Some(tx) = self.power_profile_sender.as_ref() { let _ = tx.send(PowerProfileRequest::Get); } + if let Some(tx) = self.update_trigger.as_ref() { + let _ = tx.send(()); + } let mut tasks = vec![get_popup(popup_settings)]; // Try again every time a popup is opened if self.charging_limit.is_none() { @@ -424,6 +429,9 @@ impl cosmic::Application for CosmicBatteryApplet { tokio::spawn(cosmic::process::spawn(cmd)); } }, + Message::GpuInit(tx) => { + self.update_trigger = Some(tx); + } Message::GpuOn(path, name, app_list) => { let toggled = self .gpus @@ -845,6 +853,7 @@ impl cosmic::Application for CosmicBatteryApplet { PowerProfileUpdate::Error(e) => Message::Errored(e), // TODO: handle error }), dgpu_subscription(0).map(|event| match event { + GpuUpdate::Init(tx) => Message::GpuInit(tx), GpuUpdate::On(path, name, list) => Message::GpuOn(path, name, list), GpuUpdate::Off(path) => Message::GpuOff(path), }), diff --git a/cosmic-applet-battery/src/dgpu.rs b/cosmic-applet-battery/src/dgpu.rs index 5fb28a70..c0e5aec5 100644 --- a/cosmic-applet-battery/src/dgpu.rs +++ b/cosmic-applet-battery/src/dgpu.rs @@ -19,6 +19,7 @@ use drm::control::Device as ControlDevice; use futures::{FutureExt, SinkExt}; use tokio::{ io::unix::AsyncFd, + sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, task::spawn_blocking, time::{self, Interval}, }; @@ -396,12 +397,13 @@ pub fn dgpu_subscription( #[derive(Debug)] pub enum State { Ready, - Waiting(GpuMonitor), + Waiting(GpuMonitor, UnboundedReceiver<()>), Finished, } #[derive(Debug)] pub enum GpuUpdate { + Init(UnboundedSender<()>), Off(PathBuf), On(PathBuf, String, Option>), } @@ -412,10 +414,17 @@ async fn start_listening( ) -> State { match state { State::Ready => match GpuMonitor::new().await { - Some(monitor) => State::Waiting(monitor), + Some(monitor) => { + let (tx, rx) = mpsc::unbounded_channel(); + if output.send(GpuUpdate::Init(tx)).await.is_err() { + State::Finished + } else { + State::Waiting(monitor, rx) + } + } None => State::Finished, }, - State::Waiting(mut monitor) => { + State::Waiting(mut monitor, mut trigger) => { let select_all = futures::future::select_all( monitor .gpus @@ -503,7 +512,7 @@ async fn start_listening( i = select_all => { let gpu = &mut monitor.gpus[i]; if gpu.path == monitor.primary_gpu { - return State::Waiting(monitor); + return State::Waiting(monitor, trigger); } trace!("Polling gpu {}", gpu.path.display()); @@ -529,9 +538,14 @@ async fn start_listening( return State::Finished; } } + _ = trigger.recv() => { + for gpu in &mut monitor.gpus { + gpu.interval.reset_immediately(); + } + } }; - State::Waiting(monitor) + State::Waiting(monitor, trigger) } State::Finished => iced::futures::future::pending().await, }