accesskit_winit/
lib.rs

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).
4
5/// ## Compatibility with async runtimes
6///
7/// The following only applies on Linux/Unix:
8///
9/// While this crate's API is purely blocking, it internally spawns asynchronous tasks on an executor.
10///
11/// - If you use tokio, make sure to enable the `tokio` feature of this crate.
12/// - If you use another async runtime or if you don't use one at all, the default feature will suit your needs.
13
14#[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::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(Debug)]
75pub enum WindowEvent {
76    InitialTreeRequested,
77    ActionRequested(ActionRequest),
78    AccessibilityDeactivated,
79}
80
81pub struct Adapter {
82    inner: platform_impl::Adapter,
83}
84
85impl Adapter {
86    /// Creates a new AccessKit adapter for a winit window. This must be done
87    /// before the window is shown for the first time. This means that you must
88    /// use [`winit::window::WindowAttributes::with_visible`] to make the window
89    /// initially invisible, then create the adapter, then show the window.
90    ///
91    /// Use this if you want to provide your own AccessKit handler callbacks
92    /// rather than dispatching requests through the winit event loop. This is
93    /// especially useful for the activation handler, because depending on
94    /// your application's architecture, implementing the handler directly may
95    /// allow you to return an initial tree synchronously, rather than requiring
96    /// some platform adapters to use a placeholder tree until you send
97    /// the first update. However, remember that each of these handlers may be
98    /// called on any thread, depending on the underlying platform adapter.
99    pub fn with_direct_handlers(
100        window: &dyn Window,
101        activation_handler: impl 'static + ActivationHandler + Send,
102        action_handler: impl 'static + ActionHandler + Send,
103        deactivation_handler: impl 'static + DeactivationHandler + Send,
104    ) -> Self {
105        let inner = platform_impl::Adapter::new(
106            window,
107            activation_handler,
108            action_handler,
109            deactivation_handler,
110        );
111        Self { inner }
112    }
113
114    /// Allows reacting to window events.
115    ///
116    /// This must be called whenever a new window event is received
117    /// and before it is handled by the application.
118    pub fn process_event(&mut self, window: &dyn Window, event: &WinitWindowEvent) {
119        self.inner.process_event(window, event);
120    }
121
122    /// If and only if the tree has been initialized, call the provided function
123    /// and apply the resulting update. Note: If the caller's implementation of
124    /// [`ActivationHandler::request_initial_tree`] initially returned `None`,
125    /// or if the caller created the adapter using [`EventLoopProxy`], then
126    /// the [`TreeUpdate`] returned by the provided function must contain
127    /// a full tree.
128    pub fn update_if_active(&mut self, updater: impl FnOnce() -> TreeUpdate) {
129        self.inner.update_if_active(updater);
130    }
131}