1// Copyright 2022 The AccessKit Authors. All rights reserved.
2// Licensed under the Apache License, Version 2.0 (found in
3// the LICENSE-APACHE file) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6use accesskit::{ActionHandler, NodeId, Role, TreeUpdate};
7use accesskit_consumer::{DetachedNode, FilterResult, Node, Tree, TreeChangeHandler, TreeState};
8use atspi_common::{InterfaceSet, Live, State};
9use std::sync::{
10 atomic::{AtomicUsize, Ordering},
11 Arc, RwLock,
12};
13
14use crate::{
15 context::{AppContext, Context},
16 filters::{filter, filter_detached},
17 node::{NodeIdOrRoot, NodeWrapper, PlatformNode, PlatformRoot},
18 util::WindowBounds,
19 AdapterCallback, Event, ObjectEvent, WindowEvent,
20};
21
22struct AdapterChangeHandler<'a> {
23 adapter: &'a Adapter,
24}
25
26impl AdapterChangeHandler<'_> {
27 fn add_node(&mut self, node: &Node) {
28 let role = node.role();
29 let is_root = node.is_root();
30 let node = NodeWrapper::Node(node);
31 let interfaces = node.interfaces();
32 self.adapter.register_interfaces(node.id(), interfaces);
33 if is_root && role == Role::Window {
34 let adapter_index = self
35 .adapter
36 .context
37 .read_app_context()
38 .adapter_index(self.adapter.id)
39 .unwrap();
40 self.adapter.window_created(adapter_index, node.id());
41 }
42
43 let live = node.live();
44 if live != Live::None {
45 if let Some(name) = node.name() {
46 self.adapter
47 .emit_object_event(node.id(), ObjectEvent::Announcement(name, live));
48 }
49 }
50 }
51
52 fn remove_node(&mut self, node: &DetachedNode) {
53 let role = node.role();
54 let is_root = node.is_root();
55 let node = NodeWrapper::DetachedNode(node);
56 if is_root && role == Role::Window {
57 self.adapter.window_destroyed(node.id());
58 }
59 self.adapter
60 .emit_object_event(node.id(), ObjectEvent::StateChanged(State::Defunct, true));
61 self.adapter
62 .unregister_interfaces(node.id(), node.interfaces());
63 }
64}
65
66impl TreeChangeHandler for AdapterChangeHandler<'_> {
67 fn node_added(&mut self, node: &Node) {
68 if filter(node) == FilterResult::Include {
69 self.add_node(node);
70 }
71 }
72
73 fn node_updated(&mut self, old_node: &DetachedNode, new_node: &Node) {
74 let filter_old = filter_detached(old_node);
75 let filter_new = filter(new_node);
76 if filter_new != filter_old {
77 if filter_new == FilterResult::Include {
78 self.add_node(new_node);
79 } else if filter_old == FilterResult::Include {
80 self.remove_node(old_node);
81 }
82 } else if filter_new == FilterResult::Include {
83 let old_wrapper = NodeWrapper::DetachedNode(old_node);
84 let new_wrapper = NodeWrapper::Node(new_node);
85 let old_interfaces = old_wrapper.interfaces();
86 let new_interfaces = new_wrapper.interfaces();
87 let kept_interfaces = old_interfaces & new_interfaces;
88 self.adapter
89 .unregister_interfaces(new_wrapper.id(), old_interfaces ^ kept_interfaces);
90 self.adapter
91 .register_interfaces(new_node.id(), new_interfaces ^ kept_interfaces);
92 let bounds = *self.adapter.context.read_root_window_bounds();
93 new_wrapper.notify_changes(&bounds, self.adapter, &old_wrapper);
94 }
95 }
96
97 fn focus_moved(
98 &mut self,
99 old_node: Option<&DetachedNode>,
100 new_node: Option<&Node>,
101 current_state: &TreeState,
102 ) {
103 if let Some(root_window) = root_window(current_state) {
104 if old_node.is_none() && new_node.is_some() {
105 self.adapter
106 .window_activated(&NodeWrapper::Node(&root_window));
107 } else if old_node.is_some() && new_node.is_none() {
108 self.adapter
109 .window_deactivated(&NodeWrapper::Node(&root_window));
110 }
111 }
112 }
113
114 fn node_removed(&mut self, node: &DetachedNode, _: &TreeState) {
115 if filter_detached(node) == FilterResult::Include {
116 self.remove_node(node);
117 }
118 }
119}
120
121static NEXT_ADAPTER_ID: AtomicUsize = AtomicUsize::new(0);
122
123pub struct AdapterIdToken(usize);
124
125impl AdapterIdToken {
126 pub fn next() -> Self {
127 let id: usize = NEXT_ADAPTER_ID.fetch_add(val:1, order:Ordering::Relaxed);
128 Self(id)
129 }
130
131 pub fn id(&self) -> usize {
132 self.0
133 }
134}
135
136pub struct Adapter {
137 id: usize,
138 callback: Box<dyn AdapterCallback + Send + Sync>,
139 context: Arc<Context>,
140}
141
142impl Adapter {
143 pub fn new(
144 app_context: &Arc<RwLock<AppContext>>,
145 callback: Box<dyn AdapterCallback + Send + Sync>,
146 initial_state: TreeUpdate,
147 is_window_focused: bool,
148 root_window_bounds: WindowBounds,
149 action_handler: Box<dyn ActionHandler + Send>,
150 ) -> Self {
151 let id_token = AdapterIdToken::next();
152 Self::with_id(
153 id_token,
154 app_context,
155 callback,
156 initial_state,
157 is_window_focused,
158 root_window_bounds,
159 action_handler,
160 )
161 }
162
163 pub fn with_id(
164 id_token: AdapterIdToken,
165 app_context: &Arc<RwLock<AppContext>>,
166 callback: Box<dyn AdapterCallback + Send + Sync>,
167 initial_state: TreeUpdate,
168 is_window_focused: bool,
169 root_window_bounds: WindowBounds,
170 action_handler: Box<dyn ActionHandler + Send>,
171 ) -> Self {
172 let id = id_token.0;
173 let tree = Tree::new(initial_state, is_window_focused);
174 let context = Context::new(app_context, tree, action_handler, root_window_bounds);
175 context.write_app_context().push_adapter(id, &context);
176 let adapter = Self {
177 id,
178 callback,
179 context,
180 };
181 adapter.register_tree();
182 adapter
183 }
184
185 fn register_tree(&self) {
186 fn add_children(node: Node<'_>, to_add: &mut Vec<(NodeId, InterfaceSet)>) {
187 for child in node.filtered_children(&filter) {
188 let child_id = child.id();
189 let wrapper = NodeWrapper::Node(&child);
190 let interfaces = wrapper.interfaces();
191 to_add.push((child_id, interfaces));
192 add_children(child, to_add);
193 }
194 }
195
196 let mut objects_to_add = Vec::new();
197
198 let (adapter_index, root_id) = {
199 let tree = self.context.read_tree();
200 let tree_state = tree.state();
201 let mut app_context = self.context.write_app_context();
202 app_context.name = tree_state.app_name();
203 app_context.toolkit_name = tree_state.toolkit_name();
204 app_context.toolkit_version = tree_state.toolkit_version();
205 let adapter_index = app_context.adapter_index(self.id).unwrap();
206 let root = tree_state.root();
207 let root_id = root.id();
208 let wrapper = NodeWrapper::Node(&root);
209 objects_to_add.push((root_id, wrapper.interfaces()));
210 add_children(root, &mut objects_to_add);
211 (adapter_index, root_id)
212 };
213
214 for (id, interfaces) in objects_to_add {
215 self.register_interfaces(id, interfaces);
216 if id == root_id {
217 self.window_created(adapter_index, id);
218 }
219 }
220 }
221
222 pub fn platform_node(&self, id: NodeId) -> PlatformNode {
223 PlatformNode::new(&self.context, self.id, id)
224 }
225
226 pub fn root_id(&self) -> NodeId {
227 self.context.read_tree().state().root_id()
228 }
229
230 pub fn platform_root(&self) -> PlatformRoot {
231 PlatformRoot::new(&self.context.app_context)
232 }
233
234 fn register_interfaces(&self, id: NodeId, new_interfaces: InterfaceSet) {
235 self.callback.register_interfaces(self, id, new_interfaces);
236 }
237
238 fn unregister_interfaces(&self, id: NodeId, old_interfaces: InterfaceSet) {
239 self.callback
240 .unregister_interfaces(self, id, old_interfaces);
241 }
242
243 pub(crate) fn emit_object_event(&self, target: NodeId, event: ObjectEvent) {
244 let target = NodeIdOrRoot::Node(target);
245 self.callback
246 .emit_event(self, Event::Object { target, event });
247 }
248
249 fn emit_root_object_event(&self, event: ObjectEvent) {
250 let target = NodeIdOrRoot::Root;
251 self.callback
252 .emit_event(self, Event::Object { target, event });
253 }
254
255 pub fn set_root_window_bounds(&self, new_bounds: WindowBounds) {
256 let mut bounds = self.context.root_window_bounds.write().unwrap();
257 *bounds = new_bounds;
258 }
259
260 pub fn update(&self, update: TreeUpdate) {
261 let mut handler = AdapterChangeHandler { adapter: self };
262 let mut tree = self.context.tree.write().unwrap();
263 tree.update_and_process_changes(update, &mut handler);
264 }
265
266 pub fn update_window_focus_state(&self, is_focused: bool) {
267 let mut handler = AdapterChangeHandler { adapter: self };
268 let mut tree = self.context.tree.write().unwrap();
269 tree.update_host_focus_state_and_process_changes(is_focused, &mut handler);
270 }
271
272 fn window_created(&self, adapter_index: usize, window: NodeId) {
273 self.emit_root_object_event(ObjectEvent::ChildAdded(adapter_index, window));
274 }
275
276 fn window_activated(&self, window: &NodeWrapper<'_>) {
277 self.callback.emit_event(
278 self,
279 Event::Window {
280 target: window.id(),
281 name: window.name().unwrap_or_default(),
282 event: WindowEvent::Activated,
283 },
284 );
285 self.emit_object_event(window.id(), ObjectEvent::StateChanged(State::Active, true));
286 self.emit_root_object_event(ObjectEvent::ActiveDescendantChanged(window.id()));
287 }
288
289 fn window_deactivated(&self, window: &NodeWrapper<'_>) {
290 self.callback.emit_event(
291 self,
292 Event::Window {
293 target: window.id(),
294 name: window.name().unwrap_or_default(),
295 event: WindowEvent::Deactivated,
296 },
297 );
298 self.emit_object_event(window.id(), ObjectEvent::StateChanged(State::Active, false));
299 }
300
301 fn window_destroyed(&self, window: NodeId) {
302 self.emit_root_object_event(ObjectEvent::ChildRemoved(window));
303 }
304
305 pub fn id(&self) -> usize {
306 self.id
307 }
308}
309
310fn root_window(current_state: &TreeState) -> Option<Node> {
311 const WINDOW_ROLES: &[Role] = &[Role::AlertDialog, Role::Dialog, Role::Window];
312 let root: Node<'_> = current_state.root();
313 if WINDOW_ROLES.contains(&root.role()) {
314 Some(root)
315 } else {
316 None
317 }
318}
319
320impl Drop for Adapter {
321 fn drop(&mut self) {
322 let root_id: NodeId = self.context.read_tree().state().root_id();
323 self.window_destroyed(window:root_id);
324 // Note: We deliberately do the following here, not in a Drop
325 // implementation on context, because AppContext owns a second
326 // strong reference to Context, and we need that to be released.
327 self.context.write_app_context().remove_adapter(self.id);
328 }
329}
330