feat: high contrast toggle (#1039)

This commit is contained in:
Ashley Wulber 2025-03-10 16:14:58 -04:00 committed by GitHub
parent ba53a94e09
commit efabc394fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 110 additions and 19 deletions

View file

@ -800,6 +800,21 @@ impl cosmic::Application for SettingsApp {
.dialog(self.active_page)
.map(|e| e.map(Message::PageMessage))
}
fn system_theme_update(
&mut self,
_keys: &[&'static str],
new_theme: &cosmic::cosmic_theme::Theme,
) -> Task<Self::Message> {
if let Some(page) = self.pages.page_mut::<accessibility::Page>() {
page.update(accessibility::Message::SystemTheme(Box::new(
new_theme.clone(),
)))
.map(Into::into)
} else {
Task::none()
}
}
}
impl SettingsApp {

View file

@ -1,10 +1,13 @@
use cosmic::{
app,
cosmic_theme::{CosmicPalette, ThemeBuilder},
iced_core::text::Wrapping,
theme,
theme::{self, CosmicTheme},
widget::{button, container, horizontal_space, icon, settings, text},
Apply,
Apply, Task,
};
pub use cosmic_comp_config::ZoomMovement;
use cosmic_config::CosmicConfigEntry;
use cosmic_settings_page::{
self as page,
section::{self, Section},
@ -14,6 +17,7 @@ use slotmap::SlotMap;
pub mod magnifier;
mod wayland;
use tokio::task::spawn_blocking;
pub use wayland::{AccessibilityEvent, AccessibilityRequest};
#[derive(Debug, Default)]
@ -23,6 +27,8 @@ pub struct Page {
wayland_available: bool,
wayland_thread: Option<wayland::Sender>,
theme: Box<cosmic::cosmic_theme::Theme>,
high_contrast: Option<bool>,
}
#[derive(Debug, Clone)]
@ -30,6 +36,8 @@ pub enum Message {
Event(wayland::AccessibilityEvent),
ProtocolUnavailable,
Return,
HighContrast(bool),
SystemTheme(Box<cosmic::cosmic_theme::Theme>),
}
impl page::Page<crate::pages::Message> for Page {
@ -110,6 +118,7 @@ pub fn vision() -> section::Section<crate::pages::Message> {
on = fl!("accessibility", "on");
off = fl!("accessibility", "off");
unavailable = fl!("accessibility", "unavailable");
high_contrast = fl!("accessibility", "high-contrast");
});
Section::default()
@ -154,6 +163,13 @@ pub fn vision() -> section::Section<crate::pages::Message> {
.then_some(crate::pages::Message::Page(magnifier_entity)),
)
})
.add(
cosmic::Element::from(
settings::item::builder(&descriptions[high_contrast])
.toggler(page.theme.is_high_contrast, Message::HighContrast),
)
.map(crate::pages::Message::Accessibility),
)
.into()
})
}
@ -170,6 +186,65 @@ impl Page {
Message::Return => {
return cosmic::iced::Task::done(crate::app::Message::Page(self.entity))
}
Message::SystemTheme(theme) => {
self.theme = theme;
}
Message::HighContrast(enabled) => {
if self.theme.is_high_contrast == enabled
|| self.high_contrast.is_some_and(|hc| hc == enabled)
{
return Task::none();
}
self.high_contrast = Some(enabled);
_ = std::thread::spawn(move || {
let set_hc = |is_dark: bool| {
let builder_config = if is_dark {
ThemeBuilder::dark_config()?
} else {
ThemeBuilder::light_config()?
};
let mut builder = match ThemeBuilder::get_entry(&builder_config) {
Ok(b) => b,
Err((errs, b)) => {
tracing::warn!("{errs:?}");
b
}
};
builder.palette = if is_dark {
if enabled {
CosmicPalette::HighContrastDark(builder.palette.inner())
} else {
CosmicPalette::Dark(builder.palette.inner())
}
} else if enabled {
CosmicPalette::HighContrastLight(builder.palette.inner())
} else {
CosmicPalette::Light(builder.palette.inner())
};
builder.write_entry(&builder_config)?;
let new_theme = builder.build();
let theme_config = if is_dark {
CosmicTheme::dark_config()?
} else {
CosmicTheme::light_config()?
};
new_theme.write_entry(&theme_config)?;
Result::<(), cosmic_config::Error>::Ok(())
};
if let Err(err) = set_hc(true) {
tracing::warn!("{err:?}");
}
if let Err(err) = set_hc(false) {
tracing::warn!("{err:?}");
}
});
}
}
cosmic::iced::Task::none()