mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
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>
This commit is contained in:
@@ -4,6 +4,8 @@
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
use egui_winit::accesskit_winit;
|
||||
use egui_winit::winit;
|
||||
use winit::event_loop::{
|
||||
ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget,
|
||||
@@ -15,6 +17,15 @@ use crate::epi;
|
||||
#[derive(Debug)]
|
||||
pub enum UserEvent {
|
||||
RequestRepaint,
|
||||
#[cfg(feature = "accesskit")]
|
||||
AccessKitActionRequest(accesskit_winit::ActionRequestEvent),
|
||||
}
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
impl From<accesskit_winit::ActionRequestEvent> for UserEvent {
|
||||
fn from(inner: accesskit_winit::ActionRequestEvent) -> Self {
|
||||
Self::AccessKitActionRequest(inner)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -353,7 +364,9 @@ mod glow_integration {
|
||||
|
||||
let window_builder = epi_integration::window_builder(native_options, &window_settings)
|
||||
.with_title(title)
|
||||
.with_visible(false); // Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
// Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
// We must also keep the window hidden until AccessKit is initialized.
|
||||
.with_visible(false);
|
||||
|
||||
let gl_window = unsafe {
|
||||
glutin::ContextBuilder::new()
|
||||
@@ -400,6 +413,10 @@ mod glow_integration {
|
||||
#[cfg(feature = "wgpu")]
|
||||
None,
|
||||
);
|
||||
#[cfg(feature = "accesskit")]
|
||||
{
|
||||
integration.init_accesskit(gl_window.window(), self.repaint_proxy.lock().clone());
|
||||
}
|
||||
let theme = system_theme.unwrap_or(self.native_options.default_theme);
|
||||
integration.egui_ctx.set_visuals(theme.egui_visuals());
|
||||
|
||||
@@ -671,6 +688,21 @@ mod glow_integration {
|
||||
EventResult::Wait
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "accesskit")]
|
||||
winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest(
|
||||
accesskit_winit::ActionRequestEvent { request, .. },
|
||||
)) => {
|
||||
if let Some(running) = &mut self.running {
|
||||
running
|
||||
.integration
|
||||
.on_accesskit_action_request(request.clone());
|
||||
// As a form of user input, accessibility actions should
|
||||
// lead to a repaint.
|
||||
EventResult::RepaintNext
|
||||
} else {
|
||||
EventResult::Wait
|
||||
}
|
||||
}
|
||||
_ => EventResult::Wait,
|
||||
}
|
||||
}
|
||||
@@ -769,7 +801,9 @@ mod wgpu_integration {
|
||||
let window_settings = epi_integration::load_window_settings(storage);
|
||||
epi_integration::window_builder(native_options, &window_settings)
|
||||
.with_title(title)
|
||||
.with_visible(false) // Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
// Keep hidden until we've painted something. See https://github.com/emilk/egui/pull/2279
|
||||
// We must also keep the window hidden until AccessKit is initialized.
|
||||
.with_visible(false)
|
||||
.build(event_loop)
|
||||
.unwrap()
|
||||
}
|
||||
@@ -825,6 +859,10 @@ mod wgpu_integration {
|
||||
None,
|
||||
wgpu_render_state.clone(),
|
||||
);
|
||||
#[cfg(feature = "accesskit")]
|
||||
{
|
||||
integration.init_accesskit(&window, self.repaint_proxy.lock().unwrap().clone());
|
||||
}
|
||||
let theme = system_theme.unwrap_or(self.native_options.default_theme);
|
||||
integration.egui_ctx.set_visuals(theme.egui_visuals());
|
||||
|
||||
@@ -1068,6 +1106,21 @@ mod wgpu_integration {
|
||||
EventResult::Wait
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "accesskit")]
|
||||
winit::event::Event::UserEvent(UserEvent::AccessKitActionRequest(
|
||||
accesskit_winit::ActionRequestEvent { request, .. },
|
||||
)) => {
|
||||
if let Some(running) = &mut self.running {
|
||||
running
|
||||
.integration
|
||||
.on_accesskit_action_request(request.clone());
|
||||
// As a form of user input, accessibility actions should
|
||||
// lead to a repaint.
|
||||
EventResult::RepaintNext
|
||||
} else {
|
||||
EventResult::Wait
|
||||
}
|
||||
}
|
||||
_ => EventResult::Wait,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user