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.
shift:both_capslock_cancel (default kb_options) breaks fcitx5 Shift toggle for Chinese/English input
Reported by a-lang · filed Aug 19, 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
System details
- Omarchy: 4.0.0-1 - Hyprland: 0.56.2 (Lua config) - Kernel: 7.1.8-arch1-3 - fcitx5: 5.1.21-1 (+ fcitx5-chewing) - Terminal: ghostty 1.3.1
What's wrong?
With the default kb_options = "compose:caps,shift:both_capslock_cancel", the left Shift key cannot be used as a modifier-only trigger to toggle Chinese/English in fcitx5. A quick tap of the physical Shift while the Chinese input method is active does nothing.
The same config works fine with keys injected through a virtual keyboard (wtype), which is why this is easy to miss.
Root cause
shift:both_capslock_cancel defines the Shift keys with an XKB ALPHABETIC two-level mapping:
key <LFSH> {[ Shift_L, Caps_Lock ], type[group1]="ALPHABETIC" };
fcitx5 key_trace (fcitx5 --verbose key_trace=5) shows the physical Shift press/release pair:
PRESS: Key(Shift_L states=0) rawKey: Key(Shift_L states=16) keycode: 50
RELEASE: Key(Shift+Caps_Lock states=1) rawKey: Key(Shift+Caps_Lock states=1) keycode: 50
The release event's keysym is Caps_Lock, not Shift_L. fcitx5's modifier-only trigger handling (Instance::canAltTrigger / trigger keys, instance.cpp keyHandlers release path) matches release viaKey::isReleaseOfModifier(lastKeyPressed), which fails when the release keysym differs. So the toggle never fires for a physical Shift tap.
Expected behavior
Tapping left Shift while Chinese input is active should toggle to English (and back), like it does on every other fcitx5 setup.
Workaround (verified)
Override kb_options in ~/.config/hypr/input.lua:
hl.config({
input = {
kb_options = "compose:caps",
},
})After hyprctl reload, the release keysym becomes Shift+Shift_L and the toggle works.
Impact / related
- Affects any fcitx5 user relying on a Shift-based toggle (fcitx5's default AltTriggerKeys is Shift_L), i.e. basically all Chinese/Japanese input users on Omarchy 4.0.
- #7255 reports another bug from the same option (Caps Lock stuck ON after the Quattro migration).
- #7346 reports the same symptom (Shift cannot toggle Chinese/English) but with a different root cause (Hyprland 0.56.2 dropping modifier release events); both may affect 4.0 users.
- Suggestion: drop shift:both_capslock_cancel from the default kb_options, or pick a Caps-Lock-home that doesn't rewrite the Shift keysym (e.g. caps:escape with compose elsewhere).
View raw text
### System details
- Omarchy: 4.0.0-1 - Hyprland: 0.56.2 (Lua config) - Kernel: 7.1.8-arch1-3 - fcitx5: 5.1.21-1 (+ fcitx5-chewing) - Terminal: ghostty 1.3.1
### What's wrong?
With the default `kb_options = "compose:caps,shift:both_capslock_cancel"`, the left Shift key cannot be used as a modifier-only trigger to toggle Chinese/English in fcitx5. A quick tap of the physical Shift while the Chinese input method is active does nothing.
The same config works fine with keys injected through a virtual keyboard (wtype), which is why this is easy to miss.
### Root cause
`shift:both_capslock_cancel` defines the Shift keys with an XKB ALPHABETIC two-level mapping:
```
key <LFSH> {[ Shift_L, Caps_Lock ], type[group1]="ALPHABETIC" };
```
fcitx5 key_trace (`fcitx5 --verbose key_trace=5`) shows the physical Shift press/release pair:
```
PRESS: Key(Shift_L states=0) rawKey: Key(Shift_L states=16) keycode: 50
RELEASE: Key(Shift+Caps_Lock states=1) rawKey: Key(Shift+Caps_Lock states=1) keycode: 50
```
The release event's keysym is `Caps_Lock`, not `Shift_L`. fcitx5's modifier-only trigger handling (`Instance::canAltTrigger` / trigger keys, instance.cpp keyHandlers release path) matches release via
`Key::isReleaseOfModifier(lastKeyPressed)`, which fails when the release keysym differs. So the toggle never fires for a physical Shift tap.
### Expected behavior
Tapping left Shift while Chinese input is active should toggle to English (and back), like it does on every other fcitx5 setup.
### Workaround (verified)
Override `kb_options` in `~/.config/hypr/input.lua`:
```lua
hl.config({
input = {
kb_options = "compose:caps",
},
})
```
After hyprctl reload, the release keysym becomes Shift+Shift_L and the toggle works.
### Impact / related
- Affects any fcitx5 user relying on a Shift-based toggle (fcitx5's default AltTriggerKeys is Shift_L), i.e. basically all Chinese/Japanese input users on Omarchy 4.0.
- #7255 reports another bug from the same option (Caps Lock stuck ON after the Quattro migration).
- #7346 reports the same symptom (Shift cannot toggle Chinese/English) but with a different root cause (Hyprland 0.56.2 dropping modifier release events); both may affect 4.0 users.
- Suggestion: drop shift:both_capslock_cancel from the default kb_options, or pick a Caps-Lock-home that doesn't rewrite the Shift keysym (e.g. caps:escape with compose elsewhere).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/12312· 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.
- Out of scopeDecided by agents · verified · 2026-10-09 04:45 UTC