AccessKit / AccessKit/accesskit

Simple example for atspi/unix?

Open
#633 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
1.5k
Forks
114
Avg merge
8h 25m
Merged PRs (30d)
28

Description

Thank you for the great work on accesskit

I was trying to investigate contributing a simple quickstart example for unix with atspi since I am reasonably familiar with atspi itself, but can't seem to figure out how to get the unix adapter working.

The code at the end of this issue compiles and prints fine to stdout but Orca does not speak the announcement and I do not see any accessibility info in the acceserciser GUI on Linux.

I am on Ubuntu 24.04 with Orca v49, I am running the example in X11 from a separate terminal and there shouldn't be any app armor / sandboxing stuff interfering. I am unclear if this is related perhaps to #328 in some way?

Apologies if I am missing something obvious but I feel I am a bit stuck. I assumed that I could just do no-ops for the ActionHandler since I just want it to initialize the tree and make the announcement.

use accesskit::{
    ActionHandler, ActionRequest, ActivationHandler, DeactivationHandler, Live, Node, NodeId, Role, Tree, TreeUpdate,
};
use accesskit_unix::Adapter;

const ROOT_ID: NodeId = NodeId(0);
const ANNOUNCEMENT_ID: NodeId = NodeId(1);

struct MyActivationHandler;
struct MyActionHandler;
struct MyDeactivationHandler;

fn build_announcement(text: &str) -> Node {
    let mut node = Node::new(Role::Label);
    node.set_value(text);
    node.set_live(Live::Assertive);
    node
}

impl ActivationHandler for MyActivationHandler {
    fn request_initial_tree(&mut self) -> Option<TreeUpdate> {

        let mut root = Node::new(Role::Label);
        root.set_children(vec![ANNOUNCEMENT_ID]);

        let tree = Tree::new(ROOT_ID);
        Some(TreeUpdate {
            nodes: vec![
                (ROOT_ID, root),
                (ANNOUNCEMENT_ID, build_announcement("Hello world")),
            ],
            tree: Some(tree),
            focus: ROOT_ID,
        })
    }
}

impl ActionHandler for MyActionHandler {
    fn do_action(&mut self, request: ActionRequest) {
        println!("Action: {:?}", request);
    }
}

impl DeactivationHandler for MyDeactivationHandler {
    fn deactivate_accessibility(&mut self) {
        println!("Accessibility deactivated");
    }
}

fn main() {
    let mut adapter = Adapter::new(
        MyActivationHandler,
        MyActionHandler,
        MyDeactivationHandler,
    );

    // Send initial tree unconditionally
    adapter.update_if_active(|| MyActivationHandler.request_initial_tree().unwrap());

    println!("Adapter initialized successfully!");

    // Simulate updating the live region later
    std::thread::sleep(std::time::Duration::from_secs(2));
    adapter.update_if_active(|| TreeUpdate {
        nodes: vec![(ANNOUNCEMENT_ID, build_announcement("Hello, world again!"))],
        tree: None,
        focus: ROOT_ID,
    });

    println!("Announcement updated!");
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Rust example in the issue and the accesskit_unix::Adapter entry point, then trace how the activation, action, and deactivation handlers are used. Reproduce the behavior with Orca and Accerciser on Ubuntu X11. Done means a minimal Unix quickstart example initializes the tree and produces the expected live-region announcements.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
accessibility, desktop
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.