1#[cfg(all(
15 feature = "accesskit_unix",
16 any(
17 target_os = "linux",
18 target_os = "dragonfly",
19 target_os = "freebsd",
20 target_os = "netbsd",
21 target_os = "openbsd"
22 ),
23 not(feature = "async-io"),
24 not(feature = "tokio")
25))]
26compile_error!("Either \"async-io\" (default) or \"tokio\" feature must be enabled.");
27
28#[cfg(all(
29 feature = "accesskit_unix",
30 any(
31 target_os = "linux",
32 target_os = "dragonfly",
33 target_os = "freebsd",
34 target_os = "netbsd",
35 target_os = "openbsd"
36 ),
37 feature = "async-io",
38 feature = "tokio"
39))]
40compile_error!(
41 "Both \"async-io\" (default) and \"tokio\" features cannot be enabled at the same time."
42);
43
44#[cfg(all(not(feature = "rwh_05"), not(feature = "rwh_06")))]
45compile_error!("Either \"rwh_06\" (default) or \"rwh_05\" feature must be enabled.");
46
47#[cfg(all(feature = "rwh_05", feature = "rwh_06"))]
48compile_error!(
49 "Both \"rwh_06\" (default) and \"rwh_05\" features cannot be enabled at the same time."
50);
51
52use accesskit::{ActionHandler, ActionRequest, ActivationHandler, DeactivationHandler, TreeUpdate};
53use winit::{
54 event::WindowEvent as WinitWindowEvent,
55 event_loop::{ActiveEventLoop, EventLoopProxy},
56 window::{Window, WindowId},
57};
58
59#[cfg(feature = "rwh_05")]
60#[allow(unused)]
61use rwh_05 as raw_window_handle;
62#[cfg(feature = "rwh_06")]
63#[allow(unused)]
64use rwh_06 as raw_window_handle;
65
66mod platform_impl;
67
68#[derive(Debug)]
69pub struct Event {
70 pub window_id: WindowId,
71 pub window_event: WindowEvent,
72}
73
74#[derive(Clone, Debug, PartialEq)]
75pub enum WindowEvent {
76 InitialTreeRequested,
77 ActionRequested(ActionRequest),
78 AccessibilityDeactivated,
79}
80
81struct WinitActivationHandler<T: From<Event> + Send + 'static> {
82 window_id: WindowId,
83 proxy: EventLoopProxy<T>,
84}
85
86impl<T: From<Event> + Send + 'static> ActivationHandler for WinitActivationHandler<T> {
87 fn request_initial_tree(&mut self) -> Option<TreeUpdate> {
88 let event = Event {
89 window_id: self.window_id,
90 window_event: WindowEvent::InitialTreeRequested,
91 };
92 self.proxy.send_event(event.into()).ok();
93 None
94 }
95}
96
97struct WinitActionHandler<T: From<Event> + Send + 'static> {
98 window_id: WindowId,
99 proxy: EventLoopProxy<T>,
100}
101
102impl<T: From<Event> + Send + 'static> ActionHandler for WinitActionHandler<T> {
103 fn do_action(&mut self, request: ActionRequest) {
104 let event = Event {
105 window_id: self.window_id,
106 window_event: WindowEvent::ActionRequested(request),
107 };
108 self.proxy.send_event(event.into()).ok();
109 }
110}
111
112struct WinitDeactivationHandler<T: From<Event> + Send + 'static> {
113 window_id: WindowId,
114 proxy: EventLoopProxy<T>,
115}
116
117impl<T: From<Event> + Send + 'static> DeactivationHandler for WinitDeactivationHandler<T> {
118 fn deactivate_accessibility(&mut self) {
119 let event = Event {
120 window_id: self.window_id,
121 window_event: WindowEvent::AccessibilityDeactivated,
122 };
123 self.proxy.send_event(event.into()).ok();
124 }
125}
126
127pub struct Adapter {
128 inner: platform_impl::Adapter,
129}
130
131impl Adapter {
132 pub fn with_event_loop_proxy<T: From<Event> + Send + 'static>(
150 event_loop: &ActiveEventLoop,
151 window: &Window,
152 proxy: EventLoopProxy<T>,
153 ) -> Self {
154 let window_id = window.id();
155 let activation_handler = WinitActivationHandler {
156 window_id,
157 proxy: proxy.clone(),
158 };
159 let action_handler = WinitActionHandler {
160 window_id,
161 proxy: proxy.clone(),
162 };
163 let deactivation_handler = WinitDeactivationHandler { window_id, proxy };
164 Self::with_direct_handlers(
165 event_loop,
166 window,
167 activation_handler,
168 action_handler,
169 deactivation_handler,
170 )
171 }
172
173 pub fn with_direct_handlers(
191 event_loop: &ActiveEventLoop,
192 window: &Window,
193 activation_handler: impl 'static + ActivationHandler + Send,
194 action_handler: impl 'static + ActionHandler + Send,
195 deactivation_handler: impl 'static + DeactivationHandler + Send,
196 ) -> Self {
197 if window.is_visible() == Some(true) {
198 panic!("The AccessKit winit adapter must be created before the window is shown (made visible) for the first time.");
199 }
200
201 let inner = platform_impl::Adapter::new(
202 event_loop,
203 window,
204 activation_handler,
205 action_handler,
206 deactivation_handler,
207 );
208 Self { inner }
209 }
210
211 pub fn with_mixed_handlers<T: From<Event> + Send + 'static>(
228 event_loop: &ActiveEventLoop,
229 window: &Window,
230 activation_handler: impl 'static + ActivationHandler + Send,
231 proxy: EventLoopProxy<T>,
232 ) -> Self {
233 let window_id = window.id();
234 let action_handler = WinitActionHandler {
235 window_id,
236 proxy: proxy.clone(),
237 };
238 let deactivation_handler = WinitDeactivationHandler { window_id, proxy };
239 Self::with_direct_handlers(
240 event_loop,
241 window,
242 activation_handler,
243 action_handler,
244 deactivation_handler,
245 )
246 }
247
248 pub fn process_event(&mut self, window: &Window, event: &WinitWindowEvent) {
253 self.inner.process_event(window, event);
254 }
255
256 pub fn update_if_active(&mut self, updater: impl FnOnce() -> TreeUpdate) {
263 self.inner.update_if_active(updater);
264 }
265}