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.
Default kb_options breaks Shift in all XWayland apps (Left Shift acts as ShiftLock)
Reported by ids444 · filed Sep 6, 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?
- 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
What happens
Omarchy's default kb_options breaks the Shift key for every XWayland (X11) application. A single tap of Left Shift latches input into a permanently-shifted state: letters come out uppercase and numbers come out as symbols (1 → !), until Shift is pressed again.
Wayland-native clients are unaffected, which is why this is easy to miss — on a default Omarchy install almost everything is Wayland-native. It shows up as soon as you use an XWayland app that does its own keyboard handling (I hit it with the Splashtop Business remote-desktop client, where the broken modifier state is transmitted to the remote machine).
Expected
Left Shift behaves as Shift in X11 apps, as it does in Wayland apps.
Cause
default/hypr/input.lua sets:
local kb_options = "compose:caps,shift:both_capslock_cancel"Because compose:caps takes over the physical Caps Lock key, shift:both_capslock_cancel restores Caps Lock by placing a Caps_Lock keysym on level 2 of both Shift keys:
keycode 50 = Shift_L Caps_Lock Shift_L Caps_Lock
keycode 62 = Shift_R Caps_Lock Shift_R Caps_Lock
keycode 66 = Multi_key Multi_key Multi_key Multi_keyWayland clients consume the xkb keymap directly and evaluate levels correctly. The legacy core-X11 keymap XWayland exposes has no equivalent notion, so when it derives the core modifier map it finds Caps_Lock on keycode 50, assigns that keycode to the lock modifier, and drops it from shift:
$ xmodmap -pm
shift Shift_R (0x3e)
lock Shift_L (0x32)So in X11, Left Shift is a locking key and is no longer a Shift key at all. Since the key bound to lock carries a Shift keysym, the lock behaves as ShiftLock rather than CapsLock — which is consistent with the observed symptom that it shifts numbers too, not just letters. (The mapping above is measured; the ShiftLock-vs-CapsLock reading is my interpretation of why numbers are affected.)
Steps to reproduce
On a default Omarchy install:
sudo pacman -S xorg-xmodmap # not installed by default
xmodmap -pm # runs under XWaylandObserve shift = Shift_R only and lock = Shift_L.
Then, in any XWayland app (e.g. xterm, or any X11 client), tap Left Shift once and type — output is locked to shifted, numbers included.
Workaround / suggested fix
Moving Compose off the Caps Lock key resolves it, because nothing then needs to be smuggled onto the Shift keys — Caps Lock stays a real Caps Lock:
local kb_options = "compose:ralt"Resulting map:
shift Shift_L (0x32), Shift_R (0x3e)
lock Caps_Lock (0x42)
keycode 50 = Shift_L NoSymbol Shift_L
keycode 66 = Caps_Lock NoSymbol Caps_Lock
keycode 108 = Multi_key Multi_key Multi_key Multi_keyThis keeps Compose, keeps a real Caps Lock, and keeps Shift working in both Wayland and X11. The trade-off is that Right Alt no longer acts as Alt/AltGr, which matters for layouts that use AltGr — so compose:menu may be a better default for keyboards that have a Menu key.
One gotcha for anyone testing: if an input method such as fcitx5 is running, it owns the main keyboard (hl-virtual-keyboard-fcitx5) and XWayland takes its keymap from that virtual keyboard. hyprctl reload alone does not update it — the input method has to be restarted before the new keymap reaches XWayland.
System
| Omarchy | 4.0.2-1 |
| Hyprland | 0.56.2 (efb5099) |
| xorg-xwayland | 24.1.13-1 |
| xkeyboard-config | 2.48-1 |
| Kernel | 7.1.9-arch1-2 |
| CPU | AMD Ryzen 7 5800X3D |
| GPU | NVIDIA GeForce RTX 4070 (AD104) |
View raw text
## What happens Omarchy's default `kb_options` breaks the Shift key for **every XWayland (X11) application**. A single tap of Left Shift latches input into a permanently-shifted state: letters come out uppercase *and* numbers come out as symbols (`1` → `!`), until Shift is pressed again. Wayland-native clients are unaffected, which is why this is easy to miss — on a default Omarchy install almost everything is Wayland-native. It shows up as soon as you use an XWayland app that does its own keyboard handling (I hit it with the Splashtop Business remote-desktop client, where the broken modifier state is transmitted to the remote machine). ## Expected Left Shift behaves as Shift in X11 apps, as it does in Wayland apps. ## Cause `default/hypr/input.lua` sets: ```lua local kb_options = "compose:caps,shift:both_capslock_cancel" ``` Because `compose:caps` takes over the physical Caps Lock key, `shift:both_capslock_cancel` restores Caps Lock by placing a `Caps_Lock` keysym on **level 2 of both Shift keys**: ``` keycode 50 = Shift_L Caps_Lock Shift_L Caps_Lock keycode 62 = Shift_R Caps_Lock Shift_R Caps_Lock keycode 66 = Multi_key Multi_key Multi_key Multi_key ``` Wayland clients consume the xkb keymap directly and evaluate levels correctly. The legacy core-X11 keymap XWayland exposes has no equivalent notion, so when it derives the core modifier map it finds `Caps_Lock` on keycode 50, assigns that keycode to the `lock` modifier, and drops it from `shift`: ``` $ xmodmap -pm shift Shift_R (0x3e) lock Shift_L (0x32) ``` So in X11, Left Shift is a locking key and is no longer a Shift key at all. Since the key bound to `lock` carries a Shift keysym, the lock behaves as ShiftLock rather than CapsLock — which is consistent with the observed symptom that it shifts *numbers* too, not just letters. (The mapping above is measured; the ShiftLock-vs-CapsLock reading is my interpretation of why numbers are affected.) ## Steps to reproduce On a default Omarchy install: ```bash sudo pacman -S xorg-xmodmap # not installed by default xmodmap -pm # runs under XWayland ``` Observe `shift = Shift_R` only and `lock = Shift_L`. Then, in any XWayland app (e.g. `xterm`, or any X11 client), tap Left Shift once and type — output is locked to shifted, numbers included. ## Workaround / suggested fix Moving Compose off the Caps Lock key resolves it, because nothing then needs to be smuggled onto the Shift keys — Caps Lock stays a real Caps Lock: ```lua local kb_options = "compose:ralt" ``` Resulting map: ``` shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) keycode 50 = Shift_L NoSymbol Shift_L keycode 66 = Caps_Lock NoSymbol Caps_Lock keycode 108 = Multi_key Multi_key Multi_key Multi_key ``` This keeps Compose, keeps a real Caps Lock, and keeps Shift working in both Wayland and X11. The trade-off is that Right Alt no longer acts as Alt/AltGr, which matters for layouts that use AltGr — so `compose:menu` may be a better default for keyboards that have a Menu key. One gotcha for anyone testing: if an input method such as fcitx5 is running, it owns the `main` keyboard (`hl-virtual-keyboard-fcitx5`) and XWayland takes its keymap from that virtual keyboard. `hyprctl reload` alone does not update it — the input method has to be restarted before the new keymap reaches XWayland. ## System | | | |---|---| | Omarchy | 4.0.2-1 | | Hyprland | 0.56.2 (efb5099) | | xorg-xwayland | 24.1.13-1 | | xkeyboard-config | 2.48-1 | | Kernel | 7.1.9-arch1-2 | | CPU | AMD Ryzen 7 5800X3D | | GPU | NVIDIA GeForce RTX 4070 (AD104) |
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 11:00 UTC