Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-513GitHub issuePublicReceived

Shell exposes no accessibility information: no roles or names on any surface

Reported by rmcdavid · filed Sep 15, 2026 · open at source

Partly in the audited area (menu, lock) — decided by agents · verified. Not validated yet.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
AreaPartly in the audited areamenulock· Decided by agents · verified
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. So far: partly in the audited area (menu, lock) — decided by agents · verified; matches no known issue — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.

Original report

Shell exposes no accessibility information: no roles or names on any surfacerevision 1 · captured 2026-09-28 21:23 UTC via poll
Up front: I am a hobbyist, not a professional software developer. This report was researched and written with the help of an AI assistant while I was building a third-party shell plugin. I have tried to make it accurate and to include the evidence behind every claim, but please read the technical details with that in mind. If anything here is wrong or unhelpful, tell me and I will correct it or close it.

What happens

The Omarchy shell sets no accessibility roles or names on any of its surfaces.
With an assistive technology running and Qt's AT-SPI bridge active, the bar,
application menu, clipboard picker, emoji picker, notifications, OSD, lock
screen and every panel publish an item tree with no roles and no names, so a
screen-reader user cannot identify or operate any part of the shell.

What I expected

Interactive surfaces carry Accessible.role and Accessible.name, which Qt
Quick supports out of the box through the Accessible attached property, so
assistive technology can name and operate them.

How to reproduce

grep -rn 'Accessible\.' /usr/share/omarchy/shell

No output, exit 1. That is across 102 .qml files and 34,914 lines.

Evidence

The UI kit is hand-built, which is a perfectly reasonable choice, but it means
no component inherits a default role from Qt Quick Controls. Of the 33
components in /usr/share/omarchy/shell/Ui/, only two have a Controls type as
their root:

ComponentRoot type
TextField.qmlTextField (Controls)
PanelToolTip.qmlToolTip (Controls)
Button.qmlBorderSurface
Dropdown.qml, MultiSelect.qml, SearchableDropdown.qmlItem
NumberField.qmlColumn

Five of these import QtQuick.Controls for internal use but do not derive from
it, so they get no default role. In particular Ui/Button.qml is a
BorderSurface plus a MouseArea, which means clickable things are not buttons
to assistive technology.

Ui/ConfirmDialog.qml builds its Cancel and confirm buttons as a bare
BorderSurface containing a Text, with no accessibility properties. That one
matters beyond the shell: a third-party plugin that uses ConfirmDialog cannot
annotate those buttons from outside, so the plugin cannot fix it either.

Why I am suggesting it be fixed at the source

A plugin can label its own surfaces and nothing else. Roles and names on the
shell's own components, and especially on the shared Ui/ kit where one change
covers every consumer, would make every plugin's surfaces reachable at once.

One important caveat, so nobody chases the wrong thing first

While investigating this I found that **nothing a Quickshell window declares
reaches AT-SPI at all on my machine**, so adding roles and names here would not
be observable until that is resolved. Measured with the bridge active, checking
window mapping from the compositor, and selecting the bus connection by
ToolkitName rather than by process name:

What was runWindow it createsChildren published
qml probe.qml (plain Qt)xdg-toplevel1
quickshell with a PanelWindowlayer surface0
quickshell with a FloatingWindowxdg-toplevel0

So Qt's bridge works fine on this system; no Quickshell window publishes a
tree, and it is not specific to layer-shell surfaces. I am reporting that
separately. I mention it here only so this issue is not judged by testing it
before that is fixed.

A related gotcha for anyone debugging accessibility on Omarchy

envs.lua sets QT_QPA_PLATFORMTHEME=gtk3 for the session. With the bridge
active, the shell process then has two connections on the accessibility
bus, both reporting the process name quickshell:

ConnectionToolkitNameVersionChildCount
first listedgtk3.24.520
secondQt6.11.20

The GTK one is empty and is listed first, so anyone diagnosing this who selects
by name rather than by ToolkitName will read the wrong connection and draw
the wrong conclusion. It cost me a day. Not necessarily a bug, but worth
knowing about.

System details

Arch Linux, Hyprland session. quickshell 0.3.1-1, qt6-base 6.11.2-3,
at-spi2-core 2.60.6-1. Shell launched by
/usr/share/omarchy/bin/omarchy-launch-shell as
quickshell -n -p /usr/share/omarchy/shell. No screen reader installed, so
everything above was observed through the AT-SPI bus directly rather than
through a reader.

