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-1487GitHub issuePublicFixed

Keybindings cache key includes volatile "active keymap" state, causing repeated 540ms cold rebuilds

Reported by estradanic · filed Aug 25, 2026 · open at source

In the audited area (menu) — 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?
AreaIn the audited areamenu· 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: in the audited area (menu) — 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

Keybindings cache key includes volatile "active keymap" state, causing repeated 540ms cold rebuildsrevision 1 · captured 2026-09-28 21:24 UTC via poll

Summary

omarchy-menu-keybindings rebuilds its keybindings cache from scratch on many invocations because the cache key includes a line from hyprctl devices that changes whenever an Omarchy menu holds keyboard focus. Each rebuild takes about 540ms, and each successful refresh deletes caches stored under other keys. The result is a keybindings menu that opens in 300-500ms on nearly every press.

System details

  • Omarchy 4.0.0-1
  • Hyprland 0.56.2 (efb5099)
  • Kernel 7.1.8-arch1-3
  • CPU: Intel i7-1360P, GPU: Iris Xe
  • Debug log: not available; omarchy debug is listed in omarchy --help output but the dispatcher rejects it ("Unknown Omarchy command") in this version

Steps to reproduce

  1. Open the keybindings menu with Super+K and time it.
  2. While any Omarchy menu or popup that takes exclusive keyboard focus is open (for example the root menu on Super+Space), press Super+K again. This press computes its cache key while Hyprland reports no active keymap.
  3. Close everything, then press Super+K again.

Observed: steps 2 and 3 are both slow (~500ms). Repeating this pattern keeps every press slow. On my system this happened often enough in normal use that I measured no cache hits at all across repeated presses before investigating.

Root cause

The script derives the cache filename from a content hash:

keybindings_cache_key() {
  {
    printf 'v11\n'
    hyprctl devices 2>/dev/null | grep -F 'active keymap:'
    hyprctl binds 2>/dev/null
  } | sha256sum | awk '{ print $1 }'
}

While an Omarchy layer menu has exclusive keyboard focus, Hyprland stops reporting the active keymap for the keyboard. Diffing hyprctl devices | grep 'active keymap:' plus hyprctl binds between the two states shows exactly one difference: the active keymap: English (US) line is present when no menu has focus and absent when one does. So there are two possible cache keys at any moment, and the state flips every time a menu opens.

The deletion makes it worse. refresh_keybindings_cache() runs:

find "$cache_dir" -maxdepth 1 -type f -name 'keybindings-*.records' ! -name "$cache_name" -delete

A rebuild performed while a menu has focus writes the "focused" variant of the cache and deletes the "normal" variant. The next press in the normal state misses again, rebuilds, and deletes the focused variant in turn. Every other invocation pays the full cold build.

I also found about 40 orphaned keybindings.XXXXXX temp files in ~/.cache/omarchy/, consistent with interrupted or racing refreshes after repeated presses during slow builds.

Measured impact

Timings on this machine:

  • Cold rebuild of the records file: ~540ms (build_lua_bind_cache spawns a Lua interpreter that dofiles the full Hyprland config, plus xkbcli compile-keymap and several awk/sort passes)
  • Warm read: ~21-26ms
  • End to end, pressing Super+K with a warm cache: ~310ms until the menu window maps; after a cold rebuild: 800ms+

Monitoring the cache directory during real presses confirmed the flip: the computed hash alternates between two values correlated exactly with menu focus state.

Suggested fix

Exclude the volatile input from the hash, for example by hashing only hyprctl binds and bumping the version marker so existing caches do not collide:

keybindings_cache_key() {
  {
    printf 'v12\n'
    hyprctl binds 2>/dev/null
  } | sha256sum | awk '{ print $1 }'
}

Trade-off: changing the keyboard layout would no longer invalidate the cache on its own. If layout changes matter for display resolution, a more stable signal could be used instead, such as hashing the keymap only when hyprctl binds changes, or storing the keymap as a separate validity check that does not participate in the filename.

Independently, refresh_keybindings_cache() deleting caches under all other keys turns any transient mismatch into a ping-pong. Keeping sibling caches until they age out would make the system self-healing even if some other volatile input slips in later.

I verified the fix locally by overriding the SUPER+K binding with a patched copy of the script (hash excludes hyprctl devices, marker bumped). After the patch, extended use including rapid double presses and pressing K while another menu was open produced zero cache writes and steady ~20ms script time.

Secondary observation: warm-path latency

With caching fully warm, opening the keybindings menu still takes ~310ms from keypress to window mapped. A control test with omarchy-menu-select 'TinyTest' alpha beta gamma showed ~190ms for a three-row menu, so roughly 190ms is fixed cost in the select pipeline (bash wrapper, jq payload encoding, IPC into omarchy-shell, layer surface creation) and roughly 120ms scales with the ~200 rows in the keybindings payload. No animations are involved; the menu layer rule already sets no_anim = true. Filing this here since the numbers came out of the same investigation, but happy to move it to a separate issue if you prefer.

