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

34
Cargo.lock generated
View file

@ -1519,7 +1519,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config" name = "cosmic-config"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"atomicwrites", "atomicwrites",
"cosmic-config-derive", "cosmic-config-derive",
@ -1541,7 +1541,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-config-derive" name = "cosmic-config-derive"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"quote", "quote",
"syn 1.0.109", "syn 1.0.109",
@ -1822,8 +1822,8 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-text" name = "cosmic-text"
version = "0.12.1" version = "0.13.1"
source = "git+https://github.com/pop-os/cosmic-text.git#974ddaed96b334f560b606ebe5d2ca2d2f9f23ef" source = "git+https://github.com/pop-os/cosmic-text.git#60f2c2b0c2e7cf8734b3ad0fc94ef7bce94f649b"
dependencies = [ dependencies = [
"bitflags 2.8.0", "bitflags 2.8.0",
"fontdb 0.16.2", "fontdb 0.16.2",
@ -1845,7 +1845,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-theme" name = "cosmic-theme"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"almost", "almost",
"cosmic-config", "cosmic-config",
@ -3216,7 +3216,7 @@ dependencies = [
[[package]] [[package]]
name = "iced" name = "iced"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"dnd", "dnd",
"iced_accessibility", "iced_accessibility",
@ -3234,7 +3234,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_accessibility" name = "iced_accessibility"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"accesskit", "accesskit",
"accesskit_winit", "accesskit_winit",
@ -3243,7 +3243,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_core" name = "iced_core"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"bitflags 2.8.0", "bitflags 2.8.0",
"bytes", "bytes",
@ -3268,7 +3268,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_futures" name = "iced_futures"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"futures", "futures",
"iced_core", "iced_core",
@ -3294,7 +3294,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_graphics" name = "iced_graphics"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"bitflags 2.8.0", "bitflags 2.8.0",
"bytemuck", "bytemuck",
@ -3316,7 +3316,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_renderer" name = "iced_renderer"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"iced_graphics", "iced_graphics",
"iced_tiny_skia", "iced_tiny_skia",
@ -3328,7 +3328,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_runtime" name = "iced_runtime"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"bytes", "bytes",
"cosmic-client-toolkit", "cosmic-client-toolkit",
@ -3344,7 +3344,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_tiny_skia" name = "iced_tiny_skia"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cosmic-text", "cosmic-text",
@ -3360,7 +3360,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_wgpu" name = "iced_wgpu"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"as-raw-xcb-connection", "as-raw-xcb-connection",
"bitflags 2.8.0", "bitflags 2.8.0",
@ -3391,7 +3391,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_widget" name = "iced_widget"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -3410,7 +3410,7 @@ dependencies = [
[[package]] [[package]]
name = "iced_winit" name = "iced_winit"
version = "0.14.0-dev" version = "0.14.0-dev"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"cosmic-client-toolkit", "cosmic-client-toolkit",
"dnd", "dnd",
@ -4416,7 +4416,7 @@ checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]] [[package]]
name = "libcosmic" name = "libcosmic"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#50d2104485649bdddf1247f63ec3cf2eb81c5817" source = "git+https://github.com/pop-os/libcosmic#64ddcb3bf2aed84256fe8261a0b05e1831720463"
dependencies = [ dependencies = [
"apply", "apply",
"ashpd 0.9.2", "ashpd 0.9.2",

View file

@ -800,6 +800,21 @@ impl cosmic::Application for SettingsApp {
.dialog(self.active_page) .dialog(self.active_page)
.map(|e| e.map(Message::PageMessage)) .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 { impl SettingsApp {

View file

@ -1,10 +1,13 @@
use cosmic::{ use cosmic::{
app,
cosmic_theme::{CosmicPalette, ThemeBuilder},
iced_core::text::Wrapping, iced_core::text::Wrapping,
theme, theme::{self, CosmicTheme},
widget::{button, container, horizontal_space, icon, settings, text}, widget::{button, container, horizontal_space, icon, settings, text},
Apply, Apply, Task,
}; };
pub use cosmic_comp_config::ZoomMovement; pub use cosmic_comp_config::ZoomMovement;
use cosmic_config::CosmicConfigEntry;
use cosmic_settings_page::{ use cosmic_settings_page::{
self as page, self as page,
section::{self, Section}, section::{self, Section},
@ -14,6 +17,7 @@ use slotmap::SlotMap;
pub mod magnifier; pub mod magnifier;
mod wayland; mod wayland;
use tokio::task::spawn_blocking;
pub use wayland::{AccessibilityEvent, AccessibilityRequest}; pub use wayland::{AccessibilityEvent, AccessibilityRequest};
#[derive(Debug, Default)] #[derive(Debug, Default)]
@ -23,6 +27,8 @@ pub struct Page {
wayland_available: bool, wayland_available: bool,
wayland_thread: Option<wayland::Sender>, wayland_thread: Option<wayland::Sender>,
theme: Box<cosmic::cosmic_theme::Theme>,
high_contrast: Option<bool>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -30,6 +36,8 @@ pub enum Message {
Event(wayland::AccessibilityEvent), Event(wayland::AccessibilityEvent),
ProtocolUnavailable, ProtocolUnavailable,
Return, Return,
HighContrast(bool),
SystemTheme(Box<cosmic::cosmic_theme::Theme>),
} }
impl page::Page<crate::pages::Message> for Page { impl page::Page<crate::pages::Message> for Page {
@ -110,6 +118,7 @@ pub fn vision() -> section::Section<crate::pages::Message> {
on = fl!("accessibility", "on"); on = fl!("accessibility", "on");
off = fl!("accessibility", "off"); off = fl!("accessibility", "off");
unavailable = fl!("accessibility", "unavailable"); unavailable = fl!("accessibility", "unavailable");
high_contrast = fl!("accessibility", "high-contrast");
}); });
Section::default() Section::default()
@ -154,6 +163,13 @@ pub fn vision() -> section::Section<crate::pages::Message> {
.then_some(crate::pages::Message::Page(magnifier_entity)), .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() .into()
}) })
} }
@ -170,6 +186,65 @@ impl Page {
Message::Return => { Message::Return => {
return cosmic::iced::Task::done(crate::app::Message::Page(self.entity)) 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() cosmic::iced::Task::none()

View file

@ -134,6 +134,7 @@ accessibility = Accessibility
.on = On .on = On
.off = Off .off = Off
.unavailable = Unavailable .unavailable = Unavailable
.high-contrast = High contrast mode
magnifier = Magnifier magnifier = Magnifier
.controls = Or use these shortcuts: { $zoom_in -> .controls = Or use these shortcuts: { $zoom_in ->
[zero] {""} [zero] {""}