Skip to content

Commit e1f348e

Browse files
mwcampbellemilk
andauthored
Implement accessibility APIs via AccessKit (#2294)
* squash before rebase * Update AccessKit, introducing support for editable spinners on Windows and an important fix for navigation order on macOS * Restore support for increment and decrement actions in DragValue * Avoid VoiceOver race condition bug * fix clippy lint * Tell AccessKit that the default action for a text edit (equivalent to a click) is to set the focus. This matters to some platform adapters. * Refactor InputState functions for AccessKit actions * Support the AccessKit SetValue for DragValue; this is the only way for a Windows AT to programmatically adjust the value * Same for Slider * Properly associate the slider label with both the slider and the drag value * Lazily activate egui's AccessKit support * fix clippy lint * Update AccessKit * More documentation, particularly around lazy activation * Tweak one of the doc comments * See if I can get AccessKit exempted from the 'missing backticks' lint * Make PlatformOutput::accesskit_update an Option * Refactor lazy activation * Refactor node mutation (again) * Eliminate the need for an explicit is_accesskit_active method, at least for now * Fix doc comment * More refactoring of tree construction; don't depend on Arc::get_mut * Override a clippy lint; I seem to have no other choice * Final planned refactor: a more flexible approach to hierarchy * Last AccessKit update for this PR; includes an important macOS DPI fix * Move and document the optional accesskit dependency * Fix comment typo Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * reformat * More elegant code for conditionally creating a node Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * Set step to 1.0 for all integer sliders * Add doc example for Response::labelled_by * Clarify a TODO comment I left for myself Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
1 parent 48666e1 commit e1f348e

28 files changed

+1051
-99
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ NOTE: [`epaint`](crates/epaint/CHANGELOG.md), [`eframe`](crates/eframe/CHANGELOG
2424
* Added `Area::constrain` and `Window::constrain` which constrains area to the screen bounds. ([#2270](https://github.com/emilk/egui/pull/2270)).
2525
* Added `Area::pivot` and `Window::pivot` which controls what part of the window to position. ([#2303](https://github.com/emilk/egui/pull/2303)).
2626
* Added support for [thin space](https://en.wikipedia.org/wiki/Thin_space).
27+
* Added optional integration with [AccessKit](https://accesskit.dev/) for implementing platform accessibility APIs. ([#2294](https://github.com/emilk/egui/pull/2294)).
2728

2829
### Changed 🔧
2930
* Panels always have a separator line, but no stroke on other sides. Their spacing has also changed slightly ([#2261](https://github.com/emilk/egui/pull/2261)).

Cargo.lock

+190-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clippy.toml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
doc-valid-idents = ["AccessKit", ".."]

crates/eframe/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C
1818
* Web: Add `WebInfo::user_agent` ([#2202](https://github.com/emilk/egui/pull/2202)).
1919
* Wgpu device/adapter/surface creation has now various configuration options exposed via `NativeOptions/WebOptions::wgpu_options` ([#2207](https://github.com/emilk/egui/pull/2207)).
2020
* Fix: Make sure that `native_pixels_per_point` is updated ([#2256](https://github.com/emilk/egui/pull/2256)).
21+
* Added optional, but enabled by default, integration with [AccessKit](https://accesskit.dev/) for implementing platform accessibility APIs. ([#2294](https://github.com/emilk/egui/pull/2294)).
2122

2223

2324
## 0.19.0 - 2022-08-20

crates/eframe/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ all-features = true
2020

2121

2222
[features]
23-
default = ["default_fonts", "glow"]
23+
default = ["accesskit", "default_fonts", "glow"]
24+
25+
## Enable platform accessibility API implementations through [AccessKit](https://accesskit.dev/).
26+
accesskit = ["egui/accesskit", "egui-winit/accesskit"]
2427

2528
## Detect dark mode system preference using [`dark-light`](https://docs.rs/dark-light).
2629
##

crates/eframe/src/native/epi_integration.rs

+28
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ use winit::event_loop::EventLoopWindowTarget;
33
#[cfg(target_os = "macos")]
44
use winit::platform::macos::WindowBuilderExtMacOS as _;
55

6+
#[cfg(feature = "accesskit")]
7+
use egui::accesskit;
8+
#[cfg(feature = "accesskit")]
9+
use egui_winit::accesskit_winit;
610
use egui_winit::{native_pixels_per_point, EventResponse, WindowSettings};
711

812
use crate::{epi, Theme, WindowInfo};
@@ -262,6 +266,25 @@ impl EpiIntegration {
262266
}
263267
}
264268

269+
#[cfg(feature = "accesskit")]
270+
pub fn init_accesskit<E: From<accesskit_winit::ActionRequestEvent> + Send>(
271+
&mut self,
272+
window: &winit::window::Window,
273+
event_loop_proxy: winit::event_loop::EventLoopProxy<E>,
274+
) {
275+
let egui_ctx = self.egui_ctx.clone();
276+
self.egui_winit
277+
.init_accesskit(window, event_loop_proxy, move || {
278+
// This function is called when an accessibility client
279+
// (e.g. screen reader) makes its first request. If we got here,
280+
// we know that an accessibility tree is actually wanted.
281+
egui_ctx.enable_accesskit();
282+
// Enqueue a repaint so we'll receive a full tree update soon.
283+
egui_ctx.request_repaint();
284+
egui::accesskit_placeholder_tree_update()
285+
});
286+
}
287+
265288
pub fn warm_up(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) {
266289
crate::profile_function!();
267290
let saved_memory: egui::Memory = self.egui_ctx.memory().clone();
@@ -301,6 +324,11 @@ impl EpiIntegration {
301324
self.egui_winit.on_event(&self.egui_ctx, event)
302325
}
303326

327+
#[cfg(feature = "accesskit")]
328+
pub fn on_accesskit_action_request(&mut self, request: accesskit::ActionRequest) {
329+
self.egui_winit.on_accesskit_action_request(request);
330+
}
331+
304332
pub fn update(
305333
&mut self,
306334
app: &mut dyn epi::App,

0 commit comments

Comments
 (0)