1 | //! # `AccessibleProxy` |
2 | //! |
3 | //! A handle for a remote object implementing the `org.a11y.atspi.Accessible` |
4 | //! interface. |
5 | //! |
6 | //! Accessible is the interface which is implemented by all accessible objects. |
7 | //! |
8 | |
9 | use crate::atspi_proxy ; |
10 | use crate::common::{Accessible, InterfaceSet, RelationType, Role, StateSet}; |
11 | use crate::AtspiError; |
12 | |
13 | #[atspi_proxy (interface = "org.a11y.atspi.Accessible" , assume_defaults = true)] |
14 | trait Accessible { |
15 | /// Returns an [`Accessible`] which refers to the `Application` object of the application. |
16 | /// This object will have [`Application`] interface implemented. |
17 | /// |
18 | /// The application object is the root of the accessibility hierarchy for the application. |
19 | /// It is the only object in the hierarchy that does not have a parent. |
20 | /// |
21 | /// ## Notes |
22 | /// The application object is the only object in the accessibility hierarchy that is |
23 | /// guaranteed to be persistent for the lifetime of the application. |
24 | /// All other objects in the accessibility hierarchy may be created and destroyed dynamically. |
25 | /// |
26 | /// [`Accessible`]: ../crate::common::events::Accessible |
27 | /// [`Application`]: <https://docs.rs/atspi-proxies/0.1.0/atspi_proxies/application/struct.ApplicationProxy.html> |
28 | fn get_application(&self) -> zbus::Result<Accessible>; |
29 | |
30 | /// Gets a list of name/value pairs of attributes or annotations for this object. |
31 | /// |
32 | /// ## Disambiguation |
33 | /// For typographic, textual, or textually-semantic attributes, |
34 | /// see [`TextProxy`]'s [`get_attributes`] method instead. |
35 | /// |
36 | /// [`TextProxy`]: https://docs.rs/atspi-proxies/0.1.0/atspi_proxies/text/struct.TextProxy.html |
37 | /// [`get_attributes`]: https://docs.rs/atspi-proxies/0.1.0/atspi_proxies/text/struct.TextProxy.html#method.get_attributes |
38 | fn get_attributes(&self) -> zbus::Result<std::collections::HashMap<String, String>>; |
39 | |
40 | /// Retrieve child by index (starting from 0), |
41 | /// |
42 | /// Queries the N-th accessible child of `self`. It is expected that this |
43 | /// will correspond to the order that the [`get_children`] method would return. |
44 | /// |
45 | /// ## Notes |
46 | /// Implementations vary in their behavior when the index is out of range. |
47 | /// GTK4 returns an error, while atk-adaptor (e.g. Gtk3) returns the |
48 | /// null object path "/org/a11y/atspi/null". |
49 | /// |
50 | /// Documentation advises implementors to return a DBus Error when the index is |
51 | /// out of range, to "keep the type system gods happy". |
52 | /// |
53 | /// [`get_children`]: #method.get_children |
54 | fn get_child_at_index(&self, index: i32) -> zbus::Result<Accessible>; |
55 | |
56 | /// Retrieves a list of the object's accessible children. |
57 | /// |
58 | /// Each array element is an [`Accessible`] representing the accessible child object. |
59 | /// |
60 | /// ## Registry |
61 | /// |
62 | /// On the `Accessible` interface of `org.a11y.atspi.Registry`, the registry daemon, this method retrieves a list |
63 | /// of all accessible applications' root objects on the bus. |
64 | /// |
65 | /// [`Accessible`]: ../crate::common::events::Accessible |
66 | fn get_children(&self) -> zbus::Result<Vec<Accessible>>; |
67 | |
68 | /// This object resides in its parent's list of children. |
69 | /// This returns its position in this list of children, starting from 0. |
70 | /// |
71 | /// The function returns -1 if the object does not have a parent or |
72 | /// if an exception occurs. |
73 | fn get_index_in_parent(&self) -> zbus::Result<i32>; |
74 | |
75 | /// Returns an [`InterfaceSet`] accessible interface names supported by the `self` object. |
76 | /// [`InterfaceSet`]: crate::common::InterfaceSet |
77 | fn get_interfaces(&self) -> zbus::Result<InterfaceSet>; |
78 | |
79 | /// Gets a `String` corresponding to the name of the role played by an object, |
80 | /// translated to the current locale. |
81 | /// |
82 | /// ## Notes |
83 | /// |
84 | /// This method will return useful values for roles that fall outside the |
85 | /// enumeration used in the [`get_role`] method. |
86 | /// |
87 | /// For applications, implementing this method is optional, and it may be removed |
88 | /// in a future version of the API. |
89 | /// |
90 | /// For example, [`libatspi`] will only call it in the event of an unknown role. |
91 | /// |
92 | /// [`libatspi`]: <https://gitlab.gnome.org/GNOME/at-spi2-core/main/atspi> |
93 | /// [`get_role`]: #method.get_role |
94 | fn get_localized_role_name(&self) -> zbus::Result<String>; |
95 | |
96 | /// Returns a set of relationships between the this `self` object and others. |
97 | /// |
98 | /// This vector of tuples contains a [`RelationType`] and a vector of [`Accessible`]'s to which that |
99 | /// relationship applies. |
100 | /// These relationships allow for better identification of how objects are associated with one another. |
101 | /// |
102 | /// For example, the relationship [`RelationType::LabelledBy`] can be used to identify labeling information |
103 | /// that should accompany the accessible [`name`] property when presenting an object's content or identity |
104 | /// to the end user. |
105 | /// |
106 | /// Similarly, [`RelationType::ControllerFor`] can be used to specify the context in which a valuator is useful |
107 | /// and/or the other UI components that are directly affected by user interactions with the valuator. |
108 | /// Common examples include the association of scrollbars with the viewport or panel that they control. |
109 | /// |
110 | /// [`RelationType`]: crate::common::RelationType |
111 | /// [`RelationType::LabelledBy`]: crate::common::RelationType::LabelledBy |
112 | /// [`RelationType::ControllerFor`]: crate::common::RelationType::ControllerFor |
113 | /// [`name`]: #method.name |
114 | /// [`Accessible`]: ../crate::common::events::Accessible |
115 | fn get_relation_set(&self) -> zbus::Result<Vec<(RelationType, Vec<Accessible>)>>; |
116 | |
117 | /// Gets the [`Role`] that the current accessible object represents. |
118 | /// |
119 | /// Roles make it possible for various UI toolkits to expose their controls to |
120 | /// assistive technologies (ATs) with a standard interface, regardless of toolkit. |
121 | /// |
122 | /// For example, a widget that acts like a conventional push button |
123 | /// (appears unpressed; presses when acted upon; invokes a certain action |
124 | /// when pressed) can expose an [`Role::PushButton`] role. |
125 | /// |
126 | /// [`Role::PushButton`]: crate::common::Role::PushButton |
127 | /// [`Role`]: crate::common::Role |
128 | fn get_role(&self) -> zbus::Result<Role>; |
129 | |
130 | /// Gets a `String` corresponding to the name of the role played by an object, |
131 | /// translated to the current locale. |
132 | /// |
133 | /// ## Notes |
134 | /// |
135 | /// This method will return useful values for roles that fall outside the |
136 | /// enumeration used in the `get_role` method. |
137 | /// |
138 | /// For applications, implementing this method is optional, and it may be removed |
139 | /// in a future version of the API. |
140 | /// |
141 | /// [`libatspi`]: <https://gitlab.gnome.org/GNOME/at-spi2-core/main/atspi> |
142 | /// [`libatspi`]: <https://gitlab.gnome.org/GNOME/at-spi2-core/> |
143 | fn get_role_name(&self) -> zbus::Result<String>; |
144 | |
145 | /// Method to retrieve the [`StateSet`] of states currently held by `self`. |
146 | /// [`StateSet`]: crate::common::StateSet |
147 | fn get_state(&self) -> zbus::Result<StateSet>; |
148 | |
149 | /// Application-specific identifier for the current object. |
150 | /// |
151 | /// A special id given to an object. |
152 | /// Accessible application developers can use this to give a special id to an object |
153 | /// to use in tests, for example, "my_widget". |
154 | /// |
155 | /// Note that there is no way to directly find an object by its id; |
156 | /// a test program may have to recursively get the children to find a specific id. |
157 | /// This is because accessible objects can be created dynamically, and they do not always |
158 | /// correspond to a static view of an application's data. |
159 | #[dbus_proxy(property)] |
160 | fn accessible_id(&self) -> zbus::Result<String>; |
161 | |
162 | /// Number of accessible children for the current object. |
163 | #[dbus_proxy(property)] |
164 | fn child_count(&self) -> zbus::Result<i32>; |
165 | |
166 | /// Human-readable, localized description of `self` in more detail. |
167 | /// |
168 | /// This is a longer description than the [`Name`][name] property. |
169 | /// |
170 | /// For example, a button might have a name of "OK", but a description of "OK button". |
171 | /// |
172 | /// While the Name property is meant to be a short string that screen readers say |
173 | /// during normal navigation, the Description property is for when the user asks for |
174 | /// more detail. |
175 | /// |
176 | /// [name]: #method.name |
177 | #[dbus_proxy(property)] |
178 | fn description(&self) -> zbus::Result<String>; |
179 | |
180 | /// Unix locale for the current object. |
181 | /// |
182 | /// This is a string in the form of "language_territory.codeset". |
183 | /// For example, "en_US.UTF-8" or "de_DE.UTF-8". |
184 | /// |
185 | /// For an application, this may be the locale for the language that the application |
186 | /// shows in its user interface. |
187 | /// |
188 | /// For a document being shown in an application, or a paragraph within a document, |
189 | /// the locale may refer to that object exclusively. For example: |
190 | /// an application may be showing itself in English ("en"), but it may be used to |
191 | /// display a document in Spanish ("es"). |
192 | /// In the latter case, a screen reader will want to know that it should switch to |
193 | /// Spanish while reading the document. |
194 | #[dbus_proxy(property)] |
195 | fn locale(&self) -> zbus::Result<String>; |
196 | |
197 | /// Human-readable, localized, short name for the object. |
198 | /// |
199 | /// Applications should have this set for objects which do not |
200 | /// have a [`RelationType::LabelledBy`] relation. |
201 | /// |
202 | /// Consider a widget to select RGB colors by setting three sliders. |
203 | /// The names for the sliders would be "Red", "Green", "Blue", respectively, or |
204 | /// their translations to application's locale. The names would be unnecessary if each |
205 | /// slider had a `LabeledBy` relation to corresponding labels visible in the user |
206 | /// interface. |
207 | /// |
208 | /// [`RelationType::LabelledBy`]: crate::common::RelationType::LabelledBy |
209 | #[dbus_proxy(property)] |
210 | fn name(&self) -> zbus::Result<String>; |
211 | |
212 | /// Accessible parent object of the current object. |
213 | /// |
214 | /// Null parent: |
215 | /// If the object has no parent (e.g. the application's root object is being queried), |
216 | /// The application should return "" for the application name name and "/org/a11y/atspi/null" |
217 | /// for the object path. |
218 | /// |
219 | /// Root object: |
220 | /// An application must have a single root object, called "/org/a11y/atspi/accessible/root". |
221 | /// All other objects should have that one as their highest-level ancestor. |
222 | #[dbus_proxy(property)] |
223 | fn parent(&self) -> zbus::Result<Accessible>; |
224 | } |
225 | |
226 | impl TryFrom<AccessibleProxy<'_>> for Accessible { |
227 | type Error = AtspiError; |
228 | fn try_from(proxy: AccessibleProxy<'_>) -> Result<Accessible, Self::Error> { |
229 | Ok(Accessible { |
230 | name: proxy.destination().to_string(), |
231 | path: proxy.path().to_string().try_into()?, |
232 | }) |
233 | } |
234 | } |
235 | impl TryFrom<&AccessibleProxy<'_>> for Accessible { |
236 | type Error = AtspiError; |
237 | fn try_from(proxy: &AccessibleProxy<'_>) -> Result<Accessible, Self::Error> { |
238 | Ok(Accessible { |
239 | name: proxy.destination().to_string(), |
240 | path: proxy.path().to_string().try_into()?, |
241 | }) |
242 | } |
243 | } |
244 | |
245 | impl PartialEq for AccessibleProxy<'_> { |
246 | fn eq<'a>(&self, other: &Self) -> bool { |
247 | self.path() == other.path() //&& self.destination() == other.destination() |
248 | } |
249 | } |
250 | impl Eq for AccessibleProxy<'_> {} |
251 | |
252 | #[cfg (test)] |
253 | mod tests { |
254 | use crate::accessible::Role; |
255 | |
256 | #[test ] |
257 | fn test_output_of_role_name() { |
258 | assert_eq!(Role::Invalid.name(), "invalid" ); |
259 | assert_eq!(Role::PushButtonMenu.name(), "push button menu" ); |
260 | } |
261 | } |
262 | |