1#![deny(clippy::all, clippy::pedantic, clippy::cargo, unsafe_code, rustdoc::all)]
2#![allow(clippy::module_name_repetitions)]
3#![allow(clippy::multiple_crate_versions)]
4
5//! # atspi-common
6//!
7//! Defines all common types, events, and data structures for `atspi-proxies` and `atspi-connection`.
8//! Since `atspi-proxies` and `atspi-connection` are downstream crates, the documentation can not link to it directly.
9//! Any type ending in `*Proxy` is in `atspi-proxies`.
10//!
11
12#[macro_use]
13extern crate static_assertions;
14#[macro_use]
15pub(crate) mod macros;
16
17pub mod object_ref;
18pub use object_ref::ObjectRef;
19pub mod interface;
20pub use interface::{Interface, InterfaceSet};
21pub mod state;
22pub use state::{State, StateSet};
23pub mod cache;
24pub use cache::{CacheItem, LegacyCacheItem};
25pub mod error;
26pub use error::AtspiError;
27pub mod events;
28pub use events::{BusProperties, Event, EventProperties, EventTypeProperties};
29mod role;
30pub use role::Role;
31mod relation_type;
32pub use relation_type::RelationType;
33
34use serde::{Deserialize, Serialize};
35use zvariant::Type;
36
37pub type Result<T> = std::result::Result<T, AtspiError>;
38
39pub type MatchArgs<'a> = (
40 &'a [i32],
41 MatchType,
42 std::collections::HashMap<&'a str, &'a str>,
43 MatchType,
44 &'a [i32],
45 MatchType,
46 &'a [&'a str],
47 MatchType,
48 bool,
49);
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
52#[repr(u32)]
53/// Enumeration used by interface `CollectionProxy` to specify the way [`ObjectRef`]
54/// objects should be sorted.
55///
56/// [`ObjectRef`]: crate::object_ref::ObjectRef
57pub enum SortOrder {
58 /// Invalid sort order
59 Invalid,
60 /// Canonical sort order
61 Canonical,
62 /// Flow sort order
63 Flow,
64 /// Tab sort order
65 Tab,
66 /// Reverse canonical sort order
67 ReverseCanonical,
68 /// Reverse flow sort order
69 ReverseFlow,
70 /// Reverse tab sort order
71 ReverseTab,
72}
73
74/// Method of traversing a tree in the `CollectionProxy`.
75#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
76#[repr(u32)]
77pub enum TreeTraversalType {
78 /// Restrict children tree traversal
79 RestrictChildren,
80 /// Restrict sibling tree traversal
81 RestrictSibling,
82 /// In-order tree traversal.
83 Inorder,
84}
85
86#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
87#[repr(i32)]
88/// Enumeration used by [`MatchArgs`] to specify how to interpret [`ObjectRef`] objects.
89///
90/// [`ObjectRef`]: crate::object_ref::ObjectRef
91pub enum MatchType {
92 /// Invalid match type
93 Invalid,
94 /// true if all of the criteria are met.
95 All,
96 /// true if any of the criteria are met.
97 Any,
98 /// true if none of the criteria are met.
99 NA,
100 /// Same as [`Self::All`] if the criteria is non-empty;
101 /// for empty criteria this rule requires returned value to also have empty set.
102 Empty,
103}
104
105#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
106#[repr(u32)]
107/// The coordinate type encodes the frame of reference.
108pub enum CoordType {
109 /// In relation to the entire screen.
110 Screen,
111 /// In relation to only the window.
112 Window,
113 /// In relation to the parent of the element being checked.
114 Parent,
115}
116
117#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Type)]
118#[repr(u32)]
119/// Enumeration used by `TextProxy` to indicate how to treat characters intersecting bounding boxes.
120pub enum ClipType {
121 /// No characters/glyphs are omitted.
122 Neither,
123 /// Characters/glyphs clipped by the minimum coordinate are omitted.
124 Min,
125 /// Characters/glyphs which intersect the maximum coordinate are omitted.
126 Max,
127 /// Only glyphs falling entirely within the region bounded by min and max are retained.
128 Both,
129}
130
131#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize, Type)]
132#[repr(u32)]
133/// Level of granularity to get text of, in relation to a cursor position.
134pub enum Granularity {
135 /// Gives the character at the index of the cursor. With a line-style cursor (which is standard) this will get the character that appears after the cursor.
136 Char,
137 /// Gives the entire word in front of, or which contains, the cursor. TODO: confirm that it always chooses the word in front of the cursor.
138 Word,
139 /// Gives entire sentence in front of, or which contains, the cursor. TODO: confirm that it always chooses the sentence after the cursor.
140 Sentence,
141 /// Gives the line, as seen visually of which the cursor is situated within.
142 Line,
143 /// Gives the entire block of text, regardless of where the cursor lies within it.
144 Paragraph,
145}
146
147/// Indicates relative stacking order of a `atspi_proxies::component::ComponentProxy` with respect to the
148/// onscreen visual representation of the UI.
149///
150/// The layer index, in combination with the component's extents,
151/// can be used to compute the visibility of all or part of a component.
152/// This is important in programmatic determination of region-of-interest for magnification,
153/// and in flat screen review models of the screen, as well as for other uses.
154/// Objects residing in two of the `Layer` categories support further z-ordering information,
155/// with respect to their peers in the same layer:
156/// namely, [`Layer::Window`] and [`Layer::Mdi`].
157/// Relative stacking order for other objects within the same layer is not available;
158/// the recommended heuristic is first child paints first. In other words,
159/// assume that the first siblings in the child list are subject to being
160/// overpainted by later siblings if their bounds intersect.
161#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
162pub enum Layer {
163 /// Indicates an error condition or uninitialized value.
164 Invalid,
165 /// Reserved for the desktop background; this is the bottom-most layer,
166 /// over which everything else is painted.
167 Background,
168 /// The 'background' layer for most content renderers and
169 /// UI `atspi_proxies::component::ComponentProxy` containers.
170 Canvas,
171 /// The layer in which the majority of ordinary 'foreground' widgets reside.
172 Widget,
173 /// A special layer between [`Layer::Canvas`] and [`Layer::Widget`], in which the
174 /// 'pseudo windows' (e.g. the Multiple-Document Interface frames) reside.
175 ///
176 /// See `atspi_proxies::component::ComponentProxy::get_mdizorder`.
177 Mdi,
178 /// A layer for popup window content, above [`Layer::Widget`].
179 Popup,
180 /// The topmost layer.
181 Overlay,
182 /// The layer in which a toplevel window background usually resides.
183 Window,
184}
185
186/// Enumeration used by interface the [`crate::interface::Interface::Accessible`] to specify where an object should be placed on the screen when using `scroll_to`.
187#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
188pub enum ScrollType {
189 /// Scroll the object to the top left corner of the window.
190 TopLeft,
191 /// Scroll the object to the bottom right corner of the window.
192 BottomRight,
193 /// Scroll the object to the top edge of the window.
194 TopEdge,
195 /// Scroll the object to the bottom edge of the window.
196 BottomEdge,
197 /// Scroll the object to the left edge of the window.
198 LeftEdge,
199 /// Scroll the object to the right edge of the window.
200 RightEdge,
201 /// Scroll the object to application-dependent position on the window.
202 Anywhere,
203}
204
205/// Enumeration used to indicate a type of live region and how assertive it
206/// should be in terms of speaking notifications. Currently, this is only used
207/// for `Announcement` events, but it may be used for additional purposes
208/// in the future.
209/// The argument in the `Announcement` event is named `politeness`.
210#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize, Type)]
211#[repr(i32)]
212pub enum Live {
213 /// No live region.
214 #[default]
215 None,
216 /// This live region should be considered polite.
217 Polite,
218 /// This live region should be considered assertive.
219 Assertive,
220}
221
222impl TryFrom<i32> for Live {
223 type Error = AtspiError;
224
225 fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
226 match value {
227 0 => Ok(Live::None),
228 1 => Ok(Live::Polite),
229 2 => Ok(Live::Assertive),
230 _ => Err(AtspiError::Conversion("Unknown Live variant")),
231 }
232 }
233}
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238 use zbus_lockstep::{
239 method_args_signature, method_return_signature, signal_body_type_signature,
240 };
241
242 #[test]
243 fn convert_i32_to_live() {
244 assert_eq!(Live::None, Live::try_from(0).unwrap());
245 assert_eq!(Live::Polite, Live::try_from(1).unwrap());
246 assert_eq!(Live::Assertive, Live::try_from(2).unwrap());
247 assert!(Live::try_from(3).is_err());
248 assert!(Live::try_from(-1).is_err());
249 }
250
251 #[test]
252 fn validate_live_signature() {
253 let signature = signal_body_type_signature!("Announcement");
254 let politeness_signature = signature.slice(1..2);
255 assert_eq!(Live::signature(), politeness_signature);
256 }
257
258 #[test]
259 fn validate_scroll_type_signature() {
260 let signature = method_args_signature!(member: "ScrollTo", interface: "org.a11y.atspi.Component", argument: "type");
261 assert_eq!(ScrollType::signature(), signature);
262 }
263
264 #[test]
265 fn validate_layer_signature() {
266 let signature = method_return_signature!("GetLayer");
267 assert_eq!(Layer::signature(), signature);
268 }
269
270 #[test]
271 fn validate_granularity_signature() {
272 let signature = method_args_signature!(member: "GetStringAtOffset", interface: "org.a11y.atspi.Text", argument: "granularity");
273 assert_eq!(Granularity::signature(), signature);
274 }
275
276 #[test]
277 fn validate_clip_type_signature() {
278 let signature = method_args_signature!(member: "GetTextAtOffset", interface: "org.a11y.atspi.Text", argument: "type");
279 assert_eq!(ClipType::signature(), signature);
280 }
281
282 #[test]
283 fn validate_coord_type_signature() {
284 let signature = method_args_signature!(member: "GetImagePosition", interface: "org.a11y.atspi.Image", argument: "coordType");
285 assert_eq!(CoordType::signature(), signature);
286 }
287
288 #[test]
289 fn validate_match_type_signature() {
290 let rule_signature = method_args_signature!(member: "GetMatchesTo", interface: "org.a11y.atspi.Collection", argument: "rule");
291 let match_type_signature = rule_signature.slice(3..4);
292 assert_eq!(MatchType::signature(), match_type_signature);
293 }
294
295 #[test]
296 fn validate_tree_traversal_type_signature() {
297 let signature = method_args_signature!(member: "GetMatchesTo", interface: "org.a11y.atspi.Collection", argument: "tree");
298 assert_eq!(TreeTraversalType::signature(), signature);
299 }
300
301 #[test]
302 fn validate_sort_order_signature() {
303 let signature = method_args_signature!(member: "GetMatches", interface: "org.a11y.atspi.Collection", argument: "sortby");
304 assert_eq!(SortOrder::signature(), signature);
305 }
306}
307