Skip to content

Commit a748ea8

Browse files
committed
wayland: Add support for cosmic-a11y version 2
1 parent fc43b25 commit a748ea8

File tree

2 files changed

+129
-9
lines changed

2 files changed

+129
-9
lines changed

src/wayland/handlers/a11y.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
use tracing::warn;
2+
13
use crate::{
4+
config::ColorFilter,
25
state::State,
36
wayland::protocols::a11y::{delegate_a11y, A11yHandler, A11yState},
47
};
@@ -33,6 +36,30 @@ impl A11yHandler for State {
3336
);
3437
}
3538
}
39+
40+
fn request_screen_invert(&mut self, inverted: bool) {
41+
let mut config = self.common.config.dynamic_conf.screen_filter_mut();
42+
let mut updated = (*config).clone();
43+
updated.inverted = inverted;
44+
if let Err(err) = self.backend.update_screen_filter(&updated) {
45+
warn!("Failed to apply screen color invert: {}", err);
46+
} else {
47+
*config = updated;
48+
self.common.a11y_state.set_screen_inverted(inverted);
49+
}
50+
}
51+
52+
fn request_screen_filter(&mut self, filter: Option<ColorFilter>) {
53+
let mut config = self.common.config.dynamic_conf.screen_filter_mut();
54+
let mut updated = (*config).clone();
55+
updated.color_filter = filter;
56+
if let Err(err) = self.backend.update_screen_filter(&updated) {
57+
warn!("Failed to apply screen color filter: {}", err);
58+
} else {
59+
*config = updated;
60+
self.common.a11y_state.set_screen_filter(filter);
61+
}
62+
}
3663
}
3764

3865
delegate_a11y!(State);

src/wayland/protocols/a11y.rs

Lines changed: 102 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
use cosmic_protocols::a11y::v1::server::cosmic_a11y_manager_v1;
44
use smithay::reexports::wayland_server::{
5-
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New,
5+
Client, DataInit, Dispatch, DisplayHandle, GlobalDispatch, New, Resource,
66
};
7-
use wayland_backend::server::GlobalId;
7+
use wayland_backend::{protocol::WEnum, server::GlobalId};
88

99
pub trait A11yHandler {
1010
fn a11y_state(&mut self) -> &mut A11yState;
1111

1212
fn request_screen_magnifier(&mut self, enabled: bool);
13+
fn request_screen_invert(&mut self, inverted: bool);
14+
fn request_screen_filter(&mut self, filter: Option<ColorFilter>);
1315
}
1416

1517
#[derive(Debug)]
@@ -18,6 +20,39 @@ pub struct A11yState {
1820
instances: Vec<cosmic_a11y_manager_v1::CosmicA11yManagerV1>,
1921

2022
magnifier_state: bool,
23+
screen_inverted: bool,
24+
screen_filter: Option<ColorFilter>,
25+
}
26+
27+
struct Unknown;
28+
29+
fn protocol_to_color_filter(
30+
protocol: WEnum<cosmic_a11y_manager_v1::Filter>,
31+
) -> Result<Option<ColorFilter>, Unknown> {
32+
match protocol {
33+
WEnum::Value(cosmic_a11y_manager_v1::Filter::Disabled) => Ok(None),
34+
WEnum::Value(cosmic_a11y_manager_v1::Filter::Greyscale) => Ok(Some(ColorFilter::Greyscale)),
35+
WEnum::Value(cosmic_a11y_manager_v1::Filter::DaltonizeProtanopia) => {
36+
Ok(Some(ColorFilter::Protanopia))
37+
}
38+
WEnum::Value(cosmic_a11y_manager_v1::Filter::DaltonizeDeuteranopia) => {
39+
Ok(Some(ColorFilter::Deuteranopia))
40+
}
41+
WEnum::Value(cosmic_a11y_manager_v1::Filter::DaltonizeTritanopia) => {
42+
Ok(Some(ColorFilter::Tritanopia))
43+
}
44+
WEnum::Unknown(_) | WEnum::Value(_) => Err(Unknown),
45+
}
46+
}
47+
48+
fn color_filter_to_protocol(filter: Option<ColorFilter>) -> cosmic_a11y_manager_v1::Filter {
49+
match filter {
50+
None => cosmic_a11y_manager_v1::Filter::Disabled,
51+
Some(ColorFilter::Greyscale) => cosmic_a11y_manager_v1::Filter::Greyscale,
52+
Some(ColorFilter::Protanopia) => cosmic_a11y_manager_v1::Filter::DaltonizeProtanopia,
53+
Some(ColorFilter::Deuteranopia) => cosmic_a11y_manager_v1::Filter::DaltonizeDeuteranopia,
54+
Some(ColorFilter::Tritanopia) => cosmic_a11y_manager_v1::Filter::DaltonizeTritanopia,
55+
}
2156
}
2257

