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
9use crate::atspi_proxy;
10use crate::common::{Accessible, InterfaceSet, RelationType, Role, StateSet};
11use crate::AtspiError;
12
13#[atspi_proxy(interface = "org.a11y.atspi.Accessible", assume_defaults = true)]
14trait 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
226impl 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}
235impl 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
245impl PartialEq for AccessibleProxy<'_> {
246 fn eq<'a>(&self, other: &Self) -> bool {
247 self.path() == other.path() //&& self.destination() == other.destination()
248 }
249}
250impl Eq for AccessibleProxy<'_> {}
251
252#[cfg(test)]
253mod 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