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 ] |
13 | extern crate static_assertions; |
14 | #[macro_use ] |
15 | pub(crate) mod macros; |
16 | |
17 | pub mod object_ref; |
18 | pub use object_ref::ObjectRef; |
19 | pub mod interface; |
20 | pub use interface::{Interface, InterfaceSet}; |
21 | pub mod state; |
22 | pub use state::{State, StateSet}; |
23 | pub mod cache; |
24 | pub use cache::{CacheItem, LegacyCacheItem}; |
25 | pub mod error; |
26 | pub use error::AtspiError; |
27 | pub mod events; |
28 | pub use events::{BusProperties, Event, EventProperties, EventTypeProperties}; |
29 | mod role; |
30 | pub use role::Role; |
31 | mod relation_type; |
32 | pub use relation_type::RelationType; |
33 | |
34 | use serde::{Deserialize, Serialize}; |
35 | use zvariant::Type; |
36 | |
37 | pub type Result<T> = std::result::Result<T, AtspiError>; |
38 | |
39 | pub 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 |
57 | pub 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)] |
77 | pub 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 |
91 | pub 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. |
108 | pub 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. |
120 | pub 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. |
134 | pub 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)] |
162 | pub 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)] |
188 | pub 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)] |
212 | pub 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 | |
222 | impl 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)] |
236 | mod 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 | |