Feature request: (/bug?) Nested tap-hold keys cannot resolve their `hold` action while parent is waiting for a release
Is your feature request related to a problem? Please describe.
When using actions that wait for a release event (like tap-hold-order or tap-hold-release variants), it appears they only progress when a physical key release occurs. Because of this, if the second key pressed is a tap-hold key, its "hold" action cannot resolve normally by just holding it down. Instead, you have to guess the hold timeout and physically release it to satisfy the parent key before any output happens.
The solution to this, generally, is "just add a timeout!", but...
I encountered this while trying to configure Home Row Mods and tap-hold-release layers to also act as one-shot modifiers if held and released in isolation. Other creative uses of tap-hold-order (or tap-hold-release with longer timeouts) is at risk of running into similar issues with nested tap-holds.
Here's a simplified version of that config, which accomplishes everything it should besides having this quirk.
(defcfg process-unmapped-keys yes)
(defsrc)
(deftemplate char-holdshot (char mod)
(tap-hold-release-timeout 200 200
$char ;; if tapped, output char
$mod ;; if held and another key is pressed+released, apply $mod
(tap-hold-order 0 0 ;; if held until 200ms timeout...
(one-shot 1000 $mod) ;; and no keys are released before mod is released: begin one-shot timeout when released
(one-shot 1000 $mod) ;; or, if a key is pressed and released, apply the $mod as normal.
;; even though we just want a regular mod, we use one-shot for both actions.
;; This ensures we do not consume other simultaneous one-shots.
)
)
)
(deflayermap (base)
d (t! char-holdshot d lctl)
spc (t! char-holdshot spc (layer-while-held nums))
)
(deflayermap (nums)
a (tap-hold 200 200 1 S-1)
s (tap-hold 200 200 2 S-2)
d (t! char-holdshot 3 lctl)
f (tap-hold 200 200 4 S-4)
g (tap-hold 200 200 5 S-5)
)To reproduce, hold spc and then also hold f to try outputting $. Nothing happens until one or the other key is released.
Describe the solution you'd like.
Ideally, I am hoping the logical resolution of a child's "hold" could satisfy the parent's release requirement. If changing the global behavior to allow this would be a breaking change, perhaps something like a -eager variant of the tap-hold-order and -release actions would be possible? It could fire on a release-vkey, or the hold action of a tap-hold.
Describe alternatives you've considered.
I've been churning on an alternative way to get this three-way tap/release/one-shot behavior working for a full day and haven't been able to figure it out.
Additional context
No response
Source: jtroo/kanata