wip: support desktop portal color-scheme, and accent variables

This commit is contained in:
Ashley Wulber 2024-02-21 17:34:42 -05:00 committed by Ashley Wulber
parent ce45af20f8
commit c390b2614d
7 changed files with 264 additions and 25 deletions

View file

@ -3,6 +3,8 @@
//! Contains the [`Theme`] type and its widget stylesheet implementations.
#[cfg(feature = "xdg-portal")]
pub mod portal;
pub mod style;
use cosmic_theme::ThemeMode;
pub use style::*;
@ -94,23 +96,8 @@ pub fn subscription(is_dark: bool) -> Subscription<crate::theme::Theme> {
})
}
/// Loads the preferred system theme from `cosmic-config`.
pub fn system_preference() -> Theme {
let Ok(mode_config) = ThemeMode::config() else {
return Theme::dark();
};
let Ok(is_dark) = ThemeMode::is_dark(&mode_config) else {
return Theme::dark();
};
let helper = if is_dark {
crate::cosmic_theme::Theme::dark_config()
} else {
crate::cosmic_theme::Theme::light_config()
};
let Ok(helper) = helper else {
pub fn system_dark() -> Theme {
let Ok(helper) = crate::cosmic_theme::Theme::dark_config() else {
return Theme::dark();
};
@ -124,6 +111,37 @@ pub fn system_preference() -> Theme {
Theme::system(Arc::new(t))
}
pub fn system_light() -> Theme {
let Ok(helper) = crate::cosmic_theme::Theme::dark_config() else {
return Theme::dark();
};
let t = crate::cosmic_theme::Theme::get_entry(&helper).unwrap_or_else(|(errors, theme)| {
for err in errors {
tracing::error!("{:?}", err);
}
theme
});
Theme::system(Arc::new(t))
}
/// Loads the preferred system theme from `cosmic-config`.
pub fn system_preference() -> Theme {
let Ok(mode_config) = ThemeMode::config() else {
return Theme::dark();
};
let Ok(is_dark) = ThemeMode::is_dark(&mode_config) else {
return Theme::dark();
};
if is_dark {
system_dark()
} else {
system_light()
}
}
#[must_use]
#[derive(Debug, Clone, PartialEq, Default)]
pub enum ThemeType {

77
src/theme/portal.rs Normal file
View file

@ -0,0 +1,77 @@
use ashpd::desktop::settings::{ColorScheme, Contrast};
use ashpd::desktop::Color;
use iced::futures::{self, select, FutureExt, SinkExt, StreamExt};
use iced_futures::subscription;
#[derive(Debug, Clone)]
pub enum Desktop {
Accent(Color),
ColorScheme(ColorScheme),
Contrast(Contrast),
}
pub fn desktop_settings() -> iced_futures::Subscription<Desktop> {
subscription::channel(std::any::TypeId::of::<Desktop>(), 10, |mut tx| {
async move {
let Ok(settings) = ashpd::desktop::settings::Settings::new().await else {
// wait forever
futures::future::pending::<()>().await;
unreachable!()
};
let mut color_scheme_stream = settings.receive_color_scheme_changed().await.ok();
let mut accent_stream = settings.receive_accent_color_changed().await.ok();
let mut contrast_stream = settings.receive_contrast_changed().await.ok();
loop {
let next_color_scheme = async {
if let Some(s) = color_scheme_stream.as_mut() {
return s.next().await;
}
futures::future::pending().await
};
let next_accent = async {
if let Some(s) = accent_stream.as_mut() {
// Item type is wrong in this version
// updating requires updating to zbus 4
return if s.next().await.is_some() {
settings.accent_color().await.ok()
} else {
None
};
}
futures::future::pending().await
};
let next_contrast = async {
if let Some(s) = contrast_stream.as_mut() {
return s.next().await;
}
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;
}
},
a = next_accent.fuse() => {
if let Some(a) = a {
_ = tx.send(Desktop::Accent(a)).await;
} else {
accent_stream = None;
}
},
c = next_contrast.fuse() => {
if let Some(c) = c {
_ = tx.send(Desktop::Contrast(c)).await;
} else {
contrast_stream = None;
}
}
};
}
}
})
}