Compare commits

...
Sign in to create a new pull request.

1 commit

2 changed files with 76 additions and 53 deletions

View file

@ -156,6 +156,7 @@ where
} }
} }
#[allow(clippy::too_many_lines)]
fn subscription(&self) -> Subscription<Self::Message> { fn subscription(&self) -> Subscription<Self::Message> {
let window_events = listen_with(|event, _| { let window_events = listen_with(|event, _| {
match event { match event {
@ -429,6 +430,11 @@ impl<T: Application> Cosmic<T> {
} }
Message::SystemThemeChange(keys, theme) => { Message::SystemThemeChange(keys, theme) => {
let cur_is_dark = THEME.with(|t| t.borrow().theme_type.is_dark());
// Ignore updates if the current theme mode does not match.
if cur_is_dark != theme.cosmic().is_dark {
return iced::Command::none();
}
let cmd = self.app.system_theme_update(&keys, theme.cosmic()); let cmd = self.app.system_theme_update(&keys, theme.cosmic());
// Record the last-known system theme in event that the current theme is custom. // Record the last-known system theme in event that the current theme is custom.
self.app.core_mut().system_theme = theme.clone(); self.app.core_mut().system_theme = theme.clone();
@ -472,6 +478,9 @@ impl<T: Application> Cosmic<T> {
}; };
} }
Message::SystemThemeModeChange(keys, mode) => { Message::SystemThemeModeChange(keys, mode) => {
if !keys.contains(&"is_dark") {
return iced::Command::none();
}
if THEME.with(|t| match t.borrow().theme_type { if THEME.with(|t| match t.borrow().theme_type {
ThemeType::System { ThemeType::System {
theme: _, theme: _,

View file

@ -1,7 +1,6 @@
use ashpd::desktop::settings::{ColorScheme, Contrast}; use ashpd::desktop::settings::{ColorScheme, Contrast};
use ashpd::desktop::Color; use ashpd::desktop::Color;
use iced::futures::{self, select, FutureExt, SinkExt, StreamExt}; use iced::futures::{self, select, FutureExt, SinkExt, StreamExt};
use iced::Subscription;
use iced_futures::subscription; use iced_futures::subscription;
use tracing::error; use tracing::error;
@ -15,68 +14,83 @@ pub enum Desktop {
pub fn desktop_settings() -> iced_futures::Subscription<Desktop> { pub fn desktop_settings() -> iced_futures::Subscription<Desktop> {
subscription::channel(std::any::TypeId::of::<Desktop>(), 10, |mut tx| { subscription::channel(std::any::TypeId::of::<Desktop>(), 10, |mut tx| {
async move { async move {
let Ok(settings) = ashpd::desktop::settings::Settings::new().await else { let mut attempts = 0;
// wait forever
error!("Failed to create the settings proxy");
futures::future::pending::<()>().await;
unreachable!()
};
match settings.color_scheme().await {
Ok(color_scheme) => {
let _ = tx.send(Desktop::ColorScheme(color_scheme)).await;
}
Err(err) => error!("Failed to get the color scheme {err:?}"),
};
match settings.contrast().await {
Ok(contrast) => {
let _ = tx.send(Desktop::Contrast(contrast)).await;
}
Err(err) => error!("Failed to get the contrast {err:?}"),
};
let mut color_scheme_stream = settings.receive_color_scheme_changed().await.ok();
if color_scheme_stream.is_none() {
error!("Failed to receive color scheme changes");
}
let mut contrast_stream = settings.receive_contrast_changed().await.ok();
if contrast_stream.is_none() {
error!("Failed to receive contrast changes");
}
loop { loop {
let next_color_scheme = async { let Ok(settings) = ashpd::desktop::settings::Settings::new().await else {
if let Some(s) = color_scheme_stream.as_mut() { error!("Failed to create the settings proxy");
return s.next().await; #[cfg(feature = "tokio")]
::tokio::time::sleep(::tokio::time::Duration::from_secs(2_u64.pow(attempts)))
.await;
#[cfg(not(feature = "tokio"))]
{
pending::<()>().await;
unreachable!();
} }
futures::future::pending().await attempts += 1;
continue;
}; };
let next_contrast = async { match settings.color_scheme().await {
if let Some(s) = contrast_stream.as_mut() { Ok(color_scheme) => {
return s.next().await; let _ = tx.send(Desktop::ColorScheme(color_scheme)).await;
} }
futures::future::pending().await Err(err) => error!("Failed to get the color scheme {err:?}"),
};
match settings.contrast().await {
Ok(contrast) => {
let _ = tx.send(Desktop::Contrast(contrast)).await;
}
Err(err) => error!("Failed to get the contrast {err:?}"),
}; };
select! { let mut color_scheme_stream = settings.receive_color_scheme_changed().await.ok();
s = next_color_scheme.fuse() => { if color_scheme_stream.is_none() {
if let Some(s) = s { error!("Failed to receive color scheme changes");
_ = tx.send(Desktop::ColorScheme(s)).await; }
} else {
color_scheme_stream = None; let mut contrast_stream = settings.receive_contrast_changed().await.ok();
if contrast_stream.is_none() {
error!("Failed to receive contrast changes");
}
loop {
if color_scheme_stream.is_none() && contrast_stream.is_none() {
break;
}
let next_color_scheme = async {
if let Some(s) = color_scheme_stream.as_mut() {
return s.next().await;
} }
}, futures::future::pending().await
};
c = next_contrast.fuse() => { let next_contrast = async {
if let Some(c) = c { if let Some(s) = contrast_stream.as_mut() {
_ = tx.send(Desktop::Contrast(c)).await; return s.next().await;
} else {
contrast_stream = None;
} }
} futures::future::pending().await
}; };
select! {
s = next_color_scheme.fuse() => {
if let Some(s) = s {
_ = tx.send(Desktop::ColorScheme(s)).await;
} else {
color_scheme_stream = None;
}
},
c = next_contrast.fuse() => {
if let Some(c) = c {
_ = tx.send(Desktop::Contrast(c)).await;
} else {
contrast_stream = None;
}
}
};
// Reset the attempts counter if we successfully received a change
attempts = 0;
}
} }
} }
}) })