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-1793GitHub issuePublicDecided· Out of scope

Quattro: "selection" layer namespace hook steals RETURN/TAB/arrows from any layer-shell client using that namespace (breaks wl-kbptr)

Reported by ispentanhouronthis · filed Aug 16, 2026 · open at source

Decided: Out of scope — decided by agents · verified 4 days ago.

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?
AreaOutside the audited area· 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?
Decided by agents and verified by a second, independent agent — see the decision.

Original report

Quattro: "selection" layer namespace hook steals RETURN/TAB/arrows from any layer-shell client using that namespace (breaks wl-kbptr)revision 1 · captured 2026-09-28 21:29 UTC via poll

What happened

default/hypr/bindings/utilities.lua registers global Hyprland keybinds whenever any layer surface with the namespace selection opens:

hl.on("layer.opened", function(layer)
  if layer.namespace == "selection" then
    ...
    hl.bind("RETURN", hl.dsp.exec_cmd("omarchy-capture-region --take-window"), ...)
    hl.bind("CTRL + RETURN", ...)
    hl.bind("TAB", ...) / hl.bind("CTRL + TAB", ...)
    hl.bind("LEFT"/"RIGHT"/"UP"/"DOWN", ...)

selection is not unique to slurp. It is a generic namespace that other layer-shell clients also use — `wl-kbptr` (keyboard-driven mouse pointer) hardcodes it in src/main.c:

state.wl_layer_surface = zwlr_layer_shell_v1_get_layer_surface(
    state.wl_layer_shell, state.wl_surface, ...,
    ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "selection"
);

Because Hyprland keybinds take priority over key delivery to the focused client, opening wl-kbptr silently steals RETURN, CTRL+RETURN, TAB, CTRL+TAB and all four arrow keys from it. wl-kbptr uses RETURN to confirm a selection, so the overlay appears and targets correctly but can never be confirmed — no click is ever emitted. Each RETURN press instead fires omarchy-capture-region --take-window with no picker running.

There is no error and nothing in the logs; it just looks like the app is broken.

Expected

The capture-region keybinds should only be active while omarchy-capture-region's own picker is on screen, not whenever any client happens to name its layer selection.

Steps to reproduce

  1. omarchy pkg aur add wl-kbptr (or any layer-shell client using the selection namespace)
  2. Run wl-kbptr
  3. Type a tile label to pick a target — the pointer moves correctly
  4. Press RETURN to confirm — nothing happens, no click is emitted
  5. Escape still cancels; letters still work

Workaround: press space instead of RETURN (wl-kbptr accepts both).

Evidence

Correlating raw evdev against the Wayland protocol trace confirms the compositor is swallowing the key, not the client dropping it.

/dev/input/event* (hardware) during one wl-kbptr session:

13:43:05.363  21 Y      press
13:43:05.659  50 M      press
13:43:05.946  28 ENTER  press      <-- pressed 6x total
13:43:06.956  38 L      press
13:43:07.635  28 ENTER  press
13:43:08.056  28 ENTER  press
...
13:43:09.730   1 ESC    press

WAYLAND_DEBUG=1 wl-kbptr for the same session:

wl_keyboard#14.key(4973, 2745269, 21, 1)   <-- Y
wl_keyboard#14.key(4975, 2745565, 50, 1)   <-- M
wl_keyboard#14.key(4977, 2746862, 38, 1)   <-- L
wl_keyboard#14.key(4979, 2749636,  1, 1)   <-- ESC

Every KEY_ENTER (evdev 28) is missing. Y, M, L and ESC are all delivered normally.

The client-side effect: wl-kbptr only ever emits the preview move, never a button —

zwlr_virtual_pointer_v1#22.motion_absolute(0, 1038, 16, 1600, 900)
zwlr_virtual_pointer_v1#22.frame()

hyprctl binds shows no bare RETURN bind when no selection layer is open, and shows the capture binds while one is — which matches the hook's lifecycle exactly.

Suggested fix

Gate the handler on omarchy-capture-region actually running rather than on the namespace alone. The script already maintains state in $XDG_RUNTIME_DIR (omarchy-capture-region-fullscreen, omarchy-capture-region-window), so a marker/PID it owns for the duration of the pick could be checked in the layer.opened callback before binding anything.

Matching on the layer's owning client (pid/exe) would be more precise still, if that is exposed to the Lua event.

System

  • Omarchy 4.0.0-1 (omarchy-settings 4.0.0-1), upgraded from 3.8.5
  • Hyprland 0.56.2-1
  • Arch Linux, kernel 7.1.8-arch1-3
  • ASUS ROG Zephyrus G15 GA503RM — AMD Ryzen 7 6800HS, Radeon 680M iGPU (integrated mode via supergfxctl), NVIDIA GA106 dGPU
  • wl-kbptr 0.4.1
View raw text
## What happened

`default/hypr/bindings/utilities.lua` registers global Hyprland keybinds whenever **any** layer surface with the namespace `selection` opens:

```lua
hl.on("layer.opened", function(layer)
  if layer.namespace == "selection" then
    ...
    hl.bind("RETURN", hl.dsp.exec_cmd("omarchy-capture-region --take-window"), ...)
    hl.bind("CTRL + RETURN", ...)
    hl.bind("TAB", ...) / hl.bind("CTRL + TAB", ...)
    hl.bind("LEFT"/"RIGHT"/"UP"/"DOWN", ...)
```

`selection` is not unique to slurp. It is a generic namespace that other layer-shell clients also use — [`wl-kbptr`](https://github.com/moverest/wl-kbptr) (keyboard-driven mouse pointer) hardcodes it in `src/main.c`:

```c
state.wl_layer_surface = zwlr_layer_shell_v1_get_layer_surface(
    state.wl_layer_shell, state.wl_surface, ...,
    ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "selection"
);
```

Because Hyprland keybinds take priority over key delivery to the focused client, opening wl-kbptr silently steals `RETURN`, `CTRL+RETURN`, `TAB`, `CTRL+TAB` and all four arrow keys from it. wl-kbptr uses `RETURN` to confirm a selection, so the overlay appears and targets correctly but **can never be confirmed** — no click is ever emitted. Each `RETURN` press instead fires `omarchy-capture-region --take-window` with no picker running.

There is no error and nothing in the logs; it just looks like the app is broken.

## Expected

The capture-region keybinds should only be active while `omarchy-capture-region`'s own picker is on screen, not whenever any client happens to name its layer `selection`.

## Steps to reproduce

1. `omarchy pkg aur add wl-kbptr` (or any layer-shell client using the `selection` namespace)
2. Run `wl-kbptr`
3. Type a tile label to pick a target — the pointer moves correctly
4. Press `RETURN` to confirm — nothing happens, no click is emitted
5. `Escape` still cancels; letters still work

Workaround: press `space` instead of `RETURN` (wl-kbptr accepts both).

## Evidence

Correlating raw evdev against the Wayland protocol trace confirms the compositor is swallowing the key, not the client dropping it.

`/dev/input/event*` (hardware) during one wl-kbptr session:

```
13:43:05.363  21 Y      press
13:43:05.659  50 M      press
13:43:05.946  28 ENTER  press      <-- pressed 6x total
13:43:06.956  38 L      press
13:43:07.635  28 ENTER  press
13:43:08.056  28 ENTER  press
...
13:43:09.730   1 ESC    press
```

`WAYLAND_DEBUG=1 wl-kbptr` for the same session:

```
wl_keyboard#14.key(4973, 2745269, 21, 1)   <-- Y
wl_keyboard#14.key(4975, 2745565, 50, 1)   <-- M
wl_keyboard#14.key(4977, 2746862, 38, 1)   <-- L
wl_keyboard#14.key(4979, 2749636,  1, 1)   <-- ESC
```

Every `KEY_ENTER` (evdev 28) is missing. `Y`, `M`, `L` and `ESC` are all delivered normally.

The client-side effect: wl-kbptr only ever emits the preview move, never a button —

```
zwlr_virtual_pointer_v1#22.motion_absolute(0, 1038, 16, 1600, 900)
zwlr_virtual_pointer_v1#22.frame()
```

`hyprctl binds` shows no bare `RETURN` bind when no `selection` layer is open, and shows the capture binds while one is — which matches the hook's lifecycle exactly.

## Suggested fix

Gate the handler on `omarchy-capture-region` actually running rather than on the namespace alone. The script already maintains state in `$XDG_RUNTIME_DIR` (`omarchy-capture-region-fullscreen`, `omarchy-capture-region-window`), so a marker/PID it owns for the duration of the pick could be checked in the `layer.opened` callback before binding anything.

Matching on the layer's owning client (pid/exe) would be more precise still, if that is exposed to the Lua event.

## System

- Omarchy 4.0.0-1 (`omarchy-settings` 4.0.0-1), upgraded from 3.8.5
- Hyprland 0.56.2-1
- Arch Linux, kernel 7.1.8-arch1-3
- ASUS ROG Zephyrus G15 GA503RM — AMD Ryzen 7 6800HS, Radeon 680M iGPU (integrated mode via supergfxctl), NVIDIA GA106 dGPU
- wl-kbptr 0.4.1

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

Not linked to any known issue, other report or change yet.

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.

  • Out of scopeDecided by agents · verified · 2026-10-09 04:18 UTC