feat: Add screen filter settings
This commit is contained in:
parent
64d013ed38
commit
6cb05e6494
6 changed files with 239 additions and 17 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1704,6 +1704,8 @@ dependencies = [
|
||||||
"locales-rs",
|
"locales-rs",
|
||||||
"mime 0.3.17",
|
"mime 0.3.17",
|
||||||
"notify 6.1.1",
|
"notify 6.1.1",
|
||||||
|
"num-derive 0.4.2",
|
||||||
|
"num-traits",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex",
|
"regex",
|
||||||
"ron 0.8.1",
|
"ron 0.8.1",
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@ gettext-rs = { version = "0.7.2", features = [
|
||||||
"gettext-system",
|
"gettext-system",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
async-fn-stream = "0.2.2"
|
async-fn-stream = "0.2.2"
|
||||||
|
num-traits = "0.2"
|
||||||
|
num-derive = "0.4"
|
||||||
|
|
||||||
[dependencies.cosmic-settings-subscriptions]
|
[dependencies.cosmic-settings-subscriptions]
|
||||||
git = "https://github.com/pop-os/cosmic-settings-subscriptions"
|
git = "https://github.com/pop-os/cosmic-settings-subscriptions"
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,9 @@ impl Page {
|
||||||
Message::Event(AccessibilityEvent::Magnifier(value)) => {
|
Message::Event(AccessibilityEvent::Magnifier(value)) => {
|
||||||
self.magnifier_state = value;
|
self.magnifier_state = value;
|
||||||
}
|
}
|
||||||
|
Message::Event(
|
||||||
|
AccessibilityEvent::Bound(_) | AccessibilityEvent::ScreenFilter { .. },
|
||||||
|
) => {}
|
||||||
Message::SetMagnifier(value) => {
|
Message::SetMagnifier(value) => {
|
||||||
if let Some(sender) = self.wayland_thread.as_ref() {
|
if let Some(sender) = self.wayland_thread.as_ref() {
|
||||||
let _ = sender.send(AccessibilityRequest::Magnifier(value));
|
let _ = sender.send(AccessibilityRequest::Magnifier(value));
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,63 @@
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
|
Apply, Task,
|
||||||
cosmic_theme::{CosmicPalette, ThemeBuilder},
|
cosmic_theme::{CosmicPalette, ThemeBuilder},
|
||||||
iced_core::text::Wrapping,
|
iced_core::text::Wrapping,
|
||||||
theme::{self, CosmicTheme},
|
theme::{self, CosmicTheme},
|
||||||
widget::{button, container, horizontal_space, icon, settings, text},
|
widget::{button, container, dropdown, horizontal_space, icon, settings, text, toggler},
|
||||||
Apply, Task,
|
|
||||||
};
|
};
|
||||||
pub use cosmic_comp_config::ZoomMovement;
|
pub use cosmic_comp_config::ZoomMovement;
|
||||||
use cosmic_config::CosmicConfigEntry;
|
use cosmic_config::CosmicConfigEntry;
|
||||||
use cosmic_settings_page::{
|
use cosmic_settings_page::{
|
||||||
self as page,
|
self as page, Insert,
|
||||||
section::{self, Section},
|
section::{self, Section},
|
||||||
Insert,
|
|
||||||
};
|
};
|
||||||
|
use num_traits::FromPrimitive;
|
||||||
use slotmap::SlotMap;
|
use slotmap::SlotMap;
|
||||||
|
|
||||||
pub mod magnifier;
|
pub mod magnifier;
|
||||||
mod wayland;
|
mod wayland;
|
||||||
pub use wayland::{AccessibilityEvent, AccessibilityRequest};
|
pub use wayland::{AccessibilityEvent, AccessibilityRequest, ColorFilter};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug)]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
entity: page::Entity,
|
entity: page::Entity,
|
||||||
magnifier_state: bool,
|
magnifier_state: bool,
|
||||||
|
screen_inverted: bool,
|
||||||
|
screen_filter_active: bool,
|
||||||
|
screen_filter_selection: ColorFilter,
|
||||||
|
screen_filter_selections: Vec<String>,
|
||||||
|
|
||||||
wayland_available: bool,
|
wayland_available: Option<u32>,
|
||||||
wayland_thread: Option<wayland::Sender>,
|
wayland_thread: Option<wayland::Sender>,
|
||||||
theme: Box<cosmic::cosmic_theme::Theme>,
|
theme: Box<cosmic::cosmic_theme::Theme>,
|
||||||
high_contrast: Option<bool>,
|
high_contrast: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Page {
|
||||||
|
fn default() -> Self {
|
||||||
|
Page {
|
||||||
|
entity: page::Entity::default(),
|
||||||
|
magnifier_state: false,
|
||||||
|
screen_inverted: false,
|
||||||
|
screen_filter_active: false,
|
||||||
|
screen_filter_selection: ColorFilter::Greyscale,
|
||||||
|
screen_filter_selections: vec![
|
||||||
|
// This order has to match the representation of `ColorFilter`
|
||||||
|
fl!("color-filter", "greyscale"),
|
||||||
|
fl!("color-filter", "deuteranopia"),
|
||||||
|
fl!("color-filter", "protanopia"),
|
||||||
|
fl!("color-filter", "tritanopia"),
|
||||||
|
fl!("color-filter", "unknown"),
|
||||||
|
],
|
||||||
|
|
||||||
|
wayland_available: None,
|
||||||
|
wayland_thread: None,
|
||||||
|
theme: Box::default(),
|
||||||
|
high_contrast: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Event(wayland::AccessibilityEvent),
|
Event(wayland::AccessibilityEvent),
|
||||||
|
|
@ -36,6 +65,9 @@ pub enum Message {
|
||||||
Return,
|
Return,
|
||||||
HighContrast(bool),
|
HighContrast(bool),
|
||||||
SystemTheme(Box<cosmic::cosmic_theme::Theme>),
|
SystemTheme(Box<cosmic::cosmic_theme::Theme>),
|
||||||
|
SetScreenInverted(bool),
|
||||||
|
SetScreenFilterActive(bool),
|
||||||
|
SetScreenFilterSelection(ColorFilter),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl page::Page<crate::pages::Message> for Page {
|
impl page::Page<crate::pages::Message> for Page {
|
||||||
|
|
@ -62,7 +94,6 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
if self.wayland_thread.is_none() {
|
if self.wayland_thread.is_none() {
|
||||||
match wayland::spawn_wayland_connection() {
|
match wayland::spawn_wayland_connection() {
|
||||||
Ok((tx, mut rx)) => {
|
Ok((tx, mut rx)) => {
|
||||||
self.wayland_available = true;
|
|
||||||
self.wayland_thread = Some(tx);
|
self.wayland_thread = Some(tx);
|
||||||
|
|
||||||
return cosmic::Task::stream(async_fn_stream::fn_stream(
|
return cosmic::Task::stream(async_fn_stream::fn_stream(
|
||||||
|
|
@ -88,7 +119,7 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
"Failed to spawn wayland connection for accessibility page: {}",
|
"Failed to spawn wayland connection for accessibility page: {}",
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
self.wayland_available = false;
|
self.wayland_available = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,6 +148,9 @@ pub fn vision() -> section::Section<crate::pages::Message> {
|
||||||
off = fl!("accessibility", "off");
|
off = fl!("accessibility", "off");
|
||||||
unavailable = fl!("accessibility", "unavailable");
|
unavailable = fl!("accessibility", "unavailable");
|
||||||
high_contrast = fl!("accessibility", "high-contrast");
|
high_contrast = fl!("accessibility", "high-contrast");
|
||||||
|
invert_colors = fl!("accessibility", "invert-colors");
|
||||||
|
color_filters = fl!("accessibility", "color-filters");
|
||||||
|
color_filter_type = fl!("color-filter");
|
||||||
});
|
});
|
||||||
|
|
||||||
Section::default()
|
Section::default()
|
||||||
|
|
@ -134,7 +168,7 @@ pub fn vision() -> section::Section<crate::pages::Message> {
|
||||||
.find(|(_, v)| v.id == "accessibility_magnifier")
|
.find(|(_, v)| v.id == "accessibility_magnifier")
|
||||||
.expect("magnifier page not found");
|
.expect("magnifier page not found");
|
||||||
|
|
||||||
let status_text = if page.wayland_available {
|
let status_text = if page.wayland_available.is_some() {
|
||||||
if page.magnifier_state {
|
if page.magnifier_state {
|
||||||
&descriptions[on]
|
&descriptions[on]
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -158,6 +192,7 @@ pub fn vision() -> section::Section<crate::pages::Message> {
|
||||||
.class(theme::Button::Transparent)
|
.class(theme::Button::Transparent)
|
||||||
.on_press_maybe(
|
.on_press_maybe(
|
||||||
page.wayland_available
|
page.wayland_available
|
||||||
|
.is_some()
|
||||||
.then_some(crate::pages::Message::Page(magnifier_entity)),
|
.then_some(crate::pages::Message::Page(magnifier_entity)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -168,6 +203,50 @@ pub fn vision() -> section::Section<crate::pages::Message> {
|
||||||
)
|
)
|
||||||
.map(crate::pages::Message::Accessibility),
|
.map(crate::pages::Message::Accessibility),
|
||||||
)
|
)
|
||||||
|
.add(
|
||||||
|
cosmic::Element::from(
|
||||||
|
settings::item::builder(&descriptions[invert_colors]).control(
|
||||||
|
toggler(page.screen_inverted).on_toggle_maybe(
|
||||||
|
page.wayland_available
|
||||||
|
.is_some_and(|ver| ver >= 2)
|
||||||
|
.then_some(Message::SetScreenInverted),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map(crate::pages::Message::Accessibility),
|
||||||
|
)
|
||||||
|
.add({
|
||||||
|
cosmic::Element::from(
|
||||||
|
settings::item::builder(&descriptions[color_filters]).control(
|
||||||
|
toggler(page.screen_filter_active).on_toggle_maybe(
|
||||||
|
page.wayland_available
|
||||||
|
.is_some_and(|ver| ver >= 2)
|
||||||
|
.then_some(Message::SetScreenFilterActive),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map(crate::pages::Message::Accessibility)
|
||||||
|
})
|
||||||
|
.add({
|
||||||
|
let selections = if page.screen_filter_selection == ColorFilter::Unknown {
|
||||||
|
&page.screen_filter_selections
|
||||||
|
} else {
|
||||||
|
&page.screen_filter_selections[0..4]
|
||||||
|
};
|
||||||
|
cosmic::Element::from(
|
||||||
|
settings::item::builder(&descriptions[color_filter_type]).control(
|
||||||
|
dropdown(
|
||||||
|
selections,
|
||||||
|
Some(page.screen_filter_selection as usize),
|
||||||
|
move |idx| {
|
||||||
|
let filter = ColorFilter::from_usize(idx).unwrap_or_default();
|
||||||
|
Message::SetScreenFilterSelection(filter)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.map(crate::pages::Message::Accessibility)
|
||||||
|
})
|
||||||
.into()
|
.into()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -175,14 +254,25 @@ pub fn vision() -> section::Section<crate::pages::Message> {
|
||||||
impl Page {
|
impl Page {
|
||||||
pub fn update(&mut self, message: Message) -> cosmic::iced::Task<crate::app::Message> {
|
pub fn update(&mut self, message: Message) -> cosmic::iced::Task<crate::app::Message> {
|
||||||
match message {
|
match message {
|
||||||
|
Message::Event(AccessibilityEvent::Bound(version)) => {
|
||||||
|
self.wayland_available = Some(version);
|
||||||
|
}
|
||||||
Message::Event(AccessibilityEvent::Magnifier(value)) => {
|
Message::Event(AccessibilityEvent::Magnifier(value)) => {
|
||||||
self.magnifier_state = value;
|
self.magnifier_state = value;
|
||||||
}
|
}
|
||||||
|
Message::Event(AccessibilityEvent::ScreenFilter { inverted, filter }) => {
|
||||||
|
self.screen_inverted = inverted;
|
||||||
|
self.screen_filter_active = filter.is_some();
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
self.screen_filter_selection = filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
Message::Event(AccessibilityEvent::Closed) | Message::ProtocolUnavailable => {
|
Message::Event(AccessibilityEvent::Closed) | Message::ProtocolUnavailable => {
|
||||||
self.wayland_available = false;
|
self.wayland_available = None;
|
||||||
|
self.screen_filter_active = false;
|
||||||
}
|
}
|
||||||
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) => {
|
Message::SystemTheme(theme) => {
|
||||||
self.theme = theme;
|
self.theme = theme;
|
||||||
|
|
@ -243,6 +333,34 @@ impl Page {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Message::SetScreenInverted(inverted) => {
|
||||||
|
if let Some(sender) = self.wayland_thread.as_ref() {
|
||||||
|
let _ = sender.send(AccessibilityRequest::ScreenFilter {
|
||||||
|
inverted,
|
||||||
|
filter: Some(wayland::ColorFilter::Unknown),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::SetScreenFilterActive(active) => {
|
||||||
|
if let Some(sender) = self.wayland_thread.as_ref() {
|
||||||
|
let _ = sender.send(AccessibilityRequest::ScreenFilter {
|
||||||
|
inverted: self.screen_inverted,
|
||||||
|
filter: active.then_some(self.screen_filter_selection),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Message::SetScreenFilterSelection(filter) => {
|
||||||
|
if self.screen_filter_active && self.wayland_available.is_some_and(|ver| ver >= 2) {
|
||||||
|
if let Some(sender) = self.wayland_thread.as_ref() {
|
||||||
|
let _ = sender.send(AccessibilityRequest::ScreenFilter {
|
||||||
|
inverted: self.screen_inverted,
|
||||||
|
filter: Some(filter),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.screen_filter_selection = filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmic::iced::Task::none()
|
cosmic::iced::Task::none()
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use cosmic_protocols::a11y::v1::client::cosmic_a11y_manager_v1;
|
use cosmic_protocols::a11y::v1::client::cosmic_a11y_manager_v1;
|
||||||
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
use sctk::{
|
use sctk::{
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{self, channel, LoopSignal},
|
calloop::{self, LoopSignal, channel},
|
||||||
calloop_wayland_source::WaylandSource,
|
calloop_wayland_source::WaylandSource,
|
||||||
client::{
|
client::{
|
||||||
globals::{registry_queue_init, GlobalListContents},
|
ConnectError, Connection, Dispatch, Proxy, WEnum,
|
||||||
|
globals::{GlobalListContents, registry_queue_init},
|
||||||
protocol::wl_registry,
|
protocol::wl_registry,
|
||||||
ConnectError, Connection, Dispatch, Proxy,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
registry::RegistryState,
|
registry::RegistryState,
|
||||||
|
|
@ -15,13 +16,37 @@ use tokio::sync::mpsc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum AccessibilityEvent {
|
pub enum AccessibilityEvent {
|
||||||
|
Bound(u32),
|
||||||
Magnifier(bool),
|
Magnifier(bool),
|
||||||
|
ScreenFilter {
|
||||||
|
inverted: bool,
|
||||||
|
filter: Option<ColorFilter>,
|
||||||
|
},
|
||||||
Closed,
|
Closed,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive)]
|
||||||
|
pub enum ColorFilter {
|
||||||
|
Greyscale,
|
||||||
|
Deuteranopia,
|
||||||
|
Protanopia,
|
||||||
|
Tritanopia,
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ColorFilter {
|
||||||
|
fn default() -> Self {
|
||||||
|
ColorFilter::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum AccessibilityRequest {
|
pub enum AccessibilityRequest {
|
||||||
Magnifier(bool),
|
Magnifier(bool),
|
||||||
|
ScreenFilter {
|
||||||
|
inverted: bool,
|
||||||
|
filter: Option<ColorFilter>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Sender = calloop::channel::Sender<AccessibilityRequest>;
|
pub type Sender = calloop::channel::Sender<AccessibilityRequest>;
|
||||||
|
|
@ -40,7 +65,7 @@ pub fn spawn_wayland_connection() -> Result<
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
if let Err(err) = wayland_thread(conn, event_tx.clone(), request_rx) {
|
if let Err(err) = wayland_thread(conn, event_tx.clone(), request_rx) {
|
||||||
tracing::warn!("Accessibility protocol wayland thread crashed: {}", err);
|
tracing::warn!("Accessibility protocol wayland thread crashed: {}", err);
|
||||||
let _ = event_tx.send(AccessibilityEvent::Closed);
|
let _ = event_tx.blocking_send(AccessibilityEvent::Closed);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -58,6 +83,8 @@ fn wayland_thread(
|
||||||
global: cosmic_a11y_manager_v1::CosmicA11yManagerV1,
|
global: cosmic_a11y_manager_v1::CosmicA11yManagerV1,
|
||||||
|
|
||||||
magnifier: bool,
|
magnifier: bool,
|
||||||
|
screen_inverted: bool,
|
||||||
|
screen_filter: Option<ColorFilter>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Dispatch<cosmic_a11y_manager_v1::CosmicA11yManagerV1, ()> for State {
|
impl Dispatch<cosmic_a11y_manager_v1::CosmicA11yManagerV1, ()> for State {
|
||||||
|
|
@ -87,6 +114,41 @@ fn wayland_thread(
|
||||||
state.magnifier = magnifier;
|
state.magnifier = magnifier;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cosmic_a11y_manager_v1::Event::ScreenFilter { inverted, filter } => {
|
||||||
|
let inverted = inverted
|
||||||
|
.into_result()
|
||||||
|
.unwrap_or(cosmic_a11y_manager_v1::ActiveState::Disabled)
|
||||||
|
== cosmic_a11y_manager_v1::ActiveState::Enabled;
|
||||||
|
let filter = match filter {
|
||||||
|
WEnum::Value(cosmic_a11y_manager_v1::Filter::Disabled) => None,
|
||||||
|
WEnum::Value(cosmic_a11y_manager_v1::Filter::Greyscale) => {
|
||||||
|
Some(ColorFilter::Greyscale)
|
||||||
|
}
|
||||||
|
WEnum::Value(cosmic_a11y_manager_v1::Filter::DaltonizeProtanopia) => {
|
||||||
|
Some(ColorFilter::Protanopia)
|
||||||
|
}
|
||||||
|
WEnum::Value(cosmic_a11y_manager_v1::Filter::DaltonizeDeuteranopia) => {
|
||||||
|
Some(ColorFilter::Deuteranopia)
|
||||||
|
}
|
||||||
|
WEnum::Value(cosmic_a11y_manager_v1::Filter::DaltonizeTritanopia) => {
|
||||||
|
Some(ColorFilter::Tritanopia)
|
||||||
|
}
|
||||||
|
WEnum::Value(_) | WEnum::Unknown(_) => Some(ColorFilter::Unknown),
|
||||||
|
};
|
||||||
|
|
||||||
|
if inverted != state.screen_inverted || filter != state.screen_filter {
|
||||||
|
if state
|
||||||
|
.tx
|
||||||
|
.blocking_send(AccessibilityEvent::ScreenFilter { inverted, filter })
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
state.loop_signal.stop();
|
||||||
|
state.loop_signal.wakeup();
|
||||||
|
};
|
||||||
|
state.screen_inverted = inverted;
|
||||||
|
state.screen_filter = filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -117,12 +179,14 @@ fn wayland_thread(
|
||||||
let registry_state = RegistryState::new(&globals);
|
let registry_state = RegistryState::new(&globals);
|
||||||
let Ok(global) = registry_state.bind_one::<cosmic_a11y_manager_v1::CosmicA11yManagerV1, _, _>(
|
let Ok(global) = registry_state.bind_one::<cosmic_a11y_manager_v1::CosmicA11yManagerV1, _, _>(
|
||||||
&qhandle,
|
&qhandle,
|
||||||
1..=1,
|
1..=2,
|
||||||
(),
|
(),
|
||||||
) else {
|
) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let _ = tx.blocking_send(AccessibilityEvent::Bound(global.version()));
|
||||||
|
|
||||||
loop_handle
|
loop_handle
|
||||||
.insert_source(rx, |request, _, state| match request {
|
.insert_source(rx, |request, _, state| match request {
|
||||||
channel::Event::Msg(AccessibilityRequest::Magnifier(val)) => {
|
channel::Event::Msg(AccessibilityRequest::Magnifier(val)) => {
|
||||||
|
|
@ -132,6 +196,29 @@ fn wayland_thread(
|
||||||
cosmic_a11y_manager_v1::ActiveState::Disabled
|
cosmic_a11y_manager_v1::ActiveState::Disabled
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
channel::Event::Msg(AccessibilityRequest::ScreenFilter { inverted, filter }) => {
|
||||||
|
state.global.set_screen_filter(
|
||||||
|
if inverted {
|
||||||
|
cosmic_a11y_manager_v1::ActiveState::Enabled
|
||||||
|
} else {
|
||||||
|
cosmic_a11y_manager_v1::ActiveState::Disabled
|
||||||
|
},
|
||||||
|
match filter {
|
||||||
|
None => cosmic_a11y_manager_v1::Filter::Disabled,
|
||||||
|
Some(ColorFilter::Greyscale) => cosmic_a11y_manager_v1::Filter::Greyscale,
|
||||||
|
Some(ColorFilter::Protanopia) => {
|
||||||
|
cosmic_a11y_manager_v1::Filter::DaltonizeProtanopia
|
||||||
|
}
|
||||||
|
Some(ColorFilter::Deuteranopia) => {
|
||||||
|
cosmic_a11y_manager_v1::Filter::DaltonizeDeuteranopia
|
||||||
|
}
|
||||||
|
Some(ColorFilter::Tritanopia) => {
|
||||||
|
cosmic_a11y_manager_v1::Filter::DaltonizeTritanopia
|
||||||
|
}
|
||||||
|
Some(ColorFilter::Unknown) => cosmic_a11y_manager_v1::Filter::Unknown,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
channel::Event::Closed => {
|
channel::Event::Closed => {
|
||||||
state.loop_signal.stop();
|
state.loop_signal.stop();
|
||||||
state.loop_signal.wakeup();
|
state.loop_signal.wakeup();
|
||||||
|
|
@ -145,6 +232,8 @@ fn wayland_thread(
|
||||||
global,
|
global,
|
||||||
|
|
||||||
magnifier: false,
|
magnifier: false,
|
||||||
|
screen_inverted: false,
|
||||||
|
screen_filter: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
event_loop.run(None, &mut state, |_| {})?;
|
event_loop.run(None, &mut state, |_| {})?;
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,8 @@ accessibility = Accessibility
|
||||||
.off = Off
|
.off = Off
|
||||||
.unavailable = Unavailable
|
.unavailable = Unavailable
|
||||||
.high-contrast = High contrast mode
|
.high-contrast = High contrast mode
|
||||||
|
.invert-colors = Invert Colors
|
||||||
|
.color-filters = Color filters
|
||||||
magnifier = Magnifier
|
magnifier = Magnifier
|
||||||
.controls = Or use these shortcuts: { $zoom_in ->
|
.controls = Or use these shortcuts: { $zoom_in ->
|
||||||
[zero] {""}
|
[zero] {""}
|
||||||
|
|
@ -153,6 +155,12 @@ magnifier = Magnifier
|
||||||
.continuous = Continuously with pointer
|
.continuous = Continuously with pointer
|
||||||
.onedge = When pointer reaches edge
|
.onedge = When pointer reaches edge
|
||||||
.centered = To keep pointer centered
|
.centered = To keep pointer centered
|
||||||
|
color-filter = Color filter type
|
||||||
|
.unknown = Unknown Filter active
|
||||||
|
.greyscale = Greyscale
|
||||||
|
.deuteranopia = Green/Red (green weakness, Deuteranopia)
|
||||||
|
.protanopia = Red/Green (red weakness, Protanopia)
|
||||||
|
.tritanopia = Blue/Yellow (blue weakness, Tritanopia)
|
||||||
|
|
||||||
## Desktop
|
## Desktop
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue