# AT-SPI Benchmark Results

Date: 2026-01-15

## Environment

- NixOS with `services.gnome.at-spi2-core.enable = true`
- AT-SPI bus launcher and registryd running
- QT_LINUX_ACCESSIBILITY_ALWAYS_ON not tested (no Qt apps active)

## Coverage Audit

| App | Windows | Elements | Enum Time | Coordinates | Text | Actions |
|-----|---------|----------|-----------|-------------|------|---------|
| Ghostty ("Unnamed") | 17 | 494 | 3198ms | ✓ | - | ✓ |
| vicinae | 2 | 265 | 1339ms | - | - | ✓ |
| waybar | 1 | 33 | 49ms | ✓ | ✓ | ✓ |
| xdg-desktop-portal-gtk | 0 | 0 | 0.5ms | - | - | - |
| **TOTAL** | 20 | 792 | 4586ms | | | |

### App-Specific Notes

**Ghostty Terminal**
- Registers as "Unnamed" app (accessibility name not set)
- Window titles exposed (terminal titles like "codex", "btop")
- No text interface (expected - TUI apps don't expose terminal buffer)
- Coordinates available but all show (0,0) origin
- Actions exposed on buttons/controls

**waybar (GTK)**
- Full AT-SPI coverage: coordinates, text, actions
- Fast enumeration (49ms for 33 elements)
- Good example of GTK accessibility working well

**Firefox**
- NOT visible to AT-SPI despite running
- Needs `MOZ_USE_XINPUT2=1` and/or restart with accessibility enabled
- Firefox requires explicit enablement in about:config (`accessibility.force_disabled = 0`)

**vicinae (Launcher)**
- Elements exposed but coordinates show (0,0)
- May be due to offscreen/hidden state

## Query Performance

### Full Enumeration
- **Total time**: 4586ms for 792 elements
- **Rate**: ~173 elements/second
- Ghostty enumeration is slow (3.2s for 494 elements)

### Find by Role (button)
- **Average**: 1704ms
- **Min**: 1407ms
- **Max**: 1854ms
- 5 iterations across all apps

## Roles Discovered

10 unique roles found:
- button, filler, frame, grouping, label
- layered pane, panel, progress bar, scroll bar, text

## Key Findings

1. **Coverage is partial**: Only GTK apps fully expose AT-SPI. Firefox needs explicit config.

2. **Performance is moderate**: Full enumeration takes seconds, not milliseconds. Caching recommended for repeated queries.

3. **Coordinates unreliable**: Some apps report (0,0) for all elements. May be Wayland/compositor issue.

4. **Terminal text inaccessible**: Ghostty and other terminals don't expose buffer contents via Text interface (expected limitation).

5. **App identification**: Some apps (Ghostty) don't set accessibility application name, appearing as "Unnamed".

## Recommendations

1. **Cache query results** when doing repeated lookups
2. **Filter by window first** before deep element searches
3. **Don't rely on coordinates** for click automation - use actions instead
4. **Enable Firefox accessibility** via about:config if needed
5. **Use visual capture (niri-window-capture)** as complement for apps with poor AT-SPI support

## Next Steps

- Test with Firefox accessibility enabled
- Test Electron apps (VS Code) when available
- Measure memory overhead of pyatspi queries
- Consider async/parallel enumeration for large element counts