2358
impl A11yState {
@@ -27,7 +62,7 @@ impl A11yState {
2762
F: for<'a> Fn(&'a Client) -> bool + Send + Sync + 'static,
2863
{
2964
let global = dh.create_global::<D, cosmic_a11y_manager_v1::CosmicA11yManagerV1, _>(
30-
1,
65+
2,
3166
A11yGlobalData {
3267
filter: Box::new(client_filter),
3368
},
@@ -37,6 +72,8 @@ impl A11yState {
3772
instances: Vec::new(),
3873

3974
magnifier_state: false,
75+
screen_inverted: false,
76+
screen_filter: None,
4077
}
4178
}
4279

@@ -55,6 +92,31 @@ impl A11yState {
5592
});
5693
}
5794
}
95+
96+
pub fn set_screen_inverted(&mut self, enabled: bool) {
97+
self.screen_inverted = enabled;
98+
self.send_screen_filter();
99+
}
100+
101+
pub fn set_screen_filter(&mut self, state: Option<ColorFilter>) {
102+
self.screen_filter = state;
103+
self.send_screen_filter();
104+
}
105+
106+
fn send_screen_filter(&self) {
107+
for instance in &self.instances {
108+
if instance.version() >= cosmic_a11y_manager_v1::EVT_SCREEN_FILTER_SINCE {
109+
instance.screen_filter(
110+
if self.screen_inverted {
111+
cosmic_a11y_manager_v1::ActiveState::Enabled
112+
} else {
113+
cosmic_a11y_manager_v1::ActiveState::Disabled
114+
},
115+
color_filter_to_protocol(self.screen_filter),
116+
);
117+
}
118+
}
119+
}
58120
}
59121

60122
pub struct A11yGlobalData {
@@ -85,6 +147,17 @@ where
85147
cosmic_a11y_manager_v1::ActiveState::Disabled
86148
});
87149

150+
if instance.version() >= cosmic_a11y_manager_v1::EVT_SCREEN_FILTER_SINCE {
151+
instance.screen_filter(
152+
if state.screen_inverted {
153+
cosmic_a11y_manager_v1::ActiveState::Enabled
154+
} else {
155+
cosmic_a11y_manager_v1::ActiveState::Disabled
156+
},
157+
color_filter_to_protocol(state.screen_filter),
158+
);
159+
}
160+
88161
state.instances.push(instance);
89162
}
90163

@@ -108,12 +181,30 @@ where
108181
) {
109182
match request {
110183
cosmic_a11y_manager_v1::Request::SetMagnifier { active } => {
111-
state.request_screen_magnifier(
112-
active
113-
.into_result()
114-
.unwrap_or(cosmic_a11y_manager_v1::ActiveState::Disabled)
115-
== cosmic_a11y_manager_v1::ActiveState::Enabled,
116-
);
184+
let enabled = active
185+
.into_result()
186+
.unwrap_or(cosmic_a11y_manager_v1::ActiveState::Disabled)
187+
== cosmic_a11y_manager_v1::ActiveState::Enabled;
188+
if enabled != state.a11y_state().magnifier_state {
189+
state.request_screen_magnifier(enabled);
190+
}
191+
}
192+
cosmic_a11y_manager_v1::Request::SetScreenFilter { inverted, filter } => {
193+
let inverted = inverted
194+
.into_result()
195+
.unwrap_or(cosmic_a11y_manager_v1::ActiveState::Disabled)
196+
== cosmic_a11y_manager_v1::ActiveState::Enabled;
197+
let filter = protocol_to_color_filter(filter);
198+
199+
if inverted != state.a11y_state().screen_inverted {
200+
state.request_screen_invert(inverted);
201+
}
202+
203+
if let Ok(filter) = filter {
204+
if filter != state.a11y_state().screen_filter {
205+
state.request_screen_filter(filter);
206+
}
207+
}
117208
}
118209
_ => unreachable!(),
119210
}
@@ -140,3 +231,5 @@ macro_rules! delegate_a11y {
140231
};
141232
}
142233
pub(crate) use delegate_a11y;
234+
235+
use crate::config::ColorFilter;

0 commit comments

Comments
 (0)