Skip to content

fix: accessibility tree in isolated sessions on Fedora#8

Open
davidselassie wants to merge 1 commit intoisac322:mainfrom
davidselassie:fix/a11y-isolated-session
Open

fix: accessibility tree in isolated sessions on Fedora#8
davidselassie wants to merge 1 commit intoisac322:mainfrom
davidselassie:fix/a11y-isolated-session

Conversation

@davidselassie
Copy link
Copy Markdown

@davidselassie davidselassie commented Apr 4, 2026

Summary

Fix accessibility_tree (and all AT-SPI tools) returning empty results or crashing in isolated virtual sessions on Fedora. Extract AT-SPI binary paths from D-Bus service files instead of hardcoding distro-specific paths, and explicitly bootstrap at-spi2-registryd in isolated sessions where no session manager is present to auto-activate it.

Motivation

  1. Wrong binary path: at-spi-bus-launcher was hardcoded to /usr/lib/at-spi-bus-launcher, but Fedora installs it at /usr/libexec/at-spi-bus-launcher. The launcher silently failed to start, so the AT-SPI bus was never created. AT-SPI queries crashed with "Couldn't connect to accessibility bus".

    Fix: Extract the binary path from the D-Bus service file (/usr/share/dbus-1/services/org.a11y.Bus.service) using sed. This is more robust than hardcoding paths for each distro because the service file location is standardized by the D-Bus spec and always contains the correct Exec= path for the current system — whether that's /usr/libexec (Fedora), /usr/lib (Arch), /usr/lib/at-spi2-core (Debian), or anything else. D-Bus auto-activation was also considered but doesn't work from dbus-run-session (fails with "Permission denied").

  2. Missing registryd: Even with the bus launcher running, at-spi2-registryd was never started. D-Bus auto-activation fails because the .service file uses --use-gnome-session, which requires a session manager that doesn't exist in isolated sessions. Without the registryd, no applications register their accessibility trees, so accessibility_tree returned "(no accessible applications found)".

    Fix: Extract the registryd binary path from its service file (/usr/share/dbus-1/accessibility-services/org.a11y.atspi.Registry.service) the same way, then start it directly without --use-gnome-session. The wrapper script also sets IsEnabled=true on the AT-SPI bus so that apps know to register their accessibility trees. No explicit cleanup is needed — session.stop() already kills the entire process group via os.killpg(), which covers the registryd.

How to Test

  1. Verify path extraction resolves to a real binary on your system:
    sed -n 's/^Exec=\([^ ]*\).*/\1/p' /usr/share/dbus-1/services/org.a11y.Bus.service
    
  2. Smoke test — should print an accessibility tree with elements, not "(no accessible applications found)":
    printf 'session_start app_command=kcalc\naccessibility_tree\nsession_stop\nquit\n' \
      | uv run kwin-mcp-cli
    

Checklist

  • uv run ruff check . passes
  • uv run ruff format --check . passes
  • uv run ty check passes
  • CHANGELOG.md updated (if user-facing change)
  • README.md updated (if new tools or changed behavior) — N/A, no new tools or changed behavior

🤖 Generated with Claude Code

## Summary

- Fix `accessibility_tree` (and all AT-SPI tools) returning empty results
  or crashing in isolated virtual sessions on Fedora
- Extract AT-SPI binary paths from D-Bus service files instead of
  hardcoding distro-specific paths
- Explicitly bootstrap the AT-SPI registryd in isolated sessions where
  no session manager is present to auto-activate it

## What broke

Two problems prevented the accessibility tree from working in isolated
virtual sessions on Fedora (and potentially other distros):

1. **Wrong binary path**: `at-spi-bus-launcher` was hardcoded to
   `/usr/lib/at-spi-bus-launcher`, but Fedora installs it at
   `/usr/libexec/at-spi-bus-launcher`. The launcher silently failed to
   start, so the AT-SPI bus was never created. AT-SPI queries crashed
   with "Couldn't connect to accessibility bus".

2. **Missing registryd**: Even with the bus launcher running, the
   `at-spi2-registryd` daemon was never started. D-Bus auto-activation
   fails because the `.service` file uses `--use-gnome-session`, which
   requires a GNOME session manager that doesn't exist in isolated
   sessions. Without the registryd, no applications register their
   accessibility trees, so `accessibility_tree` returned "(no accessible
   applications found)".

## How it's fixed

- Binary paths for both `at-spi-bus-launcher` and `at-spi2-registryd`
  are now extracted from their D-Bus service files
  (`/usr/share/dbus-1/services/org.a11y.Bus.service` and
  `/usr/share/dbus-1/accessibility-services/org.a11y.atspi.Registry.service`).
  These file locations are standardized by the D-Bus spec, so this works
  on any distro without hardcoding paths.
- The wrapper script now explicitly sets `IsEnabled=true` on the AT-SPI
  bus and starts `at-spi2-registryd` without `--use-gnome-session`,
  ensuring apps register their accessibility trees.
- Process cleanup is unchanged: `session.stop()` kills the entire
  process group via `os.killpg()`, which covers the registryd.

## How to test

Verify path extraction resolves to a real binary on your system:

    sed -n 's/^Exec=\([^ ]*\).*/\1/p' /usr/share/dbus-1/services/org.a11y.Bus.service

Smoke test — should print an accessibility tree with elements, not
"(no accessible applications found)":

    printf 'session_start app_command=kcalc\naccessibility_tree\nsession_stop\nquit\n' \
      | uv run kwin-mcp-cli

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@davidselassie davidselassie force-pushed the fix/a11y-isolated-session branch from 325712d to 84e4217 Compare April 4, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant