From ff0b1149ea8a98831c09f03e62b4192af0e4da12 Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Tue, 22 Mar 2022 20:38:14 -0400 Subject: [PATCH 1/9] Functional but janky impl of global quick tap. --- app/src/behaviors/behavior_hold_tap.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 548d6ef87bc..b92a2c34ba4 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -91,19 +91,19 @@ const zmk_event_t *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; // Keep track of which key was tapped most recently for 'quick_tap_ms' struct last_tapped { int32_t position; - int64_t tap_deadline; + int64_t timestamp; }; struct last_tapped last_tapped; -static void store_last_tapped(struct active_hold_tap *hold_tap) { - last_tapped.position = hold_tap->position; - last_tapped.tap_deadline = hold_tap->timestamp + hold_tap->config->quick_tap_ms; +static void store_last_tapped(int32_t position, int64_t timestamp) { + last_tapped.position = position; + last_tapped.timestamp = timestamp; } static bool is_quick_tap(struct active_hold_tap *hold_tap) { - return last_tapped.position == hold_tap->position && - last_tapped.tap_deadline > hold_tap->timestamp; + return //last_tapped.position == hold_tap->position && + last_tapped.timestamp + hold_tap->config->quick_tap_ms > hold_tap->timestamp; } static int capture_event(const zmk_event_t *event) { @@ -362,7 +362,7 @@ static int press_binding(struct active_hold_tap *hold_tap) { } else { binding.behavior_dev = hold_tap->config->tap_behavior_dev; binding.param1 = hold_tap->param_tap; - store_last_tapped(hold_tap); + /* store_last_tapped(hold_tap); */ } return behavior_keymap_binding_pressed(&binding, event); } @@ -619,6 +619,10 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) { // we want to catch layer-up events too... how? struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); + if (ev->state && !is_mod(ev->usage_page, ev->keycode)) { + store_last_tapped(0, ev->timestamp); + } + if (undecided_hold_tap == NULL) { // LOG_DBG("0x%02X bubble (no undecided hold_tap active)", ev->keycode); return ZMK_EV_EVENT_BUBBLE; From 17883dc0a18ab6796e6053bb4df9d4a94fc7304b Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Thu, 24 Mar 2022 11:26:16 -0400 Subject: [PATCH 2/9] Properly integrating global quick tap as an option --- .../behaviors/zmk,behavior-hold-tap.yaml | 2 ++ app/src/behaviors/behavior_hold_tap.c | 30 ++++++++++++------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml index 096911598f2..e4cfaeab5d4 100644 --- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml +++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml @@ -20,6 +20,8 @@ properties: default: -1 quick_tap_ms: # deprecated type: int + global-quick-tap: + type: boolean flavor: type: string required: false diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index b92a2c34ba4..06c85ed4e84 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -57,6 +57,7 @@ struct behavior_hold_tap_config { char *hold_behavior_dev; char *tap_behavior_dev; int quick_tap_ms; + bool global_quick_tap; enum flavor flavor; bool retro_tap; int32_t hold_trigger_key_positions_len; @@ -88,22 +89,30 @@ struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {}; // We capture most position_state_changed events and some modifiers_state_changed events. const zmk_event_t *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; -// Keep track of which key was tapped most recently for 'quick_tap_ms' -struct last_tapped { +// Keep track of which hold tap key was tapped most recently for the standard +// 'quick_tap_ms' implementation +struct last_hold_tapped { int32_t position; int64_t timestamp; }; -struct last_tapped last_tapped; +struct last_hold_tapped last_hold_tapped; -static void store_last_tapped(int32_t position, int64_t timestamp) { - last_tapped.position = position; - last_tapped.timestamp = timestamp; +static void store_last_hold_tapped(struct active_hold_tap *hold_tap) { + last_hold_tapped.position = hold_tap->position; + last_hold_tapped.timestamp = hold_tap->timestamp + hold_tap->config->quick_tap_ms; } +// For global quick tap we just keep track of when the last key was pressed last +int64_t last_key_tapped_timestamp; + static bool is_quick_tap(struct active_hold_tap *hold_tap) { - return //last_tapped.position == hold_tap->position && - last_tapped.timestamp + hold_tap->config->quick_tap_ms > hold_tap->timestamp; + if (hold_tap->config->global_quick_tap) { + return (last_key_tapped_timestamp + hold_tap->config->quick_tap_ms) > hold_tap->timestamp; + } else { + return last_hold_tapped.position == hold_tap->position && + last_hold_tapped.timestamp > hold_tap->timestamp; + } } static int capture_event(const zmk_event_t *event) { @@ -362,7 +371,7 @@ static int press_binding(struct active_hold_tap *hold_tap) { } else { binding.behavior_dev = hold_tap->config->tap_behavior_dev; binding.param1 = hold_tap->param_tap; - /* store_last_tapped(hold_tap); */ + store_last_hold_tapped(hold_tap); } return behavior_keymap_binding_pressed(&binding, event); } @@ -620,7 +629,7 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) { struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); if (ev->state && !is_mod(ev->usage_page, ev->keycode)) { - store_last_tapped(0, ev->timestamp); + last_key_tapped_timestamp = ev->timestamp; } if (undecided_hold_tap == NULL) { @@ -687,6 +696,7 @@ static struct behavior_hold_tap_data behavior_hold_tap_data; .hold_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 0)), \ .tap_behavior_dev = DT_LABEL(DT_INST_PHANDLE_BY_IDX(n, bindings, 1)), \ .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms), \ + .global_quick_tap = DT_INST_PROP(n, global_quick_tap), \ .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor), \ .retro_tap = DT_INST_PROP(n, retro_tap), \ .hold_trigger_key_positions = DT_INST_PROP(n, hold_trigger_key_positions), \ From d532387cbbf8a40b3549f9eab3a974b66c39aaae Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Fri, 25 Mar 2022 17:06:55 -0400 Subject: [PATCH 3/9] Adding tests for global quick tap. --- app/src/behaviors/behavior_hold_tap.c | 2 +- .../1-basic/events.patterns | 6 ++++ .../1-basic/keycode_events.snapshot | 24 +++++++++++++++ .../1-basic/native_posix.keymap | 25 ++++++++++++++++ .../2-double-hold/events.patterns | 6 ++++ .../2-double-hold/keycode_events.snapshot | 12 ++++++++ .../2-double-hold/native_posix.keymap | 20 +++++++++++++ .../8-global-quick-tap/behavior_keymap.dtsi | 29 +++++++++++++++++++ .../1-basic/events.patterns | 6 ++++ .../1-basic/keycode_events.snapshot | 24 +++++++++++++++ .../1-basic/native_posix.keymap | 25 ++++++++++++++++ .../2-double-hold/events.patterns | 6 ++++ .../2-double-hold/keycode_events.snapshot | 12 ++++++++ .../2-double-hold/native_posix.keymap | 20 +++++++++++++ .../8-global-quick-tap/behavior_keymap.dtsi | 29 +++++++++++++++++++ .../1-basic/events.patterns | 6 ++++ .../1-basic/keycode_events.snapshot | 24 +++++++++++++++ .../1-basic/native_posix.keymap | 25 ++++++++++++++++ .../2-double-hold/events.patterns | 6 ++++ .../2-double-hold/keycode_events.snapshot | 12 ++++++++ .../2-double-hold/native_posix.keymap | 20 +++++++++++++ .../8-global-quick-tap/behavior_keymap.dtsi | 29 +++++++++++++++++++ .../1-basic/events.patterns | 6 ++++ .../1-basic/keycode_events.snapshot | 24 +++++++++++++++ .../1-basic/native_posix.keymap | 25 ++++++++++++++++ .../2-double-hold/events.patterns | 6 ++++ .../2-double-hold/keycode_events.snapshot | 12 ++++++++ .../2-double-hold/native_posix.keymap | 20 +++++++++++++ .../6-global-quick-tap/behavior_keymap.dtsi | 29 +++++++++++++++++++ 29 files changed, 489 insertions(+), 1 deletion(-) create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/events.patterns create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/keycode_events.snapshot create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix.keymap create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/events.patterns create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/keycode_events.snapshot create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/native_posix.keymap create mode 100644 app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/events.patterns create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix.keymap create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/events.patterns create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap create mode 100644 app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/events.patterns create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/events.patterns create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/events.patterns create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/keycode_events.snapshot create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/native_posix.keymap create mode 100644 app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/behavior_keymap.dtsi diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 06c85ed4e84..f1cb3dc31ad 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -104,7 +104,7 @@ static void store_last_hold_tapped(struct active_hold_tap *hold_tap) { } // For global quick tap we just keep track of when the last key was pressed last -int64_t last_key_tapped_timestamp; +int64_t last_key_tapped_timestamp = INT64_MIN; static bool is_quick_tap(struct active_hold_tap *hold_tap) { if (hold_tap->config->global_quick_tap) { diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/events.patterns b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/keycode_events.snapshot b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/keycode_events.snapshot new file mode 100644 index 00000000000..dc1ac805695 --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/keycode_events.snapshot @@ -0,0 +1,24 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (balanced 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 tap (balanced decision moment quick-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 (balanced decision moment timer) +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_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 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (balanced decision moment quick-tap) +kp_pressed: usage_page 0x07 keycode 0x09 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 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix.keymap b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix.keymap new file mode 100644 index 00000000000..930760553ab --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix.keymap @@ -0,0 +1,25 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* tap */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* normal quick tap */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(0,0,400) + /* hold */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,400) + /* global quick tap */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/events.patterns b/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/keycode_events.snapshot b/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/keycode_events.snapshot new file mode 100644 index 00000000000..baaadf043ce --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/keycode_events.snapshot @@ -0,0 +1,12 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (balanced 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 hold-timer (balanced decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe0 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 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 1 cleaning up hold-tap diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/native_posix.keymap b/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/native_posix.keymap new file mode 100644 index 00000000000..37c37f55630 --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/native_posix.keymap @@ -0,0 +1,20 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* hold the first mod tap */ + ZMK_MOCK_PRESS(0,0,400) + /* hold the second mod tap */ + ZMK_MOCK_PRESS(0,1,400) + /* press the normal key */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* release the hold taps */ + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi new file mode 100644 index 00000000000..0966ce0d83c --- /dev/null +++ b/app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + ht_bal: behavior_balanced { + compatible = "zmk,behavior-hold-tap"; + label = "MOD_TAP"; + #binding-cells = <2>; + flavor = "balanced"; + tapping-term-ms = <300>; + quick-tap-ms = <300>; + bindings = <&kp>, <&kp>; + global-quick-tap; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_bal LEFT_SHIFT F &ht_bal LEFT_CONTROL C + &kp D &none>; + }; + }; +}; diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/events.patterns b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot new file mode 100644 index 00000000000..27feeb8ef8e --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot @@ -0,0 +1,24 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (hold-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 tap (hold-preferred decision moment quick-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-interrupt (hold-preferred decision moment other-key-down) +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_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 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (hold-preferred decision moment quick-tap) +kp_pressed: usage_page 0x07 keycode 0x09 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 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix.keymap b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix.keymap new file mode 100644 index 00000000000..ee0d5e80a66 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix.keymap @@ -0,0 +1,25 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* tap */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* normal quick tap */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(0,0,400) + /* hold */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,400) + /* global quick tap */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/events.patterns b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot new file mode 100644 index 00000000000..797a6ab4d70 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot @@ -0,0 +1,12 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided hold-timer (hold-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 hold-timer (hold-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe0 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 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 1 cleaning up hold-tap diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap new file mode 100644 index 00000000000..37c37f55630 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap @@ -0,0 +1,20 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* hold the first mod tap */ + ZMK_MOCK_PRESS(0,0,400) + /* hold the second mod tap */ + ZMK_MOCK_PRESS(0,1,400) + /* press the normal key */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* release the hold taps */ + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi new file mode 100644 index 00000000000..fee3361e4b4 --- /dev/null +++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + hp: behavior_hold_preferred { + compatible = "zmk,behavior-hold-tap"; + label = "MOD_TAP"; + #binding-cells = <2>; + flavor = "hold-preferred"; + tapping-term-ms = <300>; + quick-tap-ms = <300>; + bindings = <&kp>, <&kp>; + global-quick-tap; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &hp LEFT_SHIFT F &hp LEFT_CONTROL G + &kp D &none>; + }; + }; +}; diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/events.patterns b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot new file mode 100644 index 00000000000..455b3330304 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot @@ -0,0 +1,24 @@ +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 tap (tap-preferred decision moment quick-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 +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 +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-preferred decision moment quick-tap) +kp_pressed: usage_page 0x07 keycode 0x09 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 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix.keymap b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix.keymap new file mode 100644 index 00000000000..930760553ab --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix.keymap @@ -0,0 +1,25 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* tap */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* normal quick tap */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(0,0,400) + /* hold */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,400) + /* global quick tap */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/events.patterns b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot new file mode 100644 index 00000000000..ef4288730bd --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot @@ -0,0 +1,12 @@ +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 hold-timer (tap-preferred decision moment timer) +kp_pressed: usage_page 0x07 keycode 0xe0 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 0xe1 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0xe0 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 1 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap new file mode 100644 index 00000000000..37c37f55630 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix.keymap @@ -0,0 +1,20 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* hold the first mod tap */ + ZMK_MOCK_PRESS(0,0,400) + /* hold the second mod tap */ + ZMK_MOCK_PRESS(0,1,400) + /* press the normal key */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* release the hold taps */ + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi new file mode 100644 index 00000000000..4771ab75895 --- /dev/null +++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + tp: behavior_tap_preferred { + compatible = "zmk,behavior-hold-tap"; + label = "MOD_TAP"; + #binding-cells = <2>; + flavor = "tap-preferred"; + tapping-term-ms = <300>; + quick-tap-ms = <300>; + bindings = <&kp>, <&kp>; + global-quick-tap; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &tp LEFT_SHIFT F &tp LEFT_CONTROL C + &kp D &none>; + }; + }; +}; diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/keycode_events.snapshot new file mode 100644 index 00000000000..03bc028906d --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/keycode_events.snapshot @@ -0,0 +1,24 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted 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 tap (tap-unless-interrupted decision moment quick-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 tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 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 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_pressed: usage_page 0x07 keycode 0x07 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment quick-tap) +kp_pressed: usage_page 0x07 keycode 0x09 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 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix.keymap new file mode 100644 index 00000000000..930760553ab --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix.keymap @@ -0,0 +1,25 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* tap */ + ZMK_MOCK_PRESS(0,0,10) + ZMK_MOCK_RELEASE(0,0,10) + /* normal quick tap */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(0,0,400) + /* hold */ + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,400) + /* global quick tap */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_PRESS(0,0,400) + ZMK_MOCK_RELEASE(1,0,10) + ZMK_MOCK_RELEASE(0,0,10) + >; +}; diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/events.patterns b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/events.patterns new file mode 100644 index 00000000000..4db21917caf --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/events.patterns @@ -0,0 +1,6 @@ +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 \ No newline at end of file diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/keycode_events.snapshot b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/keycode_events.snapshot new file mode 100644 index 00000000000..dfd2e934508 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/keycode_events.snapshot @@ -0,0 +1,12 @@ +ht_binding_pressed: 0 new undecided hold_tap +ht_decide: 0 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_pressed: 1 new undecided hold_tap +ht_decide: 1 decided tap (tap-unless-interrupted decision moment timer) +kp_pressed: usage_page 0x07 keycode 0x0d 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 0x09 implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 0 cleaning up hold-tap +kp_released: usage_page 0x07 keycode 0x0d implicit_mods 0x00 explicit_mods 0x00 +ht_binding_released: 1 cleaning up hold-tap diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/native_posix.keymap b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/native_posix.keymap new file mode 100644 index 00000000000..37c37f55630 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/native_posix.keymap @@ -0,0 +1,20 @@ +#include +#include +#include +#include "../behavior_keymap.dtsi" + +&kscan { + events = < + /* hold the first mod tap */ + ZMK_MOCK_PRESS(0,0,400) + /* hold the second mod tap */ + ZMK_MOCK_PRESS(0,1,400) + /* press the normal key */ + ZMK_MOCK_PRESS(1,0,10) + ZMK_MOCK_RELEASE(1,0,10) + + /* release the hold taps */ + ZMK_MOCK_RELEASE(0,0,10) + ZMK_MOCK_RELEASE(0,1,10) + >; +}; diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/behavior_keymap.dtsi new file mode 100644 index 00000000000..6ca7ac72702 --- /dev/null +++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/behavior_keymap.dtsi @@ -0,0 +1,29 @@ +#include +#include +#include + +/ { + behaviors { + ht_tui: behavior_hold_tap_tap_unless_interrupted { + compatible = "zmk,behavior-hold-tap"; + label = "hold_tap_tap_unless_interrupted"; + #binding-cells = <2>; + flavor = "tap-unless-interrupted"; + tapping-term-ms = <300>; + quick-tap-ms = <300>; + bindings = <&kp>, <&kp>; + global-quick-tap; + }; + }; + + keymap { + compatible = "zmk,keymap"; + label ="Default keymap"; + + default_layer { + bindings = < + &ht_tui LEFT_SHIFT F &ht_tui LEFT_CONTROL J + &kp D &kp RIGHT_CONTROL>; + }; + }; +}; From b8f7756561a77fc854a8c8657094afc4199c8922 Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Fri, 25 Mar 2022 17:34:42 -0400 Subject: [PATCH 4/9] Adding a quick bit of docs --- docs/docs/behaviors/hold-tap.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index f7c386b3f7b..596512d7730 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -48,6 +48,10 @@ If you press a tapped hold-tap again within `quick-tap-ms` milliseconds, it will In QMK, unlike ZMK, this functionality is enabled by default, and you turn it off using `TAPPING_FORCE_HOLD`. +#### `global-quick-tap` + +If global quick tap is enabled, then the quick tap will apply not only when the given hold tap is tapped, but for any key tap before it. This effectively disables the hold tap when typing quickly, which is can be quite useful for homerow mods. It can also have the effect of removing the input delay when typing quickly. + #### `retro-tap` 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. From 58c48ea4aee7ab6886c4231dc27b40b373132db5 Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Wed, 6 Apr 2022 17:27:12 -0400 Subject: [PATCH 5/9] Unifying last tapped timestamps. Rather than holding two timestamps they are now rolled into one. --- app/src/behaviors/behavior_hold_tap.c | 31 +++++++++++++++------------ 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index f1cb3dc31ad..1ba552a44b9 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -89,29 +89,32 @@ struct active_hold_tap active_hold_taps[ZMK_BHV_HOLD_TAP_MAX_HELD] = {}; // We capture most position_state_changed events and some modifiers_state_changed events. const zmk_event_t *captured_events[ZMK_BHV_HOLD_TAP_MAX_CAPTURED_EVENTS] = {}; -// Keep track of which hold tap key was tapped most recently for the standard -// 'quick_tap_ms' implementation -struct last_hold_tapped { +// Keep track of which key was tapped most recently for the standard, if it is a hold-tap +// a position, will be given, if not it will just be INT32_MIN +struct last_tapped { int32_t position; int64_t timestamp; }; -struct last_hold_tapped last_hold_tapped; +struct last_tapped last_tapped = { INT32_MIN, INT64_MIN }; -static void store_last_hold_tapped(struct active_hold_tap *hold_tap) { - last_hold_tapped.position = hold_tap->position; - last_hold_tapped.timestamp = hold_tap->timestamp + hold_tap->config->quick_tap_ms; +static void store_last_tapped(int64_t timestamp) { + if (timestamp > last_tapped.timestamp) { + last_tapped.position = INT32_MIN; + last_tapped.timestamp = timestamp; + } } -// For global quick tap we just keep track of when the last key was pressed last -int64_t last_key_tapped_timestamp = INT64_MIN; +static void store_last_hold_tapped(struct active_hold_tap *hold_tap) { + last_tapped.position = hold_tap->position; + last_tapped.timestamp = hold_tap->timestamp; +} static bool is_quick_tap(struct active_hold_tap *hold_tap) { - if (hold_tap->config->global_quick_tap) { - return (last_key_tapped_timestamp + hold_tap->config->quick_tap_ms) > hold_tap->timestamp; + if (hold_tap->config->global_quick_tap || last_tapped.position == hold_tap->position) { + return (last_tapped.timestamp + hold_tap->config->quick_tap_ms) > hold_tap->timestamp; } else { - return last_hold_tapped.position == hold_tap->position && - last_hold_tapped.timestamp > hold_tap->timestamp; + return false; } } @@ -629,7 +632,7 @@ static int keycode_state_changed_listener(const zmk_event_t *eh) { struct zmk_keycode_state_changed *ev = as_zmk_keycode_state_changed(eh); if (ev->state && !is_mod(ev->usage_page, ev->keycode)) { - last_key_tapped_timestamp = ev->timestamp; + store_last_tapped(ev->timestamp); } if (undecided_hold_tap == NULL) { From 7aed090bab8a4a245252dc50716b288c7526df92 Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Tue, 19 Apr 2022 00:56:13 -0400 Subject: [PATCH 6/9] Fixing clang format error. --- app/src/behaviors/behavior_hold_tap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 1ba552a44b9..99ed8cf5962 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -96,7 +96,7 @@ struct last_tapped { int64_t timestamp; }; -struct last_tapped last_tapped = { INT32_MIN, INT64_MIN }; +struct last_tapped last_tapped = {INT32_MIN, INT64_MIN}; static void store_last_tapped(int64_t timestamp) { if (timestamp > last_tapped.timestamp) { From a21b8a2f7c46723e86d76f20d3c93d11bfa947ba Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Sun, 24 Apr 2022 23:09:43 -0400 Subject: [PATCH 7/9] Improving global-quick-tap docs --- docs/docs/behaviors/hold-tap.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 596512d7730..2da31b3a7f0 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -50,7 +50,25 @@ In QMK, unlike ZMK, this functionality is enabled by default, and you turn it of #### `global-quick-tap` -If global quick tap is enabled, then the quick tap will apply not only when the given hold tap is tapped, but for any key tap before it. This effectively disables the hold tap when typing quickly, which is can be quite useful for homerow mods. It can also have the effect of removing the input delay when typing quickly. +If global quick tap is enabled, then the quick tap will apply not only when the given hold tap is tapped, but for any key tap before it. This effectively disables the hold tap when typing quickly, which can be quite useful for home row mods. It can also have the effect of removing the input delay when typing quickly. + +For example, the following hold tap configuration enables global quick tap with a 125 millisecond term. +``` +gqt: global-quick-tap { + compatible = "zmk,behavior-hold-tap"; + label = "GLOBAL_QUICK_TAP"; + #binding-cells = <2>; + flavor = "tap-preferred"; + tapping-term-ms = <200>; + quick-tap-ms = <125>; + global-quick-tap; + bindings = <&kp>, <&kp>; +}; +``` + +If you press `&kp A`, and then `&gqt LEFT_SHIFT B` **within** 125 ms after, then `ab` will be output. Importantly, the `b` will be output immediately since it was within the `quick-tap-ms`. This behavior will hold for any key that is output to the computer. The `&gqt LEFT_SHIFT B` binding will only have its underlying hold-tap behavior if it is pressed 125 ms **after** any keycode is sent to the computer. + +Note that the higher the `quick-tap-ms`, the harder it will be to use the hold behavior, making this unideal for capitalizing letter while typing normally. However, paired with [mod-tap](mod-tap.md) #### `retro-tap` From 9657ce0d77cc25734a272abda14e2183a869eb04 Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Mon, 25 Apr 2022 13:46:48 -0400 Subject: [PATCH 8/9] More updates to the quick tap documentation. --- docs/docs/behaviors/hold-tap.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 2da31b3a7f0..10f35e4ee1d 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -50,9 +50,9 @@ In QMK, unlike ZMK, this functionality is enabled by default, and you turn it of #### `global-quick-tap` -If global quick tap is enabled, then the quick tap will apply not only when the given hold tap is tapped, but for any key tap before it. This effectively disables the hold tap when typing quickly, which can be quite useful for home row mods. It can also have the effect of removing the input delay when typing quickly. +If global quick tap is enabled, then `quick-tap-ms` will apply not only when the given hold-tap is tapped but for any key tap before it. This effectively disables the hold tap when typing quickly, which can be quite useful for home row mods. It can also have the effect of removing the input delay when typing quickly. -For example, the following hold tap configuration enables global quick tap with a 125 millisecond term. +For example, the following hold-tap configuration enables global quick tap with a 125 millisecond term. ``` gqt: global-quick-tap { compatible = "zmk,behavior-hold-tap"; @@ -66,9 +66,9 @@ gqt: global-quick-tap { }; ``` -If you press `&kp A`, and then `&gqt LEFT_SHIFT B` **within** 125 ms after, then `ab` will be output. Importantly, the `b` will be output immediately since it was within the `quick-tap-ms`. This behavior will hold for any key that is output to the computer. The `&gqt LEFT_SHIFT B` binding will only have its underlying hold-tap behavior if it is pressed 125 ms **after** any keycode is sent to the computer. +If you press `&kp A` and then `&gqt LEFT_SHIFT B` **within** 125 ms, then `ab` will be output. Importantly, `b` will be output immediately since it was within the `quick-tap-ms`. This quick-tap behavior will work for any key press, whether it is within a behavior like hold-tap, or a simple `&kp`. This means the `&gqt LEFT_SHIFT B` binding will only have its underlying hold-tap behavior if it is pressed 125 ms **after** a key press. -Note that the higher the `quick-tap-ms`, the harder it will be to use the hold behavior, making this unideal for capitalizing letter while typing normally. However, paired with [mod-tap](mod-tap.md) +Note that the higher the `quick-tap-ms` the harder it will be to use the hold behavior, making this less applicable for something like capitalizing letter while typing normally. However, if the hold behavior isn't used during fast typing, then it can be an effective way to mitigate misfires. #### `retro-tap` From a8323660c6c80c05ff15ff9f049cc0234750de97 Mon Sep 17 00:00:00 2001 From: Andrew Rae Date: Mon, 25 Apr 2022 23:42:55 -0400 Subject: [PATCH 9/9] Running prettier:format. --- docs/docs/behaviors/hold-tap.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md index 10f35e4ee1d..d0255c70e8a 100644 --- a/docs/docs/behaviors/hold-tap.md +++ b/docs/docs/behaviors/hold-tap.md @@ -53,6 +53,7 @@ In QMK, unlike ZMK, this functionality is enabled by default, and you turn it of If global quick tap is enabled, then `quick-tap-ms` will apply not only when the given hold-tap is tapped but for any key tap before it. This effectively disables the hold tap when typing quickly, which can be quite useful for home row mods. It can also have the effect of removing the input delay when typing quickly. For example, the following hold-tap configuration enables global quick tap with a 125 millisecond term. + ``` gqt: global-quick-tap { compatible = "zmk,behavior-hold-tap";