fix(behaviors): Fix timing of delayed hold-tap trigger
A hold-tap timer event would be triggered too soon if the hold-tap was delayed for longer than its tapping-term. This may cause accidental hold behavior when the correct behavior would be tap. By queuing the timer event instead of executing it immediately, other delayed events get a chance to be processed properly.
This commit is contained in:
parent
0f28130493
commit
efa497c69b
4 changed files with 68 additions and 5 deletions
|
@ -449,11 +449,7 @@ static int on_hold_tap_binding_pressed(struct zmk_behavior_binding *binding,
|
||||||
// if this behavior was queued we have to adjust the timer to only
|
// if this behavior was queued we have to adjust the timer to only
|
||||||
// wait for the remaining time.
|
// wait for the remaining time.
|
||||||
int32_t tapping_term_ms_left = (hold_tap->timestamp + cfg->tapping_term_ms) - k_uptime_get();
|
int32_t tapping_term_ms_left = (hold_tap->timestamp + cfg->tapping_term_ms) - k_uptime_get();
|
||||||
if (tapping_term_ms_left > 0) {
|
|
||||||
k_delayed_work_submit(&hold_tap->work, K_MSEC(tapping_term_ms_left));
|
k_delayed_work_submit(&hold_tap->work, K_MSEC(tapping_term_ms_left));
|
||||||
} else {
|
|
||||||
decide_hold_tap(hold_tap, HT_TIMER_EVENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ZMK_BEHAVIOR_OPAQUE;
|
return ZMK_BEHAVIOR_OPAQUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
s/.*hid_listener_keycode/kp/p
|
||||||
|
s/.*mo_keymap_binding/mo/p
|
||||||
|
s/.*on_hold_tap_binding/ht_binding/p
|
||||||
|
s/.*decide_hold_tap/ht_decide/p
|
|
@ -0,0 +1,10 @@
|
||||||
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
|
ht_decide: 0 decided hold-timer (tap-preferred decision moment timer)
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
ht_binding_pressed: 1 new undecided hold_tap
|
||||||
|
ht_decide: 1 decided tap (tap-preferred decision moment key-up)
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
kp_released: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
ht_binding_released: 1 cleaning up hold-tap
|
||||||
|
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
ht_binding_released: 0 cleaning up hold-tap
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <dt-bindings/zmk/keys.h>
|
||||||
|
#include <behaviors.dtsi>
|
||||||
|
#include <dt-bindings/zmk/kscan_mock.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A hold-tap with long tapping term is pressed first.
|
||||||
|
* A hold-tap with short tapping term is quickly tapped.
|
||||||
|
* The short tapping term hold-tap should 'tap', not 'hold'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/ {
|
||||||
|
behaviors {
|
||||||
|
tp_short: short_tap {
|
||||||
|
compatible = "zmk,behavior-hold-tap";
|
||||||
|
label = "MOD_TAP_SHORT";
|
||||||
|
#binding-cells = <2>;
|
||||||
|
flavor = "tap-preferred";
|
||||||
|
tapping-term-ms = <100>;
|
||||||
|
quick-tap-ms = <200>;
|
||||||
|
bindings = <&kp>, <&kp>;
|
||||||
|
};
|
||||||
|
tp_long: long_tap {
|
||||||
|
compatible = "zmk,behavior-hold-tap";
|
||||||
|
label = "MOD_TAP_LONG";
|
||||||
|
#binding-cells = <2>;
|
||||||
|
flavor = "tap-preferred";
|
||||||
|
tapping-term-ms = <200>;
|
||||||
|
quick-tap-ms = <200>;
|
||||||
|
bindings = <&kp>, <&kp>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
keymap {
|
||||||
|
compatible = "zmk,keymap";
|
||||||
|
label ="Default keymap";
|
||||||
|
|
||||||
|
default_layer {
|
||||||
|
bindings = <
|
||||||
|
&tp_long LEFT_SHIFT F &tp_short LEFT_CONTROL J
|
||||||
|
&kp D &kp RIGHT_CONTROL>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
&kscan {
|
||||||
|
events = <
|
||||||
|
ZMK_MOCK_PRESS(0,0,20)
|
||||||
|
ZMK_MOCK_PRESS(0,1,20)
|
||||||
|
ZMK_MOCK_RELEASE(0,1,200)
|
||||||
|
ZMK_MOCK_RELEASE(0,0,10)
|
||||||
|
>;
|
||||||
|
};
|
Loading…
Reference in a new issue