Refactor lazy activation

This commit is contained in:
Matt Campbell 2022-11-30 08:09:41 -06:00
parent 3109ee9825
commit 18ccf1fd10
4 changed files with 27 additions and 30 deletions

View file

@ -272,8 +272,17 @@ impl EpiIntegration {
window: &winit::window::Window, window: &winit::window::Window,
event_loop_proxy: winit::event_loop::EventLoopProxy<E>, event_loop_proxy: winit::event_loop::EventLoopProxy<E>,
) { ) {
let egui_ctx = self.egui_ctx.clone();
self.egui_winit self.egui_winit
.init_accesskit(window, event_loop_proxy, self.egui_ctx.clone()); .init_accesskit(window, event_loop_proxy, move || {
// This function is called when an accessibility client
// (e.g. screen reader) makes its first request. If we got here,
// we know that an accessibility tree is actually wanted.
egui_ctx.enable_accesskit();
// Enqueue a repaint so we'll receive a full tree update soon.
egui_ctx.request_repaint();
egui::accesskit_placeholder_tree_update()
});
} }
pub fn warm_up(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) { pub fn warm_up(&mut self, app: &mut dyn epi::App, window: &winit::window::Window) {

View file

@ -132,21 +132,11 @@ impl State {
&mut self, &mut self,
window: &winit::window::Window, window: &winit::window::Window,
event_loop_proxy: winit::event_loop::EventLoopProxy<T>, event_loop_proxy: winit::event_loop::EventLoopProxy<T>,
egui_ctx: egui::Context, initial_tree_update_factory: impl 'static + FnOnce() -> accesskit::TreeUpdate + Send,
) { ) {
self.accesskit = Some(accesskit_winit::Adapter::new( self.accesskit = Some(accesskit_winit::Adapter::new(
window, window,
move || { initial_tree_update_factory,
// This function is called when an accessibility client
// (e.g. screen reader) makes its first request. If we got here,
// we know that an accessibility tree is actually wanted.
// Tell egui that AccessKit is active, and return a placeholder
// tree for now. `egui::Context::accesskit_activated`
// will request a repaint, and that will provide the first
// real accessibility tree.
egui_ctx.accesskit_activated();
egui::accesskit_placeholder_tree_update()
},
event_loop_proxy, event_loop_proxy,
)); ));
} }

View file

@ -69,7 +69,7 @@ struct ContextImpl {
layer_rects_prev_frame: ahash::HashMap<LayerId, Vec<(Id, Rect)>>, layer_rects_prev_frame: ahash::HashMap<LayerId, Vec<(Id, Rect)>>,
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
was_accesskit_activated: bool, is_accesskit_enabled: bool,
} }
impl ContextImpl { impl ContextImpl {
@ -110,7 +110,7 @@ impl ContextImpl {
); );
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
if self.was_accesskit_activated { if self.is_accesskit_enabled {
assert!(self.output.accesskit_update.is_none()); assert!(self.output.accesskit_update.is_none());
let id = crate::accesskit_root_id(); let id = crate::accesskit_root_id();
let accesskit_id = id.accesskit_id(); let accesskit_id = id.accesskit_id();
@ -1607,20 +1607,18 @@ impl Context {
self.output().accesskit_update.is_some() self.output().accesskit_update.is_some()
} }
/// Indicates that AccessKit has been activated and egui should generate /// Enable generation of AccessKit tree updates in all future frames.
/// AccessKit tree updates for all subsequent frames. Also requests a repaint ///
/// so a full AccessKit tree will be available as soon as the repaint /// If it's practical for the egui integration to immediately run the egui
/// is done. As soon as the egui integration knows that accessibility support /// application when it is either initializing the AccessKit adapter or
/// is desired, it must call this method and provide a placeholder tree /// being called by the AccessKit adapter to provide the initial tree update,
/// to AccessKit through the [`crate::accesskit_placeholder_tree_update`] method. /// then it should do so, to provide a complete AccessKit tree to the adapter
/// immediately. Otherwise, it should enqueue a repaint and use the
/// placeholder tree update from [`crate::accesskit_placeholder_tree_update`]
/// in the meantime.
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
pub fn accesskit_activated(&self) { pub fn enable_accesskit(&self) {
let mut ctx = self.write(); self.write().is_accesskit_enabled = true;
if !ctx.was_accesskit_activated {
ctx.was_accesskit_activated = true;
drop(ctx);
self.request_repaint();
}
} }
} }

View file

@ -559,8 +559,8 @@ pub fn accesskit_root_id() -> Id {
} }
/// Return a tree update that the egui integration should provide to the /// Return a tree update that the egui integration should provide to the
/// AccessKit adapter before a real tree update is available. See also /// AccessKit adapter if it cannot immediately run the egui application
/// [`crate::Context::accesskit_activated`]. /// to get a full tree update after running [`Context::enable_accesskit`].
#[cfg(feature = "accesskit")] #[cfg(feature = "accesskit")]
pub fn accesskit_placeholder_tree_update() -> accesskit::TreeUpdate { pub fn accesskit_placeholder_tree_update() -> accesskit::TreeUpdate {
use accesskit::{Node, Role, Tree, TreeUpdate}; use accesskit::{Node, Role, Tree, TreeUpdate};