accesskit_unix/atspi/interfaces/
accessible.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) or the MIT license (found in
4// the LICENSE-MIT file), at your option.
5
6use std::collections::HashMap;
7
8use accesskit_atspi_common::{NodeIdOrRoot, PlatformNode, PlatformRoot};
9use atspi::{Interface, InterfaceSet, Role, StateSet};
10use zbus::{fdo, names::OwnedUniqueName};
11
12use super::map_root_error;
13use crate::atspi::{ObjectId, OwnedObjectAddress};
14
15pub(crate) struct NodeAccessibleInterface {
16    bus_name: OwnedUniqueName,
17    node: PlatformNode,
18}
19
20impl NodeAccessibleInterface {
21    pub fn new(bus_name: OwnedUniqueName, node: PlatformNode) -> Self {
22        Self { bus_name, node }
23    }
24
25    fn map_error(&self) -> impl '_ + FnOnce(accesskit_atspi_common::Error) -> fdo::Error {
26        |error| crate::util::map_error_from_node(&self.node, error)
27    }
28}
29
30#[dbus_interface(name = "org.a11y.atspi.Accessible")]
31impl NodeAccessibleInterface {
32    #[dbus_interface(property)]
33    fn name(&self) -> fdo::Result<String> {
34        self.node.name().map_err(self.map_error())
35    }
36
37    #[dbus_interface(property)]
38    fn description(&self) -> fdo::Result<String> {
39        self.node.description().map_err(self.map_error())
40    }
41
42    #[dbus_interface(property)]
43    fn parent(&self) -> fdo::Result<OwnedObjectAddress> {
44        self.node.parent().map_err(self.map_error()).map(|parent| {
45            match parent {
46                NodeIdOrRoot::Node(node) => ObjectId::Node {
47                    adapter: self.node.adapter_id(),
48                    node,
49                },
50                NodeIdOrRoot::Root => ObjectId::Root,
51            }
52            .to_address(self.bus_name.clone())
53        })
54    }
55
56    #[dbus_interface(property)]
57    fn child_count(&self) -> fdo::Result<i32> {
58        self.node.child_count().map_err(self.map_error())
59    }
60
61    #[dbus_interface(property)]
62    fn locale(&self) -> &str {
63        ""
64    }
65
66    #[dbus_interface(property)]
67    fn accessible_id(&self) -> fdo::Result<String> {
68        self.node.accessible_id().map_err(self.map_error())
69    }
70
71    fn get_child_at_index(&self, index: i32) -> fdo::Result<(OwnedObjectAddress,)> {
72        let index = index
73            .try_into()
74            .map_err(|_| fdo::Error::InvalidArgs("Index can't be negative.".into()))?;
75        let child = self
76            .node
77            .child_at_index(index)
78            .map_err(self.map_error())?
79            .map(|child| ObjectId::Node {
80                adapter: self.node.adapter_id(),
81                node: child,
82            });
83        Ok(super::optional_object_address(&self.bus_name, child))
84    }
85
86    fn get_children(&self) -> fdo::Result<Vec<OwnedObjectAddress>> {
87        self.node
88            .map_children(|child| {
89                ObjectId::Node {
90                    adapter: self.node.adapter_id(),
91                    node: child,
92                }
93                .to_address(self.bus_name.clone())
94            })
95            .map_err(self.map_error())
96    }
97
98    fn get_index_in_parent(&self) -> fdo::Result<i32> {
99        self.node.index_in_parent().map_err(self.map_error())
100    }
101
102    fn get_role(&self) -> fdo::Result<Role> {
103        self.node.role().map_err(self.map_error())
104    }
105
106    fn get_localized_role_name(&self) -> fdo::Result<String> {
107        self.node.localized_role_name().map_err(self.map_error())
108    }
109
110    fn get_state(&self) -> StateSet {
111        self.node.state()
112    }
113
114    fn get_attributes(&self) -> fdo::Result<HashMap<&str, String>> {
115        self.node.attributes().map_err(self.map_error())
116    }
117
118    fn get_application(&self) -> (OwnedObjectAddress,) {
119        (ObjectId::Root.to_address(self.bus_name.clone()),)
120    }
121
122    fn get_interfaces(&self) -> fdo::Result<InterfaceSet> {
123        self.node.interfaces().map_err(self.map_error())
124    }
125}
126
127pub(crate) struct RootAccessibleInterface {
128    bus_name: OwnedUniqueName,
129    desktop_address: OwnedObjectAddress,
130    root: PlatformRoot,
131}
132
133impl RootAccessibleInterface {
134    pub fn new(
135        bus_name: OwnedUniqueName,
136        desktop_address: OwnedObjectAddress,
137        root: PlatformRoot,
138    ) -> Self {
139        Self {
140            bus_name,
141            desktop_address,
142            root,
143        }
144    }
145}
146
147#[dbus_interface(name = "org.a11y.atspi.Accessible")]
148impl RootAccessibleInterface {
149    #[dbus_interface(property)]
150    fn name(&self) -> fdo::Result<String> {
151        self.root.name().map_err(map_root_error)
152    }
153
154    #[dbus_interface(property)]
155    fn description(&self) -> &str {
156        ""
157    }
158
159    #[dbus_interface(property)]
160    fn parent(&self) -> OwnedObjectAddress {
161        self.desktop_address.clone()
162    }
163
164    #[dbus_interface(property)]
165    fn child_count(&self) -> fdo::Result<i32> {
166        self.root.child_count().map_err(map_root_error)
167    }
168
169    #[dbus_interface(property)]
170    fn locale(&self) -> &str {
171        ""
172    }
173
174    #[dbus_interface(property)]
175    fn accessible_id(&self) -> &str {
176        ""
177    }
178
179    fn get_child_at_index(&self, index: i32) -> fdo::Result<(OwnedObjectAddress,)> {
180        let index = index
181            .try_into()
182            .map_err(|_| fdo::Error::InvalidArgs("Index can't be negative.".into()))?;
183        let child = self
184            .root
185            .child_id_at_index(index)
186            .map_err(map_root_error)?
187            .map(|(adapter, node)| ObjectId::Node { adapter, node });
188        Ok(super::optional_object_address(&self.bus_name, child))
189    }
190
191    fn get_children(&self) -> fdo::Result<Vec<OwnedObjectAddress>> {
192        self.root
193            .map_child_ids(|(adapter, node)| {
194                ObjectId::Node { adapter, node }.to_address(self.bus_name.clone())
195            })
196            .map_err(map_root_error)
197    }
198
199    fn get_index_in_parent(&self) -> i32 {
200        -1
201    }
202
203    fn get_role(&self) -> Role {
204        Role::Application
205    }
206
207    fn get_state(&self) -> StateSet {
208        StateSet::empty()
209    }
210
211    fn get_application(&self) -> (OwnedObjectAddress,) {
212        (ObjectId::Root.to_address(self.bus_name.clone()),)
213    }
214
215    fn get_interfaces(&self) -> InterfaceSet {
216        InterfaceSet::new(Interface::Accessible | Interface::Application)
217    }
218}