diff --git a/cosmic-settings/src/pages/power/backend/mod.rs b/cosmic-settings/src/pages/power/backend/mod.rs index 7d9c6cc..879c7aa 100644 --- a/cosmic-settings/src/pages/power/backend/mod.rs +++ b/cosmic-settings/src/pages/power/backend/mod.rs @@ -14,6 +14,7 @@ pub trait GetCurrentPowerProfile { async fn get_current_power_profile(&self) -> PowerProfile; } +#[derive(Debug, Clone)] pub enum PowerBackendEnum { S76(S76Backend), PP(PPBackend), @@ -94,6 +95,7 @@ pub fn get_power_profiles() -> Vec { ] } +#[derive(Debug, Clone)] pub struct S76Backend {} impl SetPowerProfile for S76Backend { @@ -157,6 +159,7 @@ async fn get_s76power_daemon_proxy<'a>() -> Result, idle_config: Config, idle_conf: CosmicIdleConfig, + backend: Option, + current_power_profile: Option, } impl Default for Page { @@ -84,6 +86,8 @@ impl Default for Page { .collect(), idle_config, idle_conf, + backend: None, + current_power_profile: None, } } } @@ -121,6 +125,19 @@ impl page::Page for Page { let devices = ConnectedDevice::update_connected_devices().await; Message::UpdateConnectedDevices(devices) }), + cosmic::Task::future(async move { + if let Ok(backend) = tokio::time::timeout( + std::time::Duration::from_millis(1000), + backend::get_backend(), + ) + .await + { + Message::BackendAvailabilityCheck(backend) + } else { + tracing::warn!("Power backend initialization timed out after 1000ms"); + Message::BackendAvailabilityCheck(None) + } + }), cosmic::Task::run( async_fn_stream::fn_stream(|emitter| async move { let span = tracing::span!(tracing::Level::INFO, "power::device_stream task"); @@ -193,19 +210,22 @@ pub enum Message { ScreenOffTimeChange(Option), SuspendOnAcTimeChange(Option), SuspendOnBatteryTimeChange(Option), + BackendAvailabilityCheck(Option), + CurrentPowerProfileUpdate(PowerProfile), Surface(surface::Action), } impl Page { pub fn update(&mut self, message: Message) -> Task { - let runtime = tokio::runtime::Runtime::new().unwrap(); - - let backend = runtime.block_on(backend::get_backend()); - match message { Message::PowerProfileChange(p) => { - if let Some(b) = backend { - runtime.block_on(b.set_power_profile(p)); + if let Some(ref backend) = self.backend { + self.current_power_profile = Some(p); + let backend = backend.clone(); + return cosmic::Task::future(async move { + backend.set_power_profile(p).await; + crate::app::Message::None + }); } } Message::UpdateBattery(battery) => self.battery = battery, @@ -245,6 +265,22 @@ impl Page { Message::Surface(a) => { return cosmic::task::message(crate::app::Message::Surface(a)); } + Message::BackendAvailabilityCheck(backend) => { + self.backend.clone_from(&backend); + + // If backend is available, get the current power profile + if let Some(backend) = backend { + return cosmic::Task::future(async move { + let profile = backend.get_current_power_profile().await; + crate::app::Message::PageMessage(crate::pages::Message::Power( + Message::CurrentPowerProfileUpdate(profile), + )) + }); + } + } + Message::CurrentPowerProfileUpdate(profile) => { + self.current_power_profile = Some(profile); + } }; Task::none() } @@ -368,35 +404,31 @@ fn profiles() -> Section { Section::default() .title(fl!("power-mode")) .descriptions(descriptions) - .view::(move |_binder, _page, section| { + .view::(move |_binder, page, section| { let mut section = settings::section().title(§ion.title); - let runtime = tokio::runtime::Runtime::new().unwrap(); - - let backend = runtime.block_on(backend::get_backend()); - - if let Some(b) = backend { + if page.backend.is_some() { let profiles = backend::get_power_profiles(); - let current_profile = runtime.block_on(b.get_current_power_profile()); - - section = profiles - .into_iter() - .map(|profile| { - settings::item_row(vec![ - radio( - widget::column::with_capacity(2) - .push(text::body(profile.title())) - .push(text::caption(profile.description())), - profile, - Some(current_profile), - Message::PowerProfileChange, - ) - .width(Length::Fill) - .into(), - ]) - }) - .fold(section, settings::Section::add); + if let Some(current_profile) = page.current_power_profile { + section = profiles + .into_iter() + .map(|profile| { + settings::item_row(vec![ + radio( + widget::column::with_capacity(2) + .push(text::body(profile.title())) + .push(text::caption(profile.description())), + profile, + Some(current_profile), + Message::PowerProfileChange, + ) + .width(Length::Fill) + .into(), + ]) + }) + .fold(section, settings::Section::add); + } } else { let item = text::body(fl!("power-mode", "no-backend")); section = section.add(item);