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:
@@ -11,7 +11,11 @@
|
||||
|
||||
use std::os::raw::c_void;
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
pub use accesskit_winit;
|
||||
pub use egui;
|
||||
#[cfg(feature = "accesskit")]
|
||||
use egui::accesskit;
|
||||
pub use winit;
|
||||
|
||||
pub mod clipboard;
|
||||
@@ -86,6 +90,9 @@ pub struct State {
|
||||
|
||||
/// track ime state
|
||||
input_method_editor_started: bool,
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
accesskit: Option<accesskit_winit::Adapter>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
@@ -114,9 +121,26 @@ impl State {
|
||||
pointer_touch_id: None,
|
||||
|
||||
input_method_editor_started: false,
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
accesskit: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
pub fn init_accesskit<T: From<accesskit_winit::ActionRequestEvent> + Send>(
|
||||
&mut self,
|
||||
window: &winit::window::Window,
|
||||
event_loop_proxy: winit::event_loop::EventLoopProxy<T>,
|
||||
initial_tree_update_factory: impl 'static + FnOnce() -> accesskit::TreeUpdate + Send,
|
||||
) {
|
||||
self.accesskit = Some(accesskit_winit::Adapter::new(
|
||||
window,
|
||||
initial_tree_update_factory,
|
||||
event_loop_proxy,
|
||||
));
|
||||
}
|
||||
|
||||
/// Call this once a graphics context has been created to update the maximum texture dimensions
|
||||
/// that egui will use.
|
||||
pub fn set_max_texture_side(&mut self, max_texture_side: usize) {
|
||||
@@ -374,6 +398,16 @@ impl State {
|
||||
}
|
||||
}
|
||||
|
||||
/// Call this when there is a new [`accesskit::ActionRequest`].
|
||||
///
|
||||
/// The result can be found in [`Self::egui_input`] and be extracted with [`Self::take_egui_input`].
|
||||
#[cfg(feature = "accesskit")]
|
||||
pub fn on_accesskit_action_request(&mut self, request: accesskit::ActionRequest) {
|
||||
self.egui_input
|
||||
.events
|
||||
.push(egui::Event::AccessKitActionRequest(request));
|
||||
}
|
||||
|
||||
fn on_mouse_button_input(
|
||||
&mut self,
|
||||
state: winit::event::ElementState,
|
||||
@@ -592,6 +626,8 @@ impl State {
|
||||
events: _, // handled above
|
||||
mutable_text_under_cursor: _, // only used in eframe web
|
||||
text_cursor_pos,
|
||||
#[cfg(feature = "accesskit")]
|
||||
accesskit_update,
|
||||
} = platform_output;
|
||||
self.current_pixels_per_point = egui_ctx.pixels_per_point(); // someone can have changed it to scale the UI
|
||||
|
||||
@@ -608,6 +644,13 @@ impl State {
|
||||
if let Some(egui::Pos2 { x, y }) = text_cursor_pos {
|
||||
window.set_ime_position(winit::dpi::LogicalPosition { x, y });
|
||||
}
|
||||
|
||||
#[cfg(feature = "accesskit")]
|
||||
if let Some(accesskit) = self.accesskit.as_ref() {
|
||||
if let Some(update) = accesskit_update {
|
||||
accesskit.update_if_active(|| update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_cursor_icon(&mut self, window: &winit::window::Window, cursor_icon: egui::CursorIcon) {
|
||||
|
||||
Reference in New Issue
Block a user