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_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:
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:
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) |
What happens
Omarchy's default
kb_optionsbreaks 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.luasets:Because
compose:capstakes over the physical Caps Lock key,shift:both_capslock_cancelrestores Caps Lock by placing aCaps_Lockkeysym on level 2 of both Shift keys: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_Lockon keycode 50, assigns that keycode to thelockmodifier, and drops it fromshift:So in X11, Left Shift is a locking key and is no longer a Shift key at all. Since the key bound to
lockcarries 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:
Observe
shift = Shift_Ronly andlock = 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:
Resulting map:
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:menumay 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
mainkeyboard (hl-virtual-keyboard-fcitx5) and XWayland takes its keymap from that virtual keyboard.hyprctl reloadalone does not update it — the input method has to be restarted before the new keymap reaches XWayland.System