Back to logs
2026-03-15 featuremapping-core

Hold modifier action (sticky keys)

This feature came out of a specific use case: one-handed typing with the TAP Strap. When only one hand is available, pressing Shift + a letter requires two separate taps: one to activate Shift, one for the letter. The hold_modifier action makes that possible.

What it does

A hold_modifier action keeps a modifier key (Shift, Ctrl, Alt, etc.) held down at the OS level until a release condition is met. The next key event the OS sees will have that modifier applied, exactly as if you were physically holding the key.

Three release modes

Different workflows need different release behaviour, so three modes were spec'd and implemented:

Toggle
The first tap holds the modifier; any subsequent tap from the user releases it. Good for capitalising a single character.
Count (n)
The modifier stays held for exactly n key events, then releases automatically. Useful for capitalising a fixed-length word.
Timeout (ms)
The modifier releases after a specified number of milliseconds regardless of what the user does. Good for press-and-hold style shortcuts.

Validation rules

Several validation rules were added to catch common mistakes at profile load time rather than at runtime:

  • A hold_modifier cannot target the same key as a trigger in the same layer (would create an unresolvable loop)
  • Count must be ≥ 1
  • Timeout must be > 0 ms
  • The modifier key must be a recognised modifier (shift, ctrl, alt, meta)

Test coverage

15 new unit tests cover the happy paths for all three modes plus all validation failure cases. The spec was written and confirmed before any implementation code was written, per project rules.