Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA 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.
Shell exposes no accessibility information: no roles or names on any surface
Reported by rmcdavid · filed Sep 15, 2026 · open at source
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 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
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/shellNo 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 aBorderSurface plus a MouseArea, which means clickable things are not buttons
to assistive technology.
Ui/ConfirmDialog.qml builds its Cancel and confirm buttons as a bareBorderSurface 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 byToolkitName 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 asquickshell -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.