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.
Numpad digits don't type in Omarchy Menu / Reminder Menu (NumLock keysym desync)
Reported by Exp1iots · filed Aug 25, 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.
- 2 · What does it affect?
- 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) — 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
What happened
Numpad digit keys don't type in several first-party Quickshell panels, even though the numpad works correctly everywhere else (terminal, browser, VS Code):
- Omarchy Menu — can't type numpad digits into the search/filter box
- Reminder Menu (
omarchy reminder -i) — can't enter a duration with the numpad - Likely other Qt/QML panels that accept digit input (e.g. Clock alarm time entry, Wi-Fi passphrase entry) share the same code pattern and are probably affected too, though I didn't confirm those directly
Expected
Numpad digits should insert into the filter/text field the same way regular number-row digits do.
Root cause (confirmed with wev)
Even though NumLock is genuinely locked at the compositor level (wl_keyboard.modifiers reports locked: Mod2), physical numpad key presses still resolve to the non-NumLock (navigation) keysym:
key: 87 (KP1) -> sym: KP_End (should be KP_1 with NumLock locked)
key: 88 (KP2) -> sym: KP_Down (should be KP_2)
key: 89 (KP3) -> sym: KP_Next (should be KP_3)
key: 90 (KP0) -> sym: KP_Insert (should be KP_0)
key: 83 (KP4) -> sym: KP_Left (should be KP_4)
key: 84 (KP5) -> sym: KP_Begin (should be KP_5)
key: 85 (KP6) -> sym: KP_Right (should be KP_6)
key: 79 (KP7) -> sym: KP_Home (should be KP_7)
key: 80 (KP8) -> sym: KP_Up (should be KP_8)
key: 81 (KP9) -> sym: KP_Prior (should be KP_9)modifiers event at the same time:
depressed: 00000000
latched: 00000000
locked: 00000010: Mod2This matches a known, still-open Hyprland issue where NumLock's locked-modifier state and keypad keysym-level resolution get out of sync (hyprwm/Hyprland#8288, hyprwm/Hyprland#6573, hyprwm/Hyprland discussion #10438). Toggling NumLock again (even synthetically via ydotool key 69:1 69:0) did not resync it in my testing.
In Qt, these navigation keysyms arrive as Qt.Key_Left/Right/Up/Down/Home/End/PageUp/PageDown/Insert/Clear with Qt.KeypadModifier set and an empty `event.text`. Two things then go wrong in the shell's own key handlers:
plugins/menu/Menu.qml'sKeys.onPressedhas explicit branches forQt.Key_Left/Right/Up/Down/PageUp/PageDownthat treat them as list-navigation/backspace-to-go-back, so a numpad digit gets consumed as a navigation command before it ever reaches the text-filter branch.plugins/reminders/ReminderFlow.qml'sKeys.onPressedhas no navigation branches, but its final filter branch only acceptsevent.text.length === 1, which is empty for these keysyms — so the keypress is silently dropped.
Both handlers are independent, hand-rolled Keys.onPressed blocks (not routed through the shared Ui/PanelKeyCatcher.qml dispatcher), so this can't be fixed in one shared place today — any current/future panel with digit entry needs the same guard individually. It may be worth adding a shared Util.qml helper (e.g. Util.keypadDigit(event)) that all of these call, so there's one place to maintain this workaround, in addition to (or in lieu of, since it's a compositor bug) getting a real fix from Hyprland.
Verified workaround
Adding this near the top of the affected Keys.onPressed handlers, before any navigation-key branches, fixes it for both Menu and Reminders (tested locally):
if (event.modifiers & Qt.KeypadModifier) {
const kpDigit = ({
[Qt.Key_Home]: "7", [Qt.Key_Up]: "8", [Qt.Key_PageUp]: "9",
[Qt.Key_Left]: "4", [Qt.Key_Clear]: "5", [Qt.Key_Right]: "6",
[Qt.Key_End]: "1", [Qt.Key_Down]: "2", [Qt.Key_PageDown]: "3",
[Qt.Key_Insert]: "0"
})[event.key]
if (kpDigit !== undefined) {
root.setFilter(root.filterText + kpDigit)
event.accepted = true
return
}
}Steps to reproduce
- On a laptop with an embedded Fn-numpad (or possibly any keyboard hitting the underlying Hyprland NumLock desync), enable the numpad and confirm NumLock is on (digits work fine in a browser/terminal)
- Open Omarchy Menu (
omarchy menu) and type a numpad digit — nothing appears, or the selection cursor moves instead - Open the Reminder Menu (
omarchy reminder -i) and try to type a duration with the numpad — nothing appears
System info
- Omarchy: 4.0.0-1
- Hyprland: 0.56.2
- Keyboard: internal laptop keyboard (
at-translated-set-2-keyboardinhyprctl devices) with an embedded Fn-activated numpad;input:numlock_by_defaultistrue(Omarchy default)
View raw text
## What happened
Numpad digit keys don't type in several first-party Quickshell panels, even though the numpad works correctly everywhere else (terminal, browser, VS Code):
- **Omarchy Menu** — can't type numpad digits into the search/filter box
- **Reminder Menu** (`omarchy reminder -i`) — can't enter a duration with the numpad
- Likely other Qt/QML panels that accept digit input (e.g. Clock alarm time entry, Wi-Fi passphrase entry) share the same code pattern and are probably affected too, though I didn't confirm those directly
## Expected
Numpad digits should insert into the filter/text field the same way regular number-row digits do.
## Root cause (confirmed with `wev`)
Even though NumLock is genuinely locked at the compositor level (`wl_keyboard.modifiers` reports `locked: Mod2`), physical numpad key presses still resolve to the *non*-NumLock (navigation) keysym:
```
key: 87 (KP1) -> sym: KP_End (should be KP_1 with NumLock locked)
key: 88 (KP2) -> sym: KP_Down (should be KP_2)
key: 89 (KP3) -> sym: KP_Next (should be KP_3)
key: 90 (KP0) -> sym: KP_Insert (should be KP_0)
key: 83 (KP4) -> sym: KP_Left (should be KP_4)
key: 84 (KP5) -> sym: KP_Begin (should be KP_5)
key: 85 (KP6) -> sym: KP_Right (should be KP_6)
key: 79 (KP7) -> sym: KP_Home (should be KP_7)
key: 80 (KP8) -> sym: KP_Up (should be KP_8)
key: 81 (KP9) -> sym: KP_Prior (should be KP_9)
```
modifiers event at the same time:
```
depressed: 00000000
latched: 00000000
locked: 00000010: Mod2
```
This matches a known, still-open Hyprland issue where NumLock's locked-modifier state and keypad keysym-level resolution get out of sync (hyprwm/Hyprland#8288, hyprwm/Hyprland#6573, hyprwm/Hyprland discussion #10438). Toggling NumLock again (even synthetically via `ydotool key 69:1 69:0`) did not resync it in my testing.
In Qt, these navigation keysyms arrive as `Qt.Key_Left/Right/Up/Down/Home/End/PageUp/PageDown/Insert/Clear` with `Qt.KeypadModifier` set and an **empty `event.text`**. Two things then go wrong in the shell's own key handlers:
1. `plugins/menu/Menu.qml`'s `Keys.onPressed` has explicit branches for `Qt.Key_Left/Right/Up/Down/PageUp/PageDown` that treat them as list-navigation/backspace-to-go-back, so a numpad digit gets consumed as a navigation command before it ever reaches the text-filter branch.
2. `plugins/reminders/ReminderFlow.qml`'s `Keys.onPressed` has no navigation branches, but its final filter branch only accepts `event.text.length === 1`, which is empty for these keysyms — so the keypress is silently dropped.
Both handlers are independent, hand-rolled `Keys.onPressed` blocks (not routed through the shared `Ui/PanelKeyCatcher.qml` dispatcher), so this can't be fixed in one shared place today — any current/future panel with digit entry needs the same guard individually. It may be worth adding a shared `Util.qml` helper (e.g. `Util.keypadDigit(event)`) that all of these call, so there's one place to maintain this workaround, in addition to (or in lieu of, since it's a compositor bug) getting a real fix from Hyprland.
## Verified workaround
Adding this near the top of the affected `Keys.onPressed` handlers, before any navigation-key branches, fixes it for both Menu and Reminders (tested locally):
```qml
if (event.modifiers & Qt.KeypadModifier) {
const kpDigit = ({
[Qt.Key_Home]: "7", [Qt.Key_Up]: "8", [Qt.Key_PageUp]: "9",
[Qt.Key_Left]: "4", [Qt.Key_Clear]: "5", [Qt.Key_Right]: "6",
[Qt.Key_End]: "1", [Qt.Key_Down]: "2", [Qt.Key_PageDown]: "3",
[Qt.Key_Insert]: "0"
})[event.key]
if (kpDigit !== undefined) {
root.setFilter(root.filterText + kpDigit)
event.accepted = true
return
}
}
```
## Steps to reproduce
1. On a laptop with an embedded Fn-numpad (or possibly any keyboard hitting the underlying Hyprland NumLock desync), enable the numpad and confirm NumLock is on (digits work fine in a browser/terminal)
2. Open Omarchy Menu (`omarchy menu`) and type a numpad digit — nothing appears, or the selection cursor moves instead
3. Open the Reminder Menu (`omarchy reminder -i`) and try to type a duration with the numpad — nothing appears
## System info
- Omarchy: 4.0.0-1
- Hyprland: 0.56.2
- Keyboard: internal laptop keyboard (`at-translated-set-2-keyboard` in `hyprctl devices`) with an embedded Fn-activated numpad; `input:numlock_by_default` is `true` (Omarchy default)
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/14662· confirmed
- Related PRpr/8023· 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)
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.