Specification of all CapsLock & Space key-combination cases. 2026-05-15.
| # | Input | Sequence | Result | Notes |
|---|---|---|---|---|
| 1 | Space single tap (< 200 ms, no other key) | Space↓ → Space↑ | native One space character typed. | Engine passthrough via key_tap(Space) on key-up. |
| 2 | Space hold > 200 ms (no other key) | Space↓ (held) | native Space character emitted, then auto-repeats at the OS key-repeat rate until release. Behaves identically to a normal Space key. | 200 ms timeout closes the chord-detect window; engine then injects key_down(Space) and lets the OS auto-repeat, emitting key_up(Space) on release. |
| 3 | CapsLock single tap (no other key) | CapsLock↓ → CapsLock↑ | native OS AlphaShift state toggles. | When the hidutil remap is active, the engine routes the tap to IOHIDSetModifierLockState instead of CGEvent (which can't toggle AlphaShift). |
| 4 | CapsLock hold (no other key) | CapsLock↓ (held) → CapsLock↑ | native One AlphaShift toggle on release. No auto-repeat. | CapsLock has no 200 ms timeout; tap and hold behave the same. |
| # | Input | Sequence | Result | Notes |
|---|---|---|---|---|
| 5 | Space + action key (HJKL, WASD, V, B, M, Z, 1–9, …) | Space↓ → key↓ → key↑ → Space↑ | FN Action runs (e.g. cursor left for H). No space character emitted on release. | fn_acted=true suppresses native passthrough on Space↑. |
| 6 | CapsLock + action key | CapsLock↓ → key↓ → key↑ → CapsLock↑ | FN Same as #5. AlphaShift is not toggled. | Space and CapsLock are interchangeable as triggers. |
| # | Input | Sequence | Result | Notes |
|---|---|---|---|---|
| 7 | Space then CapsLock | Space↓ → CapsLock↓ | LOCK Enter LOCK mode. AlphaShift unchanged. | Chord detected in clx_dn; fn_acted=true prevents either key emitting on release. |
| 8 | CapsLock then Space | CapsLock↓ → Space↓ | LOCK Same as #7 — order doesn't matter. | Symmetric chord detection. |
| 9 | Inside LOCK: tap Space or CapsLock alone | Space↑ or CapsLock↑ | unlock Exit LOCK mode. AlphaShift unchanged. | The unlock path in clx_up takes precedence over native passthrough. |
Rule: any modifier + Space bypasses CLX so OS shortcuts work unchanged.
| # | Input | Sequence | Result | Notes |
|---|---|---|---|---|
| 10 | Shift + Space | Shift↓ → Space↓ | bypass OS receives Shift+Space (IME switching on macOS). | Down and up both pass through. |
| 11 | Ctrl + Space | Ctrl↓ → Space↓ | bypass OS receives Ctrl+Space (IME switching, AHK-compatible). | |
| 12 | Cmd + Space | Cmd↓ → Space↓ | bypass OS receives Cmd+Space (Spotlight). | |
| 13 | Alt + Space | Alt↓ → Space↓ | bypass OS receives Alt+Space. | Aligned with other modifiers — the rule is uniform. |
| 14 | Modifier + CapsLock | mod↓ → CapsLock↓ | FN Enters CLX FN mode (CapsLock is not bypassed by modifiers). | Modifier bypass applies only to Space, where it collides with OS shortcuts. |
| # | Input | Sequence | Result | Notes |
|---|---|---|---|---|
| 15 | Non-modifier key already held when Space is pressed | A↓ → Space↓ | bypass OS receives a normal Space. | Protects fast-typing scenarios. Triggered by non_modifier_held check. |
| 16 | Non-modifier key already held when CapsLock is pressed | A↓ → CapsLock↓ | bypass OS receives a normal CapsLock (toggles AlphaShift). | Same protection for CapsLock. |
| # | Event | Behavior | Notes |
|---|---|---|---|
| 17 | CLX startup | If use_capslock is enabled: force AlphaShift OFF via IOHIDSetModifierLockState, then install the hidutil CapsLock → F18 remap. |
Forcing AlphaShift off prevents a stuck state (user with AlphaShift on couldn't toggle it back once the physical key is remapped). |
| 18 | CLX graceful exit (Quit menu, terminate:, SIGINT, SIGTERM, SIGHUP) |
hidutil remap is reset via signal handler / atexit hook. | Best-effort cleanup. AlphaShift state is left as-is. |
| 19 | CLX killed by SIGKILL (kill -9) |
Remap persists. Recovery: launch CLX again, or run hidutil property --set '{"UserKeyMapping":[]}' manually. |
SIGKILL cannot be caught. |
| 20 | CGEventTap disabled by macOS (secure input, password fields, watchdog timeout) | Tap is re-enabled automatically; all held keys are released; modules stopped. | emergency_stop() prevents stuck-key states from AccModel physics. |
fn_acted.SELF_INJECT_TAG and ignored by the hook, preventing feedback loops.