1use accesskit::{ActionHandler, NodeId, Role, TreeUpdate};
12use accesskit_consumer::{FilterResult, Node, Tree, TreeChangeHandler, TreeState};
13use atspi_common::{InterfaceSet, Live, State};
14use std::{
15 collections::HashSet,
16 sync::{
17 atomic::{AtomicUsize, Ordering},
18 Arc, RwLock,
19 },
20};
21
22use crate::{
23 context::{ActionHandlerNoMut, ActionHandlerWrapper, AppContext, Context},
24 filters::filter,
25 node::{NodeIdOrRoot, NodeWrapper, PlatformNode, PlatformRoot},
26 util::WindowBounds,
27 AdapterCallback, Event, ObjectEvent, WindowEvent,
28};
29
30struct AdapterChangeHandler<'a> {
31 adapter: &'a Adapter,
32 added_nodes: HashSet<NodeId>,
33 removed_nodes: HashSet<NodeId>,
34 checked_text_change: HashSet<NodeId>,
35}
36
37impl<'a> AdapterChangeHandler<'a> {
38 fn new(adapter: &'a Adapter) -> Self {
39 Self {
40 adapter,
41 added_nodes: HashSet::new(),
42 removed_nodes: HashSet::new(),
43 checked_text_change: HashSet::new(),
44 }
45 }
46
47 fn add_node(&mut self, node: &Node) {
48 let id = node.id();
49 if self.added_nodes.contains(&id) {
50 return;
51 }
52 self.added_nodes.insert(id);
53
54 let role = node.role();
55 let is_root = node.is_root();
56 let node = NodeWrapper(node);
57 let interfaces = node.interfaces();
58 self.adapter.register_interfaces(node.id(), interfaces);
59 if is_root && role == Role::Window {
60 let adapter_index = self
61 .adapter
62 .context
63 .read_app_context()
64 .adapter_index(self.adapter.id)
65 .unwrap();
66 self.adapter.window_created(adapter_index, node.id());
67 }
68
69 let live = node.live();
70 if live != Live::None {
71 if let Some(name) = node.name() {
72 self.adapter
73 .emit_object_event(node.id(), ObjectEvent::Announcement(name, live));
74 }
75 }
76 }
77
78 fn add_subtree(&mut self, node: &Node) {
79 self.add_node(node);
80 for child in node.filtered_children(&filter) {
81 self.add_subtree(&child);
82 }
83 }
84
85 fn remove_node(&mut self, node: &Node) {
86 let id = node.id();
87 if self.removed_nodes.contains(&id) {
88 return;
89 }
90 self.removed_nodes.insert(id);
91
92 let role = node.role();
93 let is_root = node.is_root();
94 let node = NodeWrapper(node);
95 if is_root && role == Role::Window {
96 self.adapter.window_destroyed(node.id());
97 }
98 self.adapter
99 .emit_object_event(node.id(), ObjectEvent::StateChanged(State::Defunct, true));
100 self.adapter
101 .unregister_interfaces(node.id(), node.interfaces());
102 }
103
104 fn remove_subtree(&mut self, node: &Node) {
105 for child in node.filtered_children(&filter) {
106 self.remove_subtree(&child);
107 }
108 self.remove_node(node);
109 }
110
111 fn emit_text_change_if_needed_parent(&mut self, old_node: &Node, new_node: &Node) {
112 if !new_node.supports_text_ranges() || !old_node.supports_text_ranges() {
113 return;
114 }
115 let id = new_node.id();
116 if self.checked_text_change.contains(&id) {
117 return;
118 }
119 self.checked_text_change.insert(id);
120 let old_text = old_node.document_range().text();
121 let new_text = new_node.document_range().text();
122
123 let mut old_chars = old_text.chars();
124 let mut new_chars = new_text.chars();
125 let mut prefix_usv_count = 0;
126 let mut prefix_byte_count = 0;
127 loop {
128 match (old_chars.next(), new_chars.next()) {
129 (Some(old_char), Some(new_char)) if old_char == new_char => {
130 prefix_usv_count += 1;
131 prefix_byte_count += new_char.len_utf8();
132 }
133 (None, None) => return,
134 _ => break,
135 }
136 }
137
138 let suffix_byte_count = old_text[prefix_byte_count..]
139 .chars()
140 .rev()
141 .zip(new_text[prefix_byte_count..].chars().rev())
142 .take_while(|(old_char, new_char)| old_char == new_char)
143 .fold(0, |count, (c, _)| count + c.len_utf8());
144
145 let old_content = &old_text[prefix_byte_count..old_text.len() - suffix_byte_count];
146 if let Ok(length) = old_content.chars().count().try_into() {
147 if length > 0 {
148 self.adapter.emit_object_event(
149 id,
150 ObjectEvent::TextRemoved {
151 start_index: prefix_usv_count,
152 length,
153 content: old_content.to_string(),
154 },
155 );
156 }
157 }
158
159 let new_content = &new_text[prefix_byte_count..new_text.len() - suffix_byte_count];
160 if let Ok(length) = new_content.chars().count().try_into() {
161 if length > 0 {
162 self.adapter.emit_object_event(
163 id,
164 ObjectEvent::TextInserted {
165 start_index: prefix_usv_count,
166 length,
167 content: new_content.to_string(),
168 },
169 );
170 }
171 }
172 }
173
174 fn emit_text_change_if_needed(&mut self, old_node: &Node, new_node: &Node) {
175 if let Role::InlineTextBox | Role::GenericContainer = new_node.role() {
176 if let (Some(old_parent), Some(new_parent)) = (
177 old_node.filtered_parent(&filter),
178 new_node.filtered_parent(&filter),
179 ) {
180 self.emit_text_change_if_needed_parent(&old_parent, &new_parent);
181 }
182 } else {
183 self.emit_text_change_if_needed_parent(old_node, new_node);
184 }
185 }
186
187 fn emit_text_selection_change(&self, old_node: Option<&Node>, new_node: &Node) {
188 if !new_node.supports_text_ranges() {
189 return;
190 }
191 let Some(old_node) = old_node else {
192 if let Some(selection) = new_node.text_selection() {
193 if !selection.is_degenerate() {
194 self.adapter
195 .emit_object_event(new_node.id(), ObjectEvent::TextSelectionChanged);
196 }
197 }
198 if let Some(selection_focus) = new_node.text_selection_focus() {
199 if let Ok(offset) = selection_focus.to_global_usv_index().try_into() {
200 self.adapter
201 .emit_object_event(new_node.id(), ObjectEvent::CaretMoved(offset));
202 }
203 }
204 return;
205 };
206 if !old_node.is_focused() || new_node.raw_text_selection() == old_node.raw_text_selection()
207 {
208 return;
209 }
210
211 if let Some(selection) = new_node.text_selection() {
212 if !selection.is_degenerate()
213 || old_node
214 .text_selection()
215 .map(|selection| !selection.is_degenerate())
216 .unwrap_or(false)
217 {
218 self.adapter
219 .emit_object_event(new_node.id(), ObjectEvent::TextSelectionChanged);
220 }
221 }
222
223 let old_caret_position = old_node
224 .raw_text_selection()
225 .map(|selection| selection.focus);
226 let new_caret_position = new_node
227 .raw_text_selection()
228 .map(|selection| selection.focus);
229 if old_caret_position != new_caret_position {
230 if let Some(selection_focus) = new_node.text_selection_focus() {
231 if let Ok(offset) = selection_focus.to_global_usv_index().try_into() {
232 self.adapter
233 .emit_object_event(new_node.id(), ObjectEvent::CaretMoved(offset));
234 }
235 }
236 }
237 }
238}
239
240impl TreeChangeHandler for AdapterChangeHandler<'_> {
241 fn node_added(&mut self, node: &Node) {
242 if filter(node) == FilterResult::Include {
243 self.add_node(node);
244 }
245 }
246
247 fn node_updated(&mut self, old_node: &Node, new_node: &Node) {
248 self.emit_text_change_if_needed(old_node, new_node);
249 let filter_old = filter(old_node);
250 let filter_new = filter(new_node);
251 if filter_new != filter_old {
252 if filter_new == FilterResult::Include {
253 if filter_old == FilterResult::ExcludeSubtree {
254 self.add_subtree(new_node);
255 } else {
256 self.add_node(new_node);
257 }
258 } else if filter_old == FilterResult::Include {
259 if filter_new == FilterResult::ExcludeSubtree {
260 self.remove_subtree(old_node);
261 } else {
262 self.remove_node(old_node);
263 }
264 }
265 } else if filter_new == FilterResult::Include {
266 let old_wrapper = NodeWrapper(old_node);
267 let new_wrapper = NodeWrapper(new_node);
268 let old_interfaces = old_wrapper.interfaces();
269 let new_interfaces = new_wrapper.interfaces();
270 let kept_interfaces = old_interfaces & new_interfaces;
271 self.adapter
272 .unregister_interfaces(new_wrapper.id(), old_interfaces ^ kept_interfaces);
273 self.adapter
274 .register_interfaces(new_node.id(), new_interfaces ^ kept_interfaces);
275 let bounds = *self.adapter.context.read_root_window_bounds();
276 new_wrapper.notify_changes(&bounds, self.adapter, &old_wrapper);
277 self.emit_text_selection_change(Some(old_node), new_node);
278 }
279 }
280
281 fn focus_moved(&mut self, old_node: Option<&Node>, new_node: Option<&Node>) {
282 if let (None, Some(new_node)) = (old_node, new_node) {
283 if let Some(root_window) = root_window(new_node.tree_state) {
284 self.adapter.window_activated(&NodeWrapper(&root_window));
285 }
286 } else if let (Some(old_node), None) = (old_node, new_node) {
287 if let Some(root_window) = root_window(old_node.tree_state) {
288 self.adapter.window_deactivated(&NodeWrapper(&root_window));
289 }
290 }
291 if let Some(node) = new_node {
292 self.adapter
293 .emit_object_event(node.id(), ObjectEvent::StateChanged(State::Focused, true));
294 self.emit_text_selection_change(None, node);
295 }
296 if let Some(node) = old_node {
297 self.adapter
298 .emit_object_event(node.id(), ObjectEvent::StateChanged(State::Focused, false));
299 }
300 }
301
302 fn node_removed(&mut self, node: &Node) {
303 if filter(node) == FilterResult::Include {
304 self.remove_node(node);
305 }
306 }
307}
308
309static NEXT_ADAPTER_ID: AtomicUsize = AtomicUsize::new(0);
310
311pub fn next_adapter_id() -> usize {
314 NEXT_ADAPTER_ID.fetch_add(1, Ordering::Relaxed)
315}
316
317pub struct Adapter {
318 id: usize,
319 callback: Box<dyn AdapterCallback + Send + Sync>,
320 context: Arc<Context>,
321}
322
323impl Adapter {
324 pub fn new(
325 app_context: &Arc<RwLock<AppContext>>,
326 callback: impl 'static + AdapterCallback + Send + Sync,
327 initial_state: TreeUpdate,
328 is_window_focused: bool,
329 root_window_bounds: WindowBounds,
330 action_handler: impl 'static + ActionHandler + Send,
331 ) -> Self {
332 let id = next_adapter_id();
333 Self::with_id(
334 id,
335 app_context,
336 callback,
337 initial_state,
338 is_window_focused,
339 root_window_bounds,
340 action_handler,
341 )
342 }
343
344 pub fn with_id(
345 id: usize,
346 app_context: &Arc<RwLock<AppContext>>,
347 callback: impl 'static + AdapterCallback + Send + Sync,
348 initial_state: TreeUpdate,
349 is_window_focused: bool,
350 root_window_bounds: WindowBounds,
351 action_handler: impl 'static + ActionHandler + Send,
352 ) -> Self {
353 Self::with_wrapped_action_handler(
354 id,
355 app_context,
356 callback,
357 initial_state,
358 is_window_focused,
359 root_window_bounds,
360 Arc::new(ActionHandlerWrapper::new(action_handler)),
361 )
362 }
363
364 pub fn with_wrapped_action_handler(
367 id: usize,
368 app_context: &Arc<RwLock<AppContext>>,
369 callback: impl 'static + AdapterCallback + Send + Sync,
370 initial_state: TreeUpdate,
371 is_window_focused: bool,
372 root_window_bounds: WindowBounds,
373 action_handler: Arc<dyn ActionHandlerNoMut + Send + Sync>,
374 ) -> Self {
375 let tree = Tree::new(initial_state, is_window_focused);
376 let focus_id = tree.state().focus_id();
377 let context = Context::new(app_context, tree, action_handler, root_window_bounds);
378 context.write_app_context().push_adapter(id, &context);
379 let adapter = Self {
380 id,
381 callback: Box::new(callback),
382 context,
383 };
384 adapter.register_tree();
385 if let Some(id) = focus_id {
386 adapter.emit_object_event(id, ObjectEvent::StateChanged(State::Focused, true));
387 }
388 adapter
389 }
390
391 fn register_tree(&self) {
392 fn add_children(node: Node<'_>, to_add: &mut Vec<(NodeId, InterfaceSet)>) {
393 for child in node.filtered_children(&filter) {
394 let child_id = child.id();
395 let wrapper = NodeWrapper(&child);
396 let interfaces = wrapper.interfaces();
397 to_add.push((child_id, interfaces));
398 add_children(child, to_add);
399 }
400 }
401
402 let mut objects_to_add = Vec::new();
403
404 let (adapter_index, root_id) = {
405 let tree = self.context.read_tree();
406 let tree_state = tree.state();
407 let mut app_context = self.context.write_app_context();
408 app_context.name = tree_state.app_name();
409 app_context.toolkit_name = tree_state.toolkit_name();
410 app_context.toolkit_version = tree_state.toolkit_version();
411 let adapter_index = app_context.adapter_index(self.id).unwrap();
412 let root = tree_state.root();
413 let root_id = root.id();
414 let wrapper = NodeWrapper(&root);
415 objects_to_add.push((root_id, wrapper.interfaces()));
416 add_children(root, &mut objects_to_add);
417 (adapter_index, root_id)
418 };
419
420 for (id, interfaces) in objects_to_add {
421 self.register_interfaces(id, interfaces);
422 if id == root_id {
423 self.window_created(adapter_index, id);
424 }
425 }
426 }
427
428 pub fn platform_node(&self, id: NodeId) -> PlatformNode {
429 PlatformNode::new(&self.context, self.id, id)
430 }
431
432 pub fn root_id(&self) -> NodeId {
433 self.context.read_tree().state().root_id()
434 }
435
436 pub fn platform_root(&self) -> PlatformRoot {
437 PlatformRoot::new(&self.context.app_context)
438 }
439
440 fn register_interfaces(&self, id: NodeId, new_interfaces: InterfaceSet) {
441 self.callback.register_interfaces(self, id, new_interfaces);
442 }
443
444 fn unregister_interfaces(&self, id: NodeId, old_interfaces: InterfaceSet) {
445 self.callback
446 .unregister_interfaces(self, id, old_interfaces);
447 }
448
449 pub(crate) fn emit_object_event(&self, target: NodeId, event: ObjectEvent) {
450 let target = NodeIdOrRoot::Node(target);
451 self.callback
452 .emit_event(self, Event::Object { target, event });
453 }
454
455 fn emit_root_object_event(&self, event: ObjectEvent) {
456 let target = NodeIdOrRoot::Root;
457 self.callback
458 .emit_event(self, Event::Object { target, event });
459 }
460
461 pub fn set_root_window_bounds(&mut self, new_bounds: WindowBounds) {
462 let mut bounds = self.context.root_window_bounds.write().unwrap();
463 *bounds = new_bounds;
464 }
465
466 pub fn update(&mut self, update: TreeUpdate) {
467 let mut handler = AdapterChangeHandler::new(self);
468 let mut tree = self.context.tree.write().unwrap();
469 tree.update_and_process_changes(update, &mut handler);
470 }
471
472 pub fn update_window_focus_state(&mut self, is_focused: bool) {
473 let mut handler = AdapterChangeHandler::new(self);
474 let mut tree = self.context.tree.write().unwrap();
475 tree.update_host_focus_state_and_process_changes(is_focused, &mut handler);
476 }
477
478 fn window_created(&self, adapter_index: usize, window: NodeId) {
479 self.emit_root_object_event(ObjectEvent::ChildAdded(adapter_index, window));
480 }
481
482 fn window_activated(&self, window: &NodeWrapper<'_>) {
483 self.callback.emit_event(
484 self,
485 Event::Window {
486 target: window.id(),
487 name: window.name().unwrap_or_default(),
488 event: WindowEvent::Activated,
489 },
490 );
491 self.emit_object_event(window.id(), ObjectEvent::StateChanged(State::Active, true));
492 self.emit_root_object_event(ObjectEvent::ActiveDescendantChanged(window.id()));
493 }
494
495 fn window_deactivated(&self, window: &NodeWrapper<'_>) {
496 self.callback.emit_event(
497 self,
498 Event::Window {
499 target: window.id(),
500 name: window.name().unwrap_or_default(),
501 event: WindowEvent::Deactivated,
502 },
503 );
504 self.emit_object_event(window.id(), ObjectEvent::StateChanged(State::Active, false));
505 }
506
507 fn window_destroyed(&self, window: NodeId) {
508 self.emit_root_object_event(ObjectEvent::ChildRemoved(window));
509 }
510
511 pub fn id(&self) -> usize {
512 self.id
513 }
514
515 pub fn is_window_focused(&self) -> bool {
516 self.context.read_tree().state().is_host_focused()
517 }
518
519 pub fn root_window_bounds(&self) -> WindowBounds {
520 *self.context.read_root_window_bounds()
521 }
522
523 pub fn wrapped_action_handler(&self) -> Arc<dyn ActionHandlerNoMut + Send + Sync> {
526 Arc::clone(&self.context.action_handler)
527 }
528}
529
530fn root_window(current_state: &TreeState) -> Option<Node> {
531 const WINDOW_ROLES: &[Role] = &[Role::AlertDialog, Role::Dialog, Role::Window];
532 let root = current_state.root();
533 if WINDOW_ROLES.contains(&root.role()) {
534 Some(root)
535 } else {
536 None
537 }
538}
539
540impl Drop for Adapter {
541 fn drop(&mut self) {
542 let root_id = self.context.read_tree().state().root_id();
543 self.window_destroyed(root_id);
544 self.context.write_app_context().remove_adapter(self.id);
548 }
549}