Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions platforms/unix/src/atspi/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ use accesskit_atspi_common::{
NodeId, NodeIdOrRoot, ObjectEvent, PlatformNode, PlatformRoot, Property, WindowEvent,
};
use atspi::{
Interface, InterfaceSet,
Interface, InterfaceSet, ObjectRefOwned,
events::EventBodyBorrowed,
proxy::{bus::BusProxy, socket::SocketProxy},
};
use std::{env::var, io};
use std::{
env::var,
io,
sync::{Arc, OnceLock},
};
use zbus::{
Address, Connection, Result,
connection::Builder,
Expand All @@ -28,6 +32,7 @@ pub(crate) struct Bus {
conn: Connection,
_task: Task<()>,
socket_proxy: SocketProxy<'static>,
desktop: Arc<OnceLock<ObjectRefOwned>>,
}

impl Bus {
Expand Down Expand Up @@ -58,6 +63,7 @@ impl Bus {
conn,
_task,
socket_proxy,
desktop: Arc::new(OnceLock::new()),
};
bus.register_root_node().await?;
Ok(bus)
Expand All @@ -77,23 +83,33 @@ impl Bus {
.at(path.clone(), ApplicationInterface(node.clone()))
.await?
{
self.socket_proxy
let desktop = self
.socket_proxy
.embed(&(self.unique_name().as_str(), ObjectId::Root.path().into()))
.await?;
let _ = self.desktop.set(desktop);

self.conn
.object_server()
.at(
path,
RootAccessibleInterface::new(self.unique_name().to_owned(), node.clone()),
RootAccessibleInterface::new(
self.unique_name().to_owned(),
node.clone(),
Arc::clone(&self.desktop),
),
)
.await?;

self.conn
.object_server()
.at(
cache_path(),
CacheInterface::new(self.unique_name().to_owned(), node),
CacheInterface::new(
self.unique_name().to_owned(),
node,
Arc::clone(&self.desktop),
),
)
.await?;
}
Expand Down
27 changes: 22 additions & 5 deletions platforms/unix/src/atspi/interfaces/accessible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
// the LICENSE-APACHE file) or the MIT license (found in
// the LICENSE-MIT file), at your option.

use std::collections::HashMap;
use std::{
collections::HashMap,
sync::{Arc, OnceLock},
};

use accesskit_atspi_common::{NodeIdOrRoot, PlatformNode, PlatformRoot};
use atspi::{InterfaceSet, RelationType, Role, StateSet};
use atspi::{InterfaceSet, ObjectRefOwned, RelationType, Role, StateSet};
use zbus::{fdo, interface, names::OwnedUniqueName};

use super::map_root_error;
Expand Down Expand Up @@ -143,11 +146,20 @@ impl NodeAccessibleInterface {
pub(crate) struct RootAccessibleInterface {
bus_name: OwnedUniqueName,
root: PlatformRoot,
desktop: Arc<OnceLock<ObjectRefOwned>>,
}

impl RootAccessibleInterface {
pub fn new(bus_name: OwnedUniqueName, root: PlatformRoot) -> Self {
Self { bus_name, root }
pub fn new(
bus_name: OwnedUniqueName,
root: PlatformRoot,
desktop: Arc<OnceLock<ObjectRefOwned>>,
) -> Self {
Self {
bus_name,
root,
desktop,
}
}
}

Expand All @@ -165,7 +177,12 @@ impl RootAccessibleInterface {

#[zbus(property)]
fn parent(&self) -> OwnedObjectAddress {
OwnedObjectAddress::null()
self.desktop
.get()
.cloned()
.unwrap_or_default()
.into_inner()
.into()
}

#[zbus(property)]
Expand Down
44 changes: 35 additions & 9 deletions platforms/unix/src/atspi/interfaces/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

use accesskit_atspi_common::{CacheNode, Error, NodeIdOrRoot, PlatformNode, PlatformRoot};
use atspi::{CacheItem, ObjectRef, ObjectRefOwned};
use std::sync::{Arc, OnceLock};
use zbus::{
fdo, interface,
names::{OwnedUniqueName, UniqueName},
Expand Down Expand Up @@ -52,11 +53,15 @@ fn cache_item(bus_name: &UniqueName, node: CacheNode) -> CacheItem {
}
}

fn application_cache_item(bus_name: &UniqueName, root: &PlatformRoot) -> Result<CacheItem, Error> {
fn application_cache_item(
bus_name: &UniqueName,
root: &PlatformRoot,
desktop: ObjectRefOwned,
) -> Result<CacheItem, Error> {
Ok(CacheItem {
object: object_ref(bus_name, ObjectId::Root),
app: object_ref(bus_name, ObjectId::Root),
parent: ObjectRefOwned::new(ObjectRef::Null),
parent: desktop,
index: root.index_in_parent(),
children: root.child_count()?,
ifaces: root.interfaces(),
Expand All @@ -70,11 +75,20 @@ fn application_cache_item(bus_name: &UniqueName, root: &PlatformRoot) -> Result<
pub(crate) struct CacheInterface {
bus_name: OwnedUniqueName,
root: PlatformRoot,
desktop: Arc<OnceLock<ObjectRefOwned>>,
}

impl CacheInterface {
pub fn new(bus_name: OwnedUniqueName, root: PlatformRoot) -> Self {
Self { bus_name, root }
pub fn new(
bus_name: OwnedUniqueName,
root: PlatformRoot,
desktop: Arc<OnceLock<ObjectRefOwned>>,
) -> Self {
Self {
bus_name,
root,
desktop,
}
}

fn items(&self) -> Result<Vec<CacheItem>, Error> {
Expand All @@ -83,8 +97,9 @@ impl CacheInterface {
.root
.map_descendant_cache_nodes(|node| cache_item(bus_name, node))?;

let desktop = self.desktop.get().cloned().unwrap_or_default();
let mut items = Vec::with_capacity(descendants.len() + 1);
items.push(application_cache_item(bus_name, &self.root)?);
items.push(application_cache_item(bus_name, &self.root, desktop)?);
items.extend(descendants);
Ok(items)
}
Expand All @@ -107,7 +122,8 @@ mod tests {
use accesskit_atspi_common::{
Adapter, AdapterCallback, AppContext, Event, NodeId, PlatformRoot, WindowBounds,
};
use atspi::{Interface, ObjectRef, ObjectRefOwned, Role as AtspiRole};
use atspi::{Interface, ObjectRefOwned, Role as AtspiRole};
use std::sync::{Arc, OnceLock};
use zbus::names::{OwnedUniqueName, UniqueName};

struct NoOpActionHandler;
Expand Down Expand Up @@ -150,7 +166,9 @@ mod tests {

fn cache(update: TreeUpdate) -> (Adapter, CacheInterface) {
let (adapter, root) = root_for(update);
(adapter, CacheInterface::new(bus_name(), root))
let desktop = Arc::new(OnceLock::new());
desktop.set(desktop_ref()).unwrap();
(adapter, CacheInterface::new(bus_name(), root, desktop))
}

fn window_with_button() -> TreeUpdate {
Expand All @@ -175,6 +193,10 @@ mod tests {
)
}

fn desktop_ref() -> ObjectRefOwned {
ObjectRefOwned::from_static_str_unchecked(":1.1", "/org/a11y/atspi/accessible/root")
}

#[test]
fn get_items_prepends_application_root() {
let (_adapter, iface) = cache(window_with_button());
Expand All @@ -184,7 +206,7 @@ mod tests {
};
assert_eq!(app.object, root_ref());
assert_eq!(app.app, root_ref());
assert_eq!(app.parent, ObjectRefOwned::new(ObjectRef::Null));
assert_eq!(app.parent, desktop_ref());
assert_eq!(app.index, -1);
assert_eq!(app.children, 1);
assert_eq!(app.role, AtspiRole::Application);
Expand Down Expand Up @@ -274,7 +296,11 @@ mod tests {
WindowBounds::default(),
NoOpActionHandler,
);
let iface = CacheInterface::new(bus_name(), PlatformRoot::new(&app_context));
let iface = CacheInterface::new(
bus_name(),
PlatformRoot::new(&app_context),
Arc::new(OnceLock::new()),
);
let items = iface.items().unwrap();

let app_root = &items[0];
Expand Down
Loading