View raw text
### Summary

`omarchy-menu-keybindings` rebuilds its keybindings cache from scratch on many invocations because the cache key includes a line from `hyprctl devices` that changes whenever an Omarchy menu holds keyboard focus. Each rebuild takes about 540ms, and each successful refresh deletes caches stored under other keys. The result is a keybindings menu that opens in 300-500ms on nearly every press.

### System details

- Omarchy 4.0.0-1
- Hyprland 0.56.2 (efb5099)
- Kernel 7.1.8-arch1-3
- CPU: Intel i7-1360P, GPU: Iris Xe
- Debug log: not available; `omarchy debug` is listed in `omarchy --help` output but the dispatcher rejects it ("Unknown Omarchy command") in this version

### Steps to reproduce

1. Open the keybindings menu with Super+K and time it.
2. While any Omarchy menu or popup that takes exclusive keyboard focus is open (for example the root menu on Super+Space), press Super+K again. This press computes its cache key while Hyprland reports no active keymap.
3. Close everything, then press Super+K again.

Observed: steps 2 and 3 are both slow (~500ms). Repeating this pattern keeps every press slow. On my system this happened often enough in normal use that I measured no cache hits at all across repeated presses before investigating.

### Root cause

The script derives the cache filename from a content hash:

```bash
keybindings_cache_key() {
  {
    printf 'v11\n'
    hyprctl devices 2>/dev/null | grep -F 'active keymap:'
    hyprctl binds 2>/dev/null
  } | sha256sum | awk '{ print $1 }'
}
```

While an Omarchy layer menu has exclusive keyboard focus, Hyprland stops reporting the active keymap for the keyboard. Diffing `hyprctl devices | grep 'active keymap:'` plus `hyprctl binds` between the two states shows exactly one difference: the `active keymap: English (US)` line is present when no menu has focus and absent when one does. So there are two possible cache keys at any moment, and the state flips every time a menu opens.

The deletion makes it worse. `refresh_keybindings_cache()` runs:

```bash
find "$cache_dir" -maxdepth 1 -type f -name 'keybindings-*.records' ! -name "$cache_name" -delete
```

A rebuild performed while a menu has focus writes the "focused" variant of the cache and deletes the "normal" variant. The next press in the normal state misses again, rebuilds, and deletes the focused variant in turn. Every other invocation pays the full cold build.

I also found about 40 orphaned `keybindings.XXXXXX` temp files in `~/.cache/omarchy/`, consistent with interrupted or racing refreshes after repeated presses during slow builds.

### Measured impact

Timings on this machine:

- Cold rebuild of the records file: ~540ms (`build_lua_bind_cache` spawns a Lua interpreter that dofiles the full Hyprland config, plus `xkbcli compile-keymap` and several awk/sort passes)
- Warm read: ~21-26ms
- End to end, pressing Super+K with a warm cache: ~310ms until the menu window maps; after a cold rebuild: 800ms+

Monitoring the cache directory during real presses confirmed the flip: the computed hash alternates between two values correlated exactly with menu focus state.

### Suggested fix

Exclude the volatile input from the hash, for example by hashing only `hyprctl binds` and bumping the version marker so existing caches do not collide:

```bash
keybindings_cache_key() {
  {
    printf 'v12\n'
    hyprctl binds 2>/dev/null
  } | sha256sum | awk '{ print $1 }'
}
```

Trade-off: changing the keyboard layout would no longer invalidate the cache on its own. If layout changes matter for display resolution, a more stable signal could be used instead, such as hashing the keymap only when `hyprctl binds` changes, or storing the keymap as a separate validity check that does not participate in the filename.

Independently, `refresh_keybindings_cache()` deleting caches under all other keys turns any transient mismatch into a ping-pong. Keeping sibling caches until they age out would make the system self-healing even if some other volatile input slips in later.

I verified the fix locally by overriding the SUPER+K binding with a patched copy of the script (hash excludes `hyprctl devices`, marker bumped). After the patch, extended use including rapid double presses and pressing K while another menu was open produced zero cache writes and steady ~20ms script time.

### Secondary observation: warm-path latency

With caching fully warm, opening the keybindings menu still takes ~310ms from keypress to window mapped. A control test with `omarchy-menu-select 'TinyTest' alpha beta gamma` showed ~190ms for a three-row menu, so roughly 190ms is fixed cost in the select pipeline (bash wrapper, jq payload encoding, IPC into omarchy-shell, layer surface creation) and roughly 120ms scales with the ~200 rows in the keybindings payload. No animations are involved; the menu layer rule already sets `no_anim = true`. Filing this here since the numbers came out of the same investigation, but happy to move it to a separate issue if you prefer.

Same defect, also reported as

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

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: in the audited area (menu)
  • Decided by agents · verified: matches no known issue

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