View raw text
> **Up front:** I am a hobbyist, not a professional software developer. This
> report was researched and written with the help of an AI assistant while I
> was building a third-party shell plugin. I have tried to make it accurate
> and to include the evidence behind every claim, but please read the
> technical details with that in mind. If anything here is wrong or unhelpful,
> tell me and I will correct it or close it.

## What happens

The Omarchy shell sets no accessibility roles or names on any of its surfaces.
With an assistive technology running and Qt's AT-SPI bridge active, the bar,
application menu, clipboard picker, emoji picker, notifications, OSD, lock
screen and every panel publish an item tree with no roles and no names, so a
screen-reader user cannot identify or operate any part of the shell.

## What I expected

Interactive surfaces carry `Accessible.role` and `Accessible.name`, which Qt
Quick supports out of the box through the `Accessible` attached property, so
assistive technology can name and operate them.

## How to reproduce

```
grep -rn 'Accessible\.' /usr/share/omarchy/shell
```

No output, exit 1. That is across 102 `.qml` files and 34,914 lines.

## Evidence

The UI kit is hand-built, which is a perfectly reasonable choice, but it means
no component inherits a default role from Qt Quick Controls. Of the 33
components in `/usr/share/omarchy/shell/Ui/`, only two have a Controls type as
their root:

| Component | Root type |
|---|---|
| `TextField.qml` | `TextField` (Controls) |
| `PanelToolTip.qml` | `ToolTip` (Controls) |
| `Button.qml` | `BorderSurface` |
| `Dropdown.qml`, `MultiSelect.qml`, `SearchableDropdown.qml` | `Item` |
| `NumberField.qml` | `Column` |

Five of these import `QtQuick.Controls` for internal use but do not derive from
it, so they get no default role. In particular `Ui/Button.qml` is a
`BorderSurface` plus a MouseArea, which means clickable things are not buttons
to assistive technology.

`Ui/ConfirmDialog.qml` builds its Cancel and confirm buttons as a bare
`BorderSurface` containing a `Text`, with no accessibility properties. That one
matters beyond the shell: a third-party plugin that uses `ConfirmDialog` cannot
annotate those buttons from outside, so the plugin cannot fix it either.

## Why I am suggesting it be fixed at the source

A plugin can label its own surfaces and nothing else. Roles and names on the
shell's own components, and especially on the shared `Ui/` kit where one change
covers every consumer, would make every plugin's surfaces reachable at once.

## One important caveat, so nobody chases the wrong thing first

While investigating this I found that **nothing a Quickshell window declares
reaches AT-SPI at all on my machine**, so adding roles and names here would not
be observable until that is resolved. Measured with the bridge active, checking
window mapping from the compositor, and selecting the bus connection by
`ToolkitName` rather than by process name:

| What was run | Window it creates | Children published |
|---|---|---|
| `qml probe.qml` (plain Qt) | xdg-toplevel | 1 |
| `quickshell` with a `PanelWindow` | layer surface | 0 |
| `quickshell` with a `FloatingWindow` | xdg-toplevel | 0 |

So Qt's bridge works fine on this system; no Quickshell window publishes a
tree, and it is not specific to layer-shell surfaces. I am reporting that
separately. I mention it here only so this issue is not judged by testing it
before that is fixed.

## A related gotcha for anyone debugging accessibility on Omarchy

`envs.lua` sets `QT_QPA_PLATFORMTHEME=gtk3` for the session. With the bridge
active, the shell process then has **two** connections on the accessibility
bus, both reporting the process name `quickshell`:

| Connection | ToolkitName | Version | ChildCount |
|---|---|---|---|
| first listed | `gtk` | 3.24.52 | 0 |
| second | `Qt` | 6.11.2 | 0 |

The GTK one is empty and is listed first, so anyone diagnosing this who selects
by name rather than by `ToolkitName` will read the wrong connection and draw
the wrong conclusion. It cost me a day. Not necessarily a bug, but worth
knowing about.

## System details

Arch Linux, Hyprland session. quickshell 0.3.1-1, qt6-base 6.11.2-3,
at-spi2-core 2.60.6-1. Shell launched by
`/usr/share/omarchy/bin/omarchy-launch-shell` as
`quickshell -n -p /usr/share/omarchy/shell`. No screen reader installed, so
everything above was observed through the AT-SPI bus directly rather than
through a reader.

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

  • Related PRpr/13212· confirmed

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

  • Decided by agents · verified: partly in the audited area (menu, lock)
  • Decided by agents · verified: matches no known issue

The outcome (valid, duplicate, not a bug, …) is not decided yet.