feature(hold-tap): no-hold-flash for retro taps
This is an improvement on retro-tap, solving the 'flashing hold' issue users people experience. When the tapping-term expires, the hold key is normally pressed. When retro-tap is enabled, this is undesirable; only an interrupted hold-tap should trigger the hold behavior. This change disables the hold behavior for the 'STATUS_HOLD_TIMER' state when retro-tap is enabled, and makes sure the 'STATUS_HOLD_INTERRUPT' state will be triggered when appropriate.
This commit is contained in:
parent
89ed816c67
commit
0c1940bb79
7 changed files with 19 additions and 81 deletions
|
@ -317,6 +317,10 @@ static inline const char *decision_moment_str(enum decision_moment decision_mome
|
||||||
}
|
}
|
||||||
|
|
||||||
static int press_binding(struct active_hold_tap *hold_tap) {
|
static int press_binding(struct active_hold_tap *hold_tap) {
|
||||||
|
if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct zmk_behavior_binding_event event = {
|
struct zmk_behavior_binding_event event = {
|
||||||
.position = hold_tap->position,
|
.position = hold_tap->position,
|
||||||
.timestamp = hold_tap->timestamp,
|
.timestamp = hold_tap->timestamp,
|
||||||
|
@ -335,6 +339,10 @@ static int press_binding(struct active_hold_tap *hold_tap) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int release_binding(struct active_hold_tap *hold_tap) {
|
static int release_binding(struct active_hold_tap *hold_tap) {
|
||||||
|
if (hold_tap->config->retro_tap && hold_tap->status == STATUS_HOLD_TIMER) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct zmk_behavior_binding_event event = {
|
struct zmk_behavior_binding_event event = {
|
||||||
.position = hold_tap->position,
|
.position = hold_tap->position,
|
||||||
.timestamp = hold_tap->timestamp,
|
.timestamp = hold_tap->timestamp,
|
||||||
|
@ -396,12 +404,18 @@ static void decide_retro_tap(struct active_hold_tap *hold_tap) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_hold_status_for_retro_tap(uint32_t position) {
|
static void update_hold_status_for_retro_tap(uint32_t ignore_position) {
|
||||||
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
for (int i = 0; i < ZMK_BHV_HOLD_TAP_MAX_HELD; i++) {
|
||||||
struct active_hold_tap *hold_tap = &active_hold_taps[i];
|
struct active_hold_tap *hold_tap = &active_hold_taps[i];
|
||||||
if (hold_tap->position != position && hold_tap->status == STATUS_HOLD_TIMER) {
|
if (hold_tap->position == ignore_position ||
|
||||||
|
hold_tap->position == ZMK_BHV_HOLD_TAP_POSITION_NOT_USED ||
|
||||||
|
hold_tap->config->retro_tap == false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (hold_tap->status == STATUS_HOLD_TIMER) {
|
||||||
LOG_DBG("Update hold tap %d status to hold-interrupt", hold_tap->position);
|
LOG_DBG("Update hold tap %d status to hold-interrupt", hold_tap->position);
|
||||||
hold_tap->status = STATUS_HOLD_INTERRUPT;
|
hold_tap->status = STATUS_HOLD_INTERRUPT;
|
||||||
|
press_binding(hold_tap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,14 @@ kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
ht_binding_released: 0 cleaning up hold-tap
|
||||||
ht_binding_pressed: 0 new undecided hold_tap
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
ht_decide: 0 decided hold-timer (balanced decision moment timer)
|
ht_decide: 0 decided hold-timer (balanced decision moment timer)
|
||||||
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
decide_retro_tap: 0 retro tap
|
decide_retro_tap: 0 retro tap
|
||||||
kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
ht_binding_released: 0 cleaning up hold-tap
|
||||||
ht_binding_pressed: 0 new undecided hold_tap
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
ht_decide: 0 decided hold-timer (balanced decision moment timer)
|
ht_decide: 0 decided hold-timer (balanced decision moment timer)
|
||||||
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
update_hold_status_for_retro_tap: Update hold tap 0 status to hold-interrupt
|
update_hold_status_for_retro_tap: Update hold tap 0 status to hold-interrupt
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
|
|
@ -5,16 +5,14 @@ kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
ht_binding_released: 0 cleaning up hold-tap
|
||||||
ht_binding_pressed: 0 new undecided hold_tap
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
ht_decide: 0 decided hold-timer (hold-preferred decision moment timer)
|
ht_decide: 0 decided hold-timer (hold-preferred decision moment timer)
|
||||||
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
decide_retro_tap: 0 retro tap
|
decide_retro_tap: 0 retro tap
|
||||||
kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
ht_binding_released: 0 cleaning up hold-tap
|
||||||
ht_binding_pressed: 0 new undecided hold_tap
|
ht_binding_pressed: 0 new undecided hold_tap
|
||||||
ht_decide: 0 decided hold-timer (hold-preferred decision moment timer)
|
ht_decide: 0 decided hold-timer (hold-preferred decision moment timer)
|
||||||
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
update_hold_status_for_retro_tap: Update hold tap 0 status to hold-interrupt
|
update_hold_status_for_retro_tap: Update hold tap 0 status to hold-interrupt
|
||||||
|
kp_pressed: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
||||||
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
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
|
|
||||||
s/.*update_hold_status_for_retro_tap/update_hold_status_for_retro_tap/p
|
|
||||||
s/.*decide_retro_tap/decide_retro_tap/p
|
|
|
@ -1,21 +0,0 @@
|
||||||
ht_binding_pressed: 0 new undecided hold_tap
|
|
||||||
ht_decide: 0 decided tap (tap-preferred decision moment key-up)
|
|
||||||
kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
|
||||||
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
|
|
||||||
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
decide_retro_tap: 0 retro tap
|
|
||||||
kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
kp_released: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
|
||||||
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
|
|
||||||
update_hold_status_for_retro_tap: Update hold tap 0 status to hold-interrupt
|
|
||||||
kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
kp_released: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
kp_released: usage_page 0x07 keycode 0xe1 implicit_mods 0x00 explicit_mods 0x00
|
|
||||||
ht_binding_released: 0 cleaning up hold-tap
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include <dt-bindings/zmk/keys.h>
|
|
||||||
#include <behaviors.dtsi>
|
|
||||||
#include <dt-bindings/zmk/kscan_mock.h>
|
|
||||||
|
|
||||||
/ {
|
|
||||||
behaviors {
|
|
||||||
tp: behavior_tap_preferred {
|
|
||||||
compatible = "zmk,behavior-hold-tap";
|
|
||||||
label = "MOD_TAP";
|
|
||||||
#binding-cells = <2>;
|
|
||||||
flavor = "tap-preferred";
|
|
||||||
tapping_term_ms = <300>;
|
|
||||||
bindings = <&kp>, <&kp>;
|
|
||||||
retro-tap;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
keymap {
|
|
||||||
compatible = "zmk,keymap";
|
|
||||||
label ="Default keymap";
|
|
||||||
|
|
||||||
default_layer {
|
|
||||||
bindings = <
|
|
||||||
&tp LEFT_SHIFT F &none
|
|
||||||
&kp D &none>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
&kscan {
|
|
||||||
events = <
|
|
||||||
/* tap */
|
|
||||||
ZMK_MOCK_PRESS(0,0,10)
|
|
||||||
ZMK_MOCK_RELEASE(0,0,10)
|
|
||||||
/* retro tap */
|
|
||||||
ZMK_MOCK_PRESS(0,0,400)
|
|
||||||
ZMK_MOCK_RELEASE(0,0,10)
|
|
||||||
/* hold */
|
|
||||||
ZMK_MOCK_PRESS(0,0,400)
|
|
||||||
ZMK_MOCK_PRESS(1,0,10)
|
|
||||||
ZMK_MOCK_RELEASE(1,0,10)
|
|
||||||
ZMK_MOCK_RELEASE(0,0,10)
|
|
||||||
>;
|
|
||||||
};
|
|
|
@ -51,7 +51,7 @@ In QMK, unlike ZMK, this functionality is enabled by default, and you turn it of
|
||||||
|
|
||||||
If retro tap is enabled, the tap behavior is triggered when releasing the hold-tap key if no other key was pressed in the meantime.
|
If retro tap is enabled, the tap behavior is triggered when releasing the hold-tap key if no other key was pressed in the meantime.
|
||||||
|
|
||||||
For example, if you press `&mt LEFT_SHIFT A` for a long time and then release it without pressing another key in the meantime, it will output `a`. (Actually, `LEFT_SHIFT` will be pressed when the tapping term expires, which is released just before the `a` is tapped.
|
For example, if you press `&mt LEFT_SHIFT A` and then release it without pressing another key, it will output `a`.
|
||||||
|
|
||||||
```
|
```
|
||||||
&mt {
|
&mt {
|
||||||
|
|
Loading…
Reference in a new issue