From c50ad40550ed95dbfa74cb1d27f8b9576aef02b9 Mon Sep 17 00:00:00 2001
From: Andrew Rae <ajrae.nv@gmail.com>
Date: Sat, 16 Jul 2022 21:51:25 -0700
Subject: [PATCH 1/8] refactor(behaviors): Giving global-quick-tap its own term

Detaching the global-quick-tap functionality from the quick-tap term.
This makes way for two improvements:

1. This functionality can be added to combos under a unified name
   'global-quick-tap-ms'.

2. This allows users to set a lower term for the 'global-quick-tap'
   (typically ~100ms), and a higher term for the regular
   quick-tap (typically ~200ms)

This deprecates the global-quick-tap option, however if it is set, the
quick-tap-ms value will be copied to global-quick-tap-ms.
---
 .../behaviors/zmk,behavior-hold-tap.yaml        |  5 ++++-
 app/src/behaviors/behavior_hold_tap.c           | 17 +++++++++++------
 .../1-basic/native_posix_64.keymap              |  2 +-
 .../8-global-quick-tap/behavior_keymap.dtsi     |  2 +-
 .../1-basic/native_posix_64.keymap              |  2 +-
 .../8-global-quick-tap/behavior_keymap.dtsi     |  2 +-
 .../1-basic/native_posix_64.keymap              |  2 +-
 .../2-double-hold/native_posix_64.keymap        |  2 +-
 .../8-global-quick-tap/behavior_keymap.dtsi     |  2 +-
 .../1-basic/native_posix_64.keymap              |  2 +-
 .../6-global-quick-tap/behavior_keymap.dtsi     |  2 +-
 11 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
index a2affbf2147..cca0e96951a 100644
--- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
+++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
@@ -20,8 +20,11 @@ properties:
     default: -1
   quick_tap_ms: # deprecated
     type: int
-  global-quick-tap:
+  global-quick-tap: # deprecated
     type: boolean
+  global-quick-tap-ms:
+    type: int
+    default: -1
   flavor:
     type: string
     required: false
diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c
index 30350ef24ce..1f172e44c46 100644
--- a/app/src/behaviors/behavior_hold_tap.c
+++ b/app/src/behaviors/behavior_hold_tap.c
@@ -57,7 +57,7 @@ struct behavior_hold_tap_config {
     char *hold_behavior_dev;
     char *tap_behavior_dev;
     int quick_tap_ms;
-    bool global_quick_tap;
+    int global_quick_tap_ms;
     enum flavor flavor;
     bool retro_tap;
     bool hold_trigger_on_release;
@@ -97,7 +97,9 @@ struct last_tapped {
     int64_t timestamp;
 };
 
-struct last_tapped last_tapped = {INT32_MIN, INT64_MIN};
+// Set time stamp to large negative number initially for test suites, but not
+// int64 min since it will overflow if -1 is added
+struct last_tapped last_tapped = {INT32_MIN, INT32_MIN};
 
 static void store_last_tapped(int64_t timestamp) {
     if (timestamp > last_tapped.timestamp) {
@@ -112,10 +114,11 @@ static void store_last_hold_tapped(struct active_hold_tap *hold_tap) {
 }
 
 static bool is_quick_tap(struct active_hold_tap *hold_tap) {
-    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;
+    if ((last_tapped.timestamp + hold_tap->config->global_quick_tap_ms) > hold_tap->timestamp) {
+        return true;
     } else {
-        return false;
+        return (last_tapped.position == hold_tap->position) &&
+               (last_tapped.timestamp + hold_tap->config->quick_tap_ms) > hold_tap->timestamp;
     }
 }
 
@@ -703,7 +706,9 @@ static int behavior_hold_tap_init(const struct device *dev) {
         .hold_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 0), label),               \
         .tap_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 1), label),                \
         .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms),                                             \
-        .global_quick_tap = DT_INST_PROP(n, global_quick_tap),                                     \
+        .global_quick_tap_ms = DT_INST_PROP(n, global_quick_tap)                                   \
+                                   ? DT_INST_PROP(n, quick_tap_ms)                                 \
+                                   : DT_INST_PROP(n, global_quick_tap_ms),                         \
         .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor),                                             \
         .retro_tap = DT_INST_PROP(n, retro_tap),                                                   \
         .hold_trigger_on_release = DT_INST_PROP(n, hold_trigger_on_release),                       \
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix_64.keymap
index 5af001f6be1..cdbe51bfe3c 100644
--- a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix_64.keymap
@@ -7,7 +7,7 @@
     events = <
         /* tap */
         ZMK_MOCK_PRESS(0,0,10)
-        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,0,250)
         /* normal quick tap */
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(0,0,400)
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
index ef8efd437d7..8fa363a22e6 100644
--- 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
@@ -11,8 +11,8 @@
             flavor = "balanced";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
+            global-quick-tap-ms = <100>;
             bindings = <&kp>, <&kp>;
-            global-quick-tap;
         };
     };
 
diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
index e28eb4c37e8..a7ba7304c35 100644
--- a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
@@ -7,7 +7,7 @@
     events = <
         /* tap */
         ZMK_MOCK_PRESS(0,0,10)
-        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,0,250)
         /* normal quick tap */
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(0,0,400)
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
index 392a5f83435..8b162bd6a10 100644
--- 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
@@ -11,8 +11,8 @@
             flavor = "hold-preferred";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
+            global-quick-tap-ms = <100>;
             bindings = <&kp>, <&kp>;
-            global-quick-tap;
         };
     };
 
diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
index 5af001f6be1..cdbe51bfe3c 100644
--- a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
@@ -7,7 +7,7 @@
     events = <
         /* tap */
         ZMK_MOCK_PRESS(0,0,10)
-        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,0,250)
         /* normal quick tap */
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(0,0,400)
diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap
index 69d691cee8e..068ae81a8c6 100644
--- a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap
+++ b/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap
@@ -6,7 +6,7 @@
 &kscan {
     events = <
         /* hold the first mod tap */
-        ZMK_MOCK_PRESS(0,0,400)
+        ZMK_MOCK_PRESS(0,0,10)
         /* hold the second mod tap */
         ZMK_MOCK_PRESS(0,1,400)
         /* press the normal key */
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
index 02362ef2b09..9268da077a4 100644
--- 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
@@ -11,8 +11,8 @@
             flavor = "tap-preferred";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
+            global-quick-tap-ms = <100>;
             bindings = <&kp>, <&kp>;
-            global-quick-tap;
         };
     };
 
diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix_64.keymap
index 5af001f6be1..cdbe51bfe3c 100644
--- a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix_64.keymap
@@ -7,7 +7,7 @@
     events = <
         /* tap */
         ZMK_MOCK_PRESS(0,0,10)
-        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,0,250)
         /* normal quick tap */
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(0,0,400)
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
index 029a8128292..0ee84a0d908 100644
--- 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
@@ -11,8 +11,8 @@
             flavor = "tap-unless-interrupted";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
+            global-quick-tap-ms = <100>;
             bindings = <&kp>, <&kp>;
-            global-quick-tap;
         };
     };
 

From 8e69f8c196928bcd82487398916b279179095970 Mon Sep 17 00:00:00 2001
From: Andrew Rae <ajrae.nv@gmail.com>
Date: Mon, 18 Jul 2022 18:27:44 -0700
Subject: [PATCH 2/8] feat(behaviors): Adding global-quick-tap-ms for combos

This brings the 'global-quick-tap' functionality to combos by filtering
out candidate combos that fell within their own quick tap term.

I also replaced `return 0` with `return ZMK_EV_EVENT_BUBBLE` where appropriate.
(I assume this was done in past as it is similar to errno returning, but
being that this is to signify an event type I find this more clear)
---
 app/dts/bindings/zmk,combos.yaml              |  3 +
 app/src/combo.c                               | 50 +++++++++++++--
 .../combo/global-quick-tap/events.patterns    |  1 +
 .../global-quick-tap/keycode_events.snapshot  | 14 ++++
 .../global-quick-tap/native_posix_64.keymap   | 64 +++++++++++++++++++
 5 files changed, 126 insertions(+), 6 deletions(-)
 create mode 100644 app/tests/combo/global-quick-tap/events.patterns
 create mode 100644 app/tests/combo/global-quick-tap/keycode_events.snapshot
 create mode 100644 app/tests/combo/global-quick-tap/native_posix_64.keymap

diff --git a/app/dts/bindings/zmk,combos.yaml b/app/dts/bindings/zmk,combos.yaml
index d094b5c42af..6f6794baa49 100644
--- a/app/dts/bindings/zmk,combos.yaml
+++ b/app/dts/bindings/zmk,combos.yaml
@@ -18,6 +18,9 @@ child-binding:
     timeout-ms:
       type: int
       default: 50
+    global-quick-tap-ms:
+      type: int
+      default: -1
     slow-release:
       type: boolean
     layers:
diff --git a/app/src/combo.c b/app/src/combo.c
index 90c89c15e73..c069994a842 100644
--- a/app/src/combo.c
+++ b/app/src/combo.c
@@ -16,6 +16,7 @@
 #include <zmk/behavior.h>
 #include <zmk/event_manager.h>
 #include <zmk/events/position_state_changed.h>
+#include <zmk/events/keycode_state_changed.h>
 #include <zmk/hid.h>
 #include <zmk/matrix.h>
 #include <zmk/keymap.h>
@@ -30,6 +31,7 @@ struct combo_cfg {
     int32_t key_position_len;
     struct zmk_behavior_binding behavior;
     int32_t timeout_ms;
+    int32_t global_quick_tap_ms;
     // if slow release is set, the combo releases when the last key is released.
     // otherwise, the combo releases when the first key is released.
     bool slow_release;
@@ -72,6 +74,17 @@ int active_combo_count = 0;
 struct k_work_delayable timeout_task;
 int64_t timeout_task_timeout_at;
 
+// this keeps track of the last non-combo, non-mod key tap
+int64_t last_tapped_timestamp = INT32_MIN;
+// this keeps track of the last time a combo was pressed
+int64_t last_combo_timestamp = INT32_MIN;
+
+static void store_last_tapped(int64_t timestamp) {
+    if (timestamp > last_combo_timestamp) {
+        last_tapped_timestamp = timestamp;
+    }
+}
+
 // Store the combo key pointer in the combos array, one pointer for each key position
 // The combos are sorted shortest-first, then by virtual-key-position.
 static int initialize_combo(struct combo_cfg *new_combo) {
@@ -122,6 +135,10 @@ static bool combo_active_on_layer(struct combo_cfg *combo, uint8_t layer) {
     return false;
 }
 
+static bool is_quick_tap(struct combo_cfg *combo, int64_t timestamp) {
+    return (last_tapped_timestamp + combo->global_quick_tap_ms) > timestamp;
+}
+
 static int setup_candidates_for_first_keypress(int32_t position, int64_t timestamp) {
     int number_of_combo_candidates = 0;
     uint8_t highest_active_layer = zmk_keymap_highest_layer_active();
@@ -130,7 +147,7 @@ static int setup_candidates_for_first_keypress(int32_t position, int64_t timesta
         if (combo == NULL) {
             return number_of_combo_candidates;
         }
-        if (combo_active_on_layer(combo, highest_active_layer)) {
+        if (combo_active_on_layer(combo, highest_active_layer) && !is_quick_tap(combo, timestamp)) {
             candidates[number_of_combo_candidates].combo = combo;
             candidates[number_of_combo_candidates].timeout_at = timestamp + combo->timeout_ms;
             number_of_combo_candidates++;
@@ -240,7 +257,7 @@ static int capture_pressed_key(const zmk_event_t *ev) {
         pressed_keys[i] = ev;
         return ZMK_EV_EVENT_CAPTURED;
     }
-    return 0;
+    return ZMK_EV_EVENT_BUBBLE;
 }
 
 const struct zmk_listener zmk_listener_combo;
@@ -272,6 +289,8 @@ static inline int press_combo_behavior(struct combo_cfg *combo, int32_t timestam
         .timestamp = timestamp,
     };
 
+    last_combo_timestamp = timestamp;
+
     return behavior_keymap_binding_pressed(&combo->behavior, event);
 }
 
@@ -401,7 +420,7 @@ static int position_state_down(const zmk_event_t *ev, struct zmk_position_state_
     if (candidates[0].combo == NULL) {
         num_candidates = setup_candidates_for_first_keypress(data->position, data->timestamp);
         if (num_candidates == 0) {
-            return 0;
+            return ZMK_EV_EVENT_BUBBLE;
         }
     } else {
         filter_timed_out_candidates(data->timestamp);
@@ -441,7 +460,7 @@ static int position_state_up(const zmk_event_t *ev, struct zmk_position_state_ch
         ZMK_EVENT_RAISE(ev);
         return ZMK_EV_EVENT_CAPTURED;
     }
-    return 0;
+    return ZMK_EV_EVENT_BUBBLE;
 }
 
 static void combo_timeout_handler(struct k_work *item) {
@@ -458,7 +477,7 @@ static void combo_timeout_handler(struct k_work *item) {
 static int position_state_changed_listener(const zmk_event_t *ev) {
     struct zmk_position_state_changed *data = as_zmk_position_state_changed(ev);
     if (data == NULL) {
-        return 0;
+        return ZMK_EV_EVENT_BUBBLE;
     }
 
     if (data->state) { // keydown
@@ -468,12 +487,31 @@ static int position_state_changed_listener(const zmk_event_t *ev) {
     }
 }
 
-ZMK_LISTENER(combo, position_state_changed_listener);
+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(ev->timestamp);
+    }
+    return ZMK_EV_EVENT_BUBBLE;
+}
+
+int behavior_combo_listener(const zmk_event_t *eh) {
+    if (as_zmk_position_state_changed(eh) != NULL) {
+        return position_state_changed_listener(eh);
+    } else if (as_zmk_keycode_state_changed(eh) != NULL) {
+        return keycode_state_changed_listener(eh);
+    }
+    return ZMK_EV_EVENT_BUBBLE;
+}
+
+ZMK_LISTENER(combo, behavior_combo_listener);
 ZMK_SUBSCRIPTION(combo, zmk_position_state_changed);
+ZMK_SUBSCRIPTION(combo, zmk_keycode_state_changed);
 
 #define COMBO_INST(n)                                                                              \
     static struct combo_cfg combo_config_##n = {                                                   \
         .timeout_ms = DT_PROP(n, timeout_ms),                                                      \
+        .global_quick_tap_ms = DT_PROP(n, global_quick_tap_ms),                                    \
         .key_positions = DT_PROP(n, key_positions),                                                \
         .key_position_len = DT_PROP_LEN(n, key_positions),                                         \
         .behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, n),                                              \
diff --git a/app/tests/combo/global-quick-tap/events.patterns b/app/tests/combo/global-quick-tap/events.patterns
new file mode 100644
index 00000000000..833100f6ac4
--- /dev/null
+++ b/app/tests/combo/global-quick-tap/events.patterns
@@ -0,0 +1 @@
+s/.*hid_listener_keycode_//p
\ No newline at end of file
diff --git a/app/tests/combo/global-quick-tap/keycode_events.snapshot b/app/tests/combo/global-quick-tap/keycode_events.snapshot
new file mode 100644
index 00000000000..ee4dd064c61
--- /dev/null
+++ b/app/tests/combo/global-quick-tap/keycode_events.snapshot
@@ -0,0 +1,14 @@
+pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x1B implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x1B implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x1B implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x1B implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
+pressed: usage_page 0x07 keycode 0x1C implicit_mods 0x00 explicit_mods 0x00
+released: usage_page 0x07 keycode 0x1C implicit_mods 0x00 explicit_mods 0x00
diff --git a/app/tests/combo/global-quick-tap/native_posix_64.keymap b/app/tests/combo/global-quick-tap/native_posix_64.keymap
new file mode 100644
index 00000000000..92b5a8ae88e
--- /dev/null
+++ b/app/tests/combo/global-quick-tap/native_posix_64.keymap
@@ -0,0 +1,64 @@
+#include <dt-bindings/zmk/keys.h>
+#include <behaviors.dtsi>
+#include <dt-bindings/zmk/kscan-mock.h>
+
+/ {
+    combos {
+        compatible = "zmk,combos";
+        combo_one {
+            timeout-ms = <50>;
+            key-positions = <0 1>;
+            bindings = <&kp X>;
+            global-quick-tap-ms = <100>;
+        };
+
+        combo_two {
+            timeout-ms = <50>;
+            key-positions = <0 2>;
+            bindings = <&kp Y>;
+        };
+    };
+
+    keymap {
+        compatible = "zmk,keymap";
+        label ="Default keymap";
+
+        default_layer {
+            bindings = <
+                &kp A &kp B
+                &kp C &kp D
+            >;
+        };
+    };
+};
+
+&kscan {
+    events = <
+        /* Tap A  */
+        ZMK_MOCK_PRESS(0,0,10)
+        ZMK_MOCK_RELEASE(0,0,60)
+        /* Quick Tap A and B */
+        ZMK_MOCK_PRESS(0,0,10)
+        ZMK_MOCK_PRESS(0,1,10)
+        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,1,200)
+        /* Combo One */
+        ZMK_MOCK_PRESS(0,0,10)
+        ZMK_MOCK_PRESS(0,1,10)
+        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,1,10)
+        /* Combo One Again (shouldn't quick tap) */
+        ZMK_MOCK_PRESS(0,0,10)
+        ZMK_MOCK_PRESS(0,1,10)
+        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(0,1,10)
+        /* Tap A  */
+        ZMK_MOCK_PRESS(0,0,10)
+        ZMK_MOCK_RELEASE(0,0,60)
+        /* Combo 2  */
+        ZMK_MOCK_PRESS(0,0,10)
+        ZMK_MOCK_PRESS(1,0,10)
+        ZMK_MOCK_RELEASE(0,0,10)
+        ZMK_MOCK_RELEASE(1,0,10)
+    >;
+};

From f2dc8ee318323fff25f82e3db6cd7210d47d84ef Mon Sep 17 00:00:00 2001
From: Andrew Rae <ajrae.nv@gmail.com>
Date: Sun, 28 May 2023 15:35:51 -0400
Subject: [PATCH 3/8] feat(docs): Adding global-quick-tap-ms docs

---
 docs/docs/behaviors/hold-tap.md | 10 +++++-----
 docs/docs/config/combos.md      | 15 ++++++++-------
 docs/docs/features/combos.md    |  1 +
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md
index 2a8489a15ab..66cf5958224 100644
--- a/docs/docs/behaviors/hold-tap.md
+++ b/docs/docs/behaviors/hold-tap.md
@@ -49,11 +49,11 @@ Defines how long a key must be pressed to trigger Hold behavior.
 
 If you press a tapped hold-tap again within `quick-tap-ms` milliseconds, it will always trigger the tap behavior. This is useful for things like a backspace, where a quick tap+hold holds backspace pressed. Set this to a negative value to disable. The default is -1 (disabled).
 
-#### `global-quick-tap`
+#### `global-quick-tap-ms`
 
-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 tapped before it. This effectively disables the hold-tap when typing quickly, which 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-ms` is like `quick-tap-ms` however it will apply for _any_ key tapped before it. This effectively disables the hold-tap when typing quickly, which can be quite useful for homerow 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 `quick-tap-ms` term.
+For example, the following hold-tap configuration enables `global-quick-tap-ms` with a 125 millisecond term, alongside a regular `quick-tap-ms` with a 200 millisecond term.
 
 ```
 gqt: global-quick-tap {
@@ -62,8 +62,8 @@ gqt: global-quick-tap {
     #binding-cells = <2>;
     flavor = "tap-preferred";
     tapping-term-ms = <200>;
-    quick-tap-ms = <125>;
-    global-quick-tap;
+    quick-tap-ms = <200>;
+    global-quick-tap-ms = <125>;
     bindings = <&kp>, <&kp>;
 };
 ```
diff --git a/docs/docs/config/combos.md b/docs/docs/config/combos.md
index cd351125450..ca80245019e 100644
--- a/docs/docs/config/combos.md
+++ b/docs/docs/config/combos.md
@@ -31,12 +31,13 @@ The `zmk,combos` node itself has no properties. It should have one child node pe
 
 Each child node can have the following properties:
 
-| Property        | Type          | Description                                                                                           | Default |
-| --------------- | ------------- | ----------------------------------------------------------------------------------------------------- | ------- |
-| `bindings`      | phandle-array | A [behavior](../features/keymaps.md#behaviors) to run when the combo is triggered                     |         |
-| `key-positions` | array         | A list of key position indices for the keys which should trigger the combo                            |         |
-| `timeout-ms`    | int           | All the keys in `key-positions` must be pressed within this time in milliseconds to trigger the combo | 50      |
-| `slow-release`  | bool          | Releases the combo when all keys are released instead of when any key is released                     | false   |
-| `layers`        | array         | A list of layers on which the combo may be triggered. `-1` allows all layers.                         | `<-1>`  |
+| Property              | Type          | Description                                                                                                               | Default |
+| --------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- | ------- |
+| `bindings`            | phandle-array | A [behavior](../features/keymaps.md#behaviors) to run when the combo is triggered                                         |         |
+| `key-positions`       | array         | A list of key position indices for the keys which should trigger the combo                                                |         |
+| `timeout-ms`          | int           | All the keys in `key-positions` must be pressed within this time in milliseconds to trigger the combo                     | 50      |
+| `global-quick-tap-ms` | int           | If any key is tapped within `global-quick-tap-ms` before a key in the combo, the key will not be considered for the combo | -1      |
+| `slow-release`        | bool          | Releases the combo when all keys are released instead of when any key is released                                         | false   |
+| `layers`              | array         | A list of layers on which the combo may be triggered. `-1` allows all layers.                                             | `<-1>`  |
 
 The `key-positions` array must not be longer than the `CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO` setting, which defaults to 4. If you want a combo that triggers when pressing 5 keys, then you must change the setting to 5.
diff --git a/docs/docs/features/combos.md b/docs/docs/features/combos.md
index 44313cc1dac..263c1a5383c 100644
--- a/docs/docs/features/combos.md
+++ b/docs/docs/features/combos.md
@@ -30,6 +30,7 @@ Combos configured in your `.keymap` file, but are separate from the `keymap` nod
 - `layers = <0 1...>` will allow limiting a combo to specific layers. This is an _optional_ parameter, when omitted it defaults to global scope.
 - `bindings` is the behavior that is activated when the behavior is pressed.
 - (advanced) you can specify `slow-release` if you want the combo binding to be released when all key-positions are released. The default is to release the combo as soon as any of the keys in the combo is released.
+- (advanced) you can specify `global-quick-tap-ms` much like in [hold-taps](behaviors/hold-tap.md#global-quick-tap-ms). If any key is tapped within `global-quick-tap-ms` before a key in the combo, the key will not be considered for the combo.
 
 :::info
 

From c54acd49fcbe5b4a06433595506aa350a9a24eec Mon Sep 17 00:00:00 2001
From: Andrew Rae <56003701+andrewjrae@users.noreply.github.com>
Date: Sun, 28 May 2023 21:35:02 -0400
Subject: [PATCH 4/8] refactor(docs): Applying suggestions for gqt from
 @caksoylar

Co-authored-by: Cem Aksoylar <caksoylar@users.noreply.github.com>
---
 docs/docs/behaviors/hold-tap.md |  4 ++--
 docs/docs/config/behaviors.md   | 22 +++++++++++-----------
 docs/docs/config/combos.md      | 16 ++++++++--------
 docs/docs/features/combos.md    |  2 +-
 4 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md
index 66cf5958224..e1b1059508a 100644
--- a/docs/docs/behaviors/hold-tap.md
+++ b/docs/docs/behaviors/hold-tap.md
@@ -47,11 +47,11 @@ Defines how long a key must be pressed to trigger Hold behavior.
 
 #### `quick-tap-ms`
 
-If you press a tapped hold-tap again within `quick-tap-ms` milliseconds, it will always trigger the tap behavior. This is useful for things like a backspace, where a quick tap+hold holds backspace pressed. Set this to a negative value to disable. The default is -1 (disabled).
+If you press a tapped hold-tap again within `quick-tap-ms` milliseconds of the first press, it will always trigger the tap behavior. This is useful for things like a backspace, where a quick tap+hold holds backspace pressed. Set this to a negative value to disable. The default is -1 (disabled).
 
 #### `global-quick-tap-ms`
 
-If `global-quick-tap-ms` is like `quick-tap-ms` however it will apply for _any_ key tapped before it. This effectively disables the hold-tap when typing quickly, which can be quite useful for homerow mods. It can also have the effect of removing the input delay when typing quickly.
+`global-quick-tap-ms` is like `quick-tap-ms` however it will apply for _any_ non-modifier key pressed before it. This effectively disables the hold-tap when typing quickly, which can be quite useful for homerow 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-ms` with a 125 millisecond term, alongside a regular `quick-tap-ms` with a 200 millisecond term.
 
diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md
index 60e8b72abca..172a0f13fee 100644
--- a/docs/docs/config/behaviors.md
+++ b/docs/docs/config/behaviors.md
@@ -58,17 +58,17 @@ Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml](htt
 
 Applies to: `compatible = "zmk,behavior-hold-tap"`
 
-| Property                     | Type          | Description                                                                               | Default            |
-| ---------------------------- | ------------- | ----------------------------------------------------------------------------------------- | ------------------ |
-| `label`                      | string        | Unique label for the node                                                                 |                    |
-| `#binding-cells`             | int           | Must be `<2>`                                                                             |                    |
-| `bindings`                   | phandle array | A list of two behaviors (without parameters): one for hold and one for tap                |                    |
-| `flavor`                     | string        | Adjusts how the behavior chooses between hold and tap                                     | `"hold-preferred"` |
-| `tapping-term-ms`            | int           | How long in milliseconds the key must be held to trigger a hold                           |                    |
-| `quick-tap-ms`               | int           | Tap twice within this period (in milliseconds) to trigger a tap, even when held           | -1 (disabled)      |
-| `global-quick-tap`           | bool          | If enabled, `quick-tap-ms` also applies when tapping another key and then this one.       | false              |
-| `retro-tap`                  | bool          | Triggers the tap behavior on release if no other key was pressed during a hold            | false              |
-| `hold-trigger-key-positions` | array         | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap. |                    |
+| Property                     | Type          | Description                                                                                                  | Default            |
+| ---------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------ | ------------------ |
+| `label`                      | string        | Unique label for the node                                                                                    |                    |
+| `#binding-cells`             | int           | Must be `<2>`                                                                                                |                    |
+| `bindings`                   | phandle array | A list of two behaviors (without parameters): one for hold and one for tap                                   |                    |
+| `flavor`                     | string        | Adjusts how the behavior chooses between hold and tap                                                        | `"hold-preferred"` |
+| `tapping-term-ms`            | int           | How long in milliseconds the key must be held to trigger a hold                                              |                    |
+| `quick-tap-ms`               | int           | Tap twice within this period (in milliseconds) to trigger a tap, even when held                              | -1 (disabled)      |
+| `global-quick-tap-ms`        | int           | Triggers a tap immediately if any non-modifier key was pressed within `global-quick-tap-ms` of the hold-tap. | -1 (disabled)      |
+| `retro-tap`                  | bool          | Triggers the tap behavior on release if no other key was pressed during a hold                               | false              |
+| `hold-trigger-key-positions` | array         | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap.                    |                    |
 
 The `flavor` property may be one of:
 
diff --git a/docs/docs/config/combos.md b/docs/docs/config/combos.md
index ca80245019e..33622a7a869 100644
--- a/docs/docs/config/combos.md
+++ b/docs/docs/config/combos.md
@@ -31,13 +31,13 @@ The `zmk,combos` node itself has no properties. It should have one child node pe
 
 Each child node can have the following properties:
 
-| Property              | Type          | Description                                                                                                               | Default |
-| --------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- | ------- |
-| `bindings`            | phandle-array | A [behavior](../features/keymaps.md#behaviors) to run when the combo is triggered                                         |         |
-| `key-positions`       | array         | A list of key position indices for the keys which should trigger the combo                                                |         |
-| `timeout-ms`          | int           | All the keys in `key-positions` must be pressed within this time in milliseconds to trigger the combo                     | 50      |
-| `global-quick-tap-ms` | int           | If any key is tapped within `global-quick-tap-ms` before a key in the combo, the key will not be considered for the combo | -1      |
-| `slow-release`        | bool          | Releases the combo when all keys are released instead of when any key is released                                         | false   |
-| `layers`              | array         | A list of layers on which the combo may be triggered. `-1` allows all layers.                                             | `<-1>`  |
+| Property              | Type          | Description                                                                                                                             | Default       |
+| --------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
+| `bindings`            | phandle-array | A [behavior](../features/keymaps.md#behaviors) to run when the combo is triggered                                                       |               |
+| `key-positions`       | array         | A list of key position indices for the keys which should trigger the combo                                                              |               |
+| `timeout-ms`          | int           | All the keys in `key-positions` must be pressed within this time in milliseconds to trigger the combo                                   | 50            |
+| `global-quick-tap-ms` | int           | If any non-modifier key is pressed within `global-quick-tap-ms` before a key in the combo, the key will not be considered for the combo | -1 (disabled) |
+| `slow-release`        | bool          | Releases the combo when all keys are released instead of when any key is released                                                       | false         |
+| `layers`              | array         | A list of layers on which the combo may be triggered. `-1` allows all layers.                                                           | `<-1>`        |
 
 The `key-positions` array must not be longer than the `CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO` setting, which defaults to 4. If you want a combo that triggers when pressing 5 keys, then you must change the setting to 5.
diff --git a/docs/docs/features/combos.md b/docs/docs/features/combos.md
index 263c1a5383c..5ad061686a2 100644
--- a/docs/docs/features/combos.md
+++ b/docs/docs/features/combos.md
@@ -30,7 +30,7 @@ Combos configured in your `.keymap` file, but are separate from the `keymap` nod
 - `layers = <0 1...>` will allow limiting a combo to specific layers. This is an _optional_ parameter, when omitted it defaults to global scope.
 - `bindings` is the behavior that is activated when the behavior is pressed.
 - (advanced) you can specify `slow-release` if you want the combo binding to be released when all key-positions are released. The default is to release the combo as soon as any of the keys in the combo is released.
-- (advanced) you can specify `global-quick-tap-ms` much like in [hold-taps](behaviors/hold-tap.md#global-quick-tap-ms). If any key is tapped within `global-quick-tap-ms` before a key in the combo, the key will not be considered for the combo.
+- (advanced) you can specify a `global-quick-tap-ms` value much like for [hold-taps](behaviors/hold-tap.md#global-quick-tap-ms). If any non-modifier key is pressed within `global-quick-tap-ms` before a key in the combo, the combo will not trigger.
 
 :::info
 

From 2a5f110cda621dc063dcea63f35c10c69a8b52d1 Mon Sep 17 00:00:00 2001
From: Andrew Rae <ajrae.nv@gmail.com>
Date: Sun, 24 Sep 2023 09:38:45 -0400
Subject: [PATCH 5/8] refactor(behaviors): global-quick-tap ->
 require-prior-idle

Renaming global-quick-tap-ms to require-prior-idle.
---
 .../behaviors/zmk,behavior-hold-tap.yaml      |  2 +-
 app/dts/bindings/zmk,combos.yaml              |  2 +-
 app/src/behaviors/behavior_hold_tap.c         | 10 ++++-----
 app/src/combo.c                               |  6 ++---
 .../events.patterns                           |  0
 .../keycode_events.snapshot                   |  0
 .../native_posix_64.keymap                    |  2 +-
 .../1-basic/events.patterns                   |  0
 .../1-basic/keycode_events.snapshot           |  0
 .../1-basic/native_posix_64.keymap            |  0
 .../2-double-hold/events.patterns             |  0
 .../2-double-hold/keycode_events.snapshot     |  0
 .../2-double-hold/native_posix_64.keymap      |  0
 .../behavior_keymap.dtsi                      |  2 +-
 .../1-basic/events.patterns                   |  0
 .../1-basic/keycode_events.snapshot           |  0
 .../1-basic/native_posix_64.keymap            |  0
 .../2-double-hold/events.patterns             |  0
 .../2-double-hold/keycode_events.snapshot     |  0
 .../2-double-hold/native_posix_64.keymap      |  0
 .../behavior_keymap.dtsi                      |  2 +-
 .../1-basic/events.patterns                   |  0
 .../1-basic/keycode_events.snapshot           |  0
 .../1-basic/native_posix_64.keymap            |  0
 .../2-double-hold/events.patterns             |  0
 .../2-double-hold/keycode_events.snapshot     |  0
 .../2-double-hold/native_posix_64.keymap      |  0
 .../behavior_keymap.dtsi                      |  2 +-
 .../1-basic/events.patterns                   |  0
 .../1-basic/keycode_events.snapshot           |  0
 .../1-basic/native_posix_64.keymap            |  0
 .../2-double-hold/events.patterns             |  0
 .../2-double-hold/keycode_events.snapshot     |  0
 .../2-double-hold/native_posix_64.keymap      |  0
 .../behavior_keymap.dtsi                      |  2 +-
 docs/docs/behaviors/hold-tap.md               | 12 +++++-----
 docs/docs/config/behaviors.md                 | 22 +++++++++----------
 docs/docs/config/combos.md                    | 16 +++++++-------
 docs/docs/features/combos.md                  |  2 +-
 39 files changed, 41 insertions(+), 41 deletions(-)
 rename app/tests/combo/{global-quick-tap => require-prior-idle}/events.patterns (100%)
 rename app/tests/combo/{global-quick-tap => require-prior-idle}/keycode_events.snapshot (100%)
 rename app/tests/combo/{global-quick-tap => require-prior-idle}/native_posix_64.keymap (97%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/1-basic/events.patterns (100%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/1-basic/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/1-basic/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/events.patterns (100%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/balanced/{8-global-quick-tap => 8-require-prior-idle}/behavior_keymap.dtsi (94%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/1-basic/events.patterns (100%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/1-basic/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/1-basic/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/events.patterns (100%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/hold-preferred/{8-global-quick-tap => 8-require-prior-idle}/behavior_keymap.dtsi (94%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/1-basic/events.patterns (100%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/1-basic/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/1-basic/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/events.patterns (100%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/2-double-hold/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/tap-preferred/{8-global-quick-tap => 8-require-prior-idle}/behavior_keymap.dtsi (93%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/1-basic/events.patterns (100%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/1-basic/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/1-basic/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/2-double-hold/events.patterns (100%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/2-double-hold/keycode_events.snapshot (100%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/2-double-hold/native_posix_64.keymap (100%)
 rename app/tests/hold-tap/tap-unless-interrupted/{6-global-quick-tap => 6-require-prior-idle}/behavior_keymap.dtsi (94%)

diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
index cca0e96951a..7a140f9134d 100644
--- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
+++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
@@ -22,7 +22,7 @@ properties:
     type: int
   global-quick-tap: # deprecated
     type: boolean
-  global-quick-tap-ms:
+  require-prior-idle-ms:
     type: int
     default: -1
   flavor:
diff --git a/app/dts/bindings/zmk,combos.yaml b/app/dts/bindings/zmk,combos.yaml
index 6f6794baa49..f146ab7a230 100644
--- a/app/dts/bindings/zmk,combos.yaml
+++ b/app/dts/bindings/zmk,combos.yaml
@@ -18,7 +18,7 @@ child-binding:
     timeout-ms:
       type: int
       default: 50
-    global-quick-tap-ms:
+    require-prior-idle-ms:
       type: int
       default: -1
     slow-release:
diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c
index 1f172e44c46..d4aa0dce036 100644
--- a/app/src/behaviors/behavior_hold_tap.c
+++ b/app/src/behaviors/behavior_hold_tap.c
@@ -57,7 +57,7 @@ struct behavior_hold_tap_config {
     char *hold_behavior_dev;
     char *tap_behavior_dev;
     int quick_tap_ms;
-    int global_quick_tap_ms;
+    int require_prior_idle_ms;
     enum flavor flavor;
     bool retro_tap;
     bool hold_trigger_on_release;
@@ -114,7 +114,7 @@ static void store_last_hold_tapped(struct active_hold_tap *hold_tap) {
 }
 
 static bool is_quick_tap(struct active_hold_tap *hold_tap) {
-    if ((last_tapped.timestamp + hold_tap->config->global_quick_tap_ms) > hold_tap->timestamp) {
+    if ((last_tapped.timestamp + hold_tap->config->require_prior_idle_ms) > hold_tap->timestamp) {
         return true;
     } else {
         return (last_tapped.position == hold_tap->position) &&
@@ -706,9 +706,9 @@ static int behavior_hold_tap_init(const struct device *dev) {
         .hold_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 0), label),               \
         .tap_behavior_dev = DT_PROP(DT_INST_PHANDLE_BY_IDX(n, bindings, 1), label),                \
         .quick_tap_ms = DT_INST_PROP(n, quick_tap_ms),                                             \
-        .global_quick_tap_ms = DT_INST_PROP(n, global_quick_tap)                                   \
-                                   ? DT_INST_PROP(n, quick_tap_ms)                                 \
-                                   : DT_INST_PROP(n, global_quick_tap_ms),                         \
+        .require_prior_idle_ms = DT_INST_PROP(n, global_quick_tap)                                 \
+                                     ? DT_INST_PROP(n, quick_tap_ms)                               \
+                                     : DT_INST_PROP(n, require_prior_idle_ms),                     \
         .flavor = DT_ENUM_IDX(DT_DRV_INST(n), flavor),                                             \
         .retro_tap = DT_INST_PROP(n, retro_tap),                                                   \
         .hold_trigger_on_release = DT_INST_PROP(n, hold_trigger_on_release),                       \
diff --git a/app/src/combo.c b/app/src/combo.c
index c069994a842..31019e5a112 100644
--- a/app/src/combo.c
+++ b/app/src/combo.c
@@ -31,7 +31,7 @@ struct combo_cfg {
     int32_t key_position_len;
     struct zmk_behavior_binding behavior;
     int32_t timeout_ms;
-    int32_t global_quick_tap_ms;
+    int32_t require_prior_idle_ms;
     // if slow release is set, the combo releases when the last key is released.
     // otherwise, the combo releases when the first key is released.
     bool slow_release;
@@ -136,7 +136,7 @@ static bool combo_active_on_layer(struct combo_cfg *combo, uint8_t layer) {
 }
 
 static bool is_quick_tap(struct combo_cfg *combo, int64_t timestamp) {
-    return (last_tapped_timestamp + combo->global_quick_tap_ms) > timestamp;
+    return (last_tapped_timestamp + combo->require_prior_idle_ms) > timestamp;
 }
 
 static int setup_candidates_for_first_keypress(int32_t position, int64_t timestamp) {
@@ -511,7 +511,7 @@ ZMK_SUBSCRIPTION(combo, zmk_keycode_state_changed);
 #define COMBO_INST(n)                                                                              \
     static struct combo_cfg combo_config_##n = {                                                   \
         .timeout_ms = DT_PROP(n, timeout_ms),                                                      \
-        .global_quick_tap_ms = DT_PROP(n, global_quick_tap_ms),                                    \
+        .require_prior_idle_ms = DT_PROP(n, require_prior_idle_ms),                                \
         .key_positions = DT_PROP(n, key_positions),                                                \
         .key_position_len = DT_PROP_LEN(n, key_positions),                                         \
         .behavior = ZMK_KEYMAP_EXTRACT_BINDING(0, n),                                              \
diff --git a/app/tests/combo/global-quick-tap/events.patterns b/app/tests/combo/require-prior-idle/events.patterns
similarity index 100%
rename from app/tests/combo/global-quick-tap/events.patterns
rename to app/tests/combo/require-prior-idle/events.patterns
diff --git a/app/tests/combo/global-quick-tap/keycode_events.snapshot b/app/tests/combo/require-prior-idle/keycode_events.snapshot
similarity index 100%
rename from app/tests/combo/global-quick-tap/keycode_events.snapshot
rename to app/tests/combo/require-prior-idle/keycode_events.snapshot
diff --git a/app/tests/combo/global-quick-tap/native_posix_64.keymap b/app/tests/combo/require-prior-idle/native_posix_64.keymap
similarity index 97%
rename from app/tests/combo/global-quick-tap/native_posix_64.keymap
rename to app/tests/combo/require-prior-idle/native_posix_64.keymap
index 92b5a8ae88e..206b230a7fa 100644
--- a/app/tests/combo/global-quick-tap/native_posix_64.keymap
+++ b/app/tests/combo/require-prior-idle/native_posix_64.keymap
@@ -9,7 +9,7 @@
             timeout-ms = <50>;
             key-positions = <0 1>;
             bindings = <&kp X>;
-            global-quick-tap-ms = <100>;
+            require-prior-idle-ms = <100>;
         };
 
         combo_two {
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/events.patterns b/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/events.patterns
similarity index 100%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/events.patterns
rename to app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/events.patterns
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/keycode_events.snapshot b/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/keycode_events.snapshot
rename to app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/keycode_events.snapshot
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/1-basic/native_posix_64.keymap
rename to app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/native_posix_64.keymap
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/events.patterns b/app/tests/hold-tap/balanced/8-require-prior-idle/2-double-hold/events.patterns
similarity index 100%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/events.patterns
rename to app/tests/hold-tap/balanced/8-require-prior-idle/2-double-hold/events.patterns
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-require-prior-idle/2-double-hold/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/keycode_events.snapshot
rename to app/tests/hold-tap/balanced/8-require-prior-idle/2-double-hold/keycode_events.snapshot
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/native_posix_64.keymap b/app/tests/hold-tap/balanced/8-require-prior-idle/2-double-hold/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/2-double-hold/native_posix_64.keymap
rename to app/tests/hold-tap/balanced/8-require-prior-idle/2-double-hold/native_posix_64.keymap
diff --git a/app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/balanced/8-require-prior-idle/behavior_keymap.dtsi
similarity index 94%
rename from app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi
rename to app/tests/hold-tap/balanced/8-require-prior-idle/behavior_keymap.dtsi
index 8fa363a22e6..670bdcc2650 100644
--- a/app/tests/hold-tap/balanced/8-global-quick-tap/behavior_keymap.dtsi
+++ b/app/tests/hold-tap/balanced/8-require-prior-idle/behavior_keymap.dtsi
@@ -11,7 +11,7 @@
             flavor = "balanced";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
-            global-quick-tap-ms = <100>;
+            require-prior-idle-ms = <100>;
             bindings = <&kp>, <&kp>;
         };
     };
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-require-prior-idle/1-basic/events.patterns
similarity index 100%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/events.patterns
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/events.patterns
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-require-prior-idle/1-basic/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/keycode_events.snapshot
diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
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-require-prior-idle/2-double-hold/events.patterns
similarity index 100%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/events.patterns
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/2-double-hold/events.patterns
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-require-prior-idle/2-double-hold/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/2-double-hold/keycode_events.snapshot
diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap b/app/tests/hold-tap/hold-preferred/8-require-prior-idle/2-double-hold/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/2-double-hold/native_posix_64.keymap
diff --git a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/hold-preferred/8-require-prior-idle/behavior_keymap.dtsi
similarity index 94%
rename from app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi
rename to app/tests/hold-tap/hold-preferred/8-require-prior-idle/behavior_keymap.dtsi
index 8b162bd6a10..a99eb3f56f8 100644
--- a/app/tests/hold-tap/hold-preferred/8-global-quick-tap/behavior_keymap.dtsi
+++ b/app/tests/hold-tap/hold-preferred/8-require-prior-idle/behavior_keymap.dtsi
@@ -11,7 +11,7 @@
             flavor = "hold-preferred";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
-            global-quick-tap-ms = <100>;
+            require-prior-idle-ms = <100>;
             bindings = <&kp>, <&kp>;
         };
     };
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-require-prior-idle/1-basic/events.patterns
similarity index 100%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/events.patterns
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/events.patterns
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-require-prior-idle/1-basic/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/keycode_events.snapshot
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/keycode_events.snapshot
diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/1-basic/native_posix_64.keymap
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
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-require-prior-idle/2-double-hold/events.patterns
similarity index 100%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/events.patterns
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/2-double-hold/events.patterns
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-require-prior-idle/2-double-hold/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/keycode_events.snapshot
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/2-double-hold/keycode_events.snapshot
diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap b/app/tests/hold-tap/tap-preferred/8-require-prior-idle/2-double-hold/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/2-double-hold/native_posix_64.keymap
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/2-double-hold/native_posix_64.keymap
diff --git a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi b/app/tests/hold-tap/tap-preferred/8-require-prior-idle/behavior_keymap.dtsi
similarity index 93%
rename from app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi
rename to app/tests/hold-tap/tap-preferred/8-require-prior-idle/behavior_keymap.dtsi
index 9268da077a4..c66dc934092 100644
--- a/app/tests/hold-tap/tap-preferred/8-global-quick-tap/behavior_keymap.dtsi
+++ b/app/tests/hold-tap/tap-preferred/8-require-prior-idle/behavior_keymap.dtsi
@@ -11,7 +11,7 @@
             flavor = "tap-preferred";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
-            global-quick-tap-ms = <100>;
+            require-prior-idle-ms = <100>;
             bindings = <&kp>, <&kp>;
         };
     };
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-require-prior-idle/1-basic/events.patterns
similarity index 100%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/events.patterns
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/events.patterns
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-require-prior-idle/1-basic/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/keycode_events.snapshot
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/keycode_events.snapshot
diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix_64.keymap b/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/1-basic/native_posix_64.keymap
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/native_posix_64.keymap
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-require-prior-idle/2-double-hold/events.patterns
similarity index 100%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/events.patterns
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/2-double-hold/events.patterns
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-require-prior-idle/2-double-hold/keycode_events.snapshot
similarity index 100%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/keycode_events.snapshot
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/2-double-hold/keycode_events.snapshot
diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/native_posix_64.keymap b/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/2-double-hold/native_posix_64.keymap
similarity index 100%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/2-double-hold/native_posix_64.keymap
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/2-double-hold/native_posix_64.keymap
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-require-prior-idle/behavior_keymap.dtsi
similarity index 94%
rename from app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/behavior_keymap.dtsi
rename to app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/behavior_keymap.dtsi
index 0ee84a0d908..7aa3940833f 100644
--- a/app/tests/hold-tap/tap-unless-interrupted/6-global-quick-tap/behavior_keymap.dtsi
+++ b/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/behavior_keymap.dtsi
@@ -11,7 +11,7 @@
             flavor = "tap-unless-interrupted";
             tapping-term-ms = <300>;
             quick-tap-ms = <300>;
-            global-quick-tap-ms = <100>;
+            require-prior-idle-ms = <100>;
             bindings = <&kp>, <&kp>;
         };
     };
diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md
index e1b1059508a..e8192f684b1 100644
--- a/docs/docs/behaviors/hold-tap.md
+++ b/docs/docs/behaviors/hold-tap.md
@@ -49,11 +49,11 @@ Defines how long a key must be pressed to trigger Hold behavior.
 
 If you press a tapped hold-tap again within `quick-tap-ms` milliseconds of the first press, it will always trigger the tap behavior. This is useful for things like a backspace, where a quick tap+hold holds backspace pressed. Set this to a negative value to disable. The default is -1 (disabled).
 
-#### `global-quick-tap-ms`
+#### `require-prior-idle-ms`
 
-`global-quick-tap-ms` is like `quick-tap-ms` however it will apply for _any_ non-modifier key pressed before it. This effectively disables the hold-tap when typing quickly, which can be quite useful for homerow mods. It can also have the effect of removing the input delay when typing quickly.
+`require-prior-idle-ms` is like `quick-tap-ms` however it will apply for _any_ non-modifier key pressed before it. This effectively disables the hold-tap when typing quickly, which can be quite useful for homerow 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-ms` with a 125 millisecond term, alongside a regular `quick-tap-ms` with a 200 millisecond term.
+For example, the following hold-tap configuration enables `require-prior-idle-ms` with a 125 millisecond term, alongside `quick-tap-ms` with a 200 millisecond term.
 
 ```
 gqt: global-quick-tap {
@@ -63,14 +63,14 @@ gqt: global-quick-tap {
     flavor = "tap-preferred";
     tapping-term-ms = <200>;
     quick-tap-ms = <200>;
-    global-quick-tap-ms = <125>;
+    require-prior-idle-ms = <125>;
     bindings = <&kp>, <&kp>;
 };
 ```
 
-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.
+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 `require-prior-idle-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 greater the value of `quick-tap-ms` is, the harder it will be to invoke the hold behavior, making this feature less applicable for use-cases like capitalizing letters while typing normally. However, if the hold behavior isn't used during fast typing, then it can be an effective way to mitigate misfires.
+Note that the greater the value of `require-prior-idle-ms` is, the harder it will be to invoke the hold behavior, making this feature less applicable for use-cases like capitalizing letters 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`
 
diff --git a/docs/docs/config/behaviors.md b/docs/docs/config/behaviors.md
index 172a0f13fee..f3f1f563ec8 100644
--- a/docs/docs/config/behaviors.md
+++ b/docs/docs/config/behaviors.md
@@ -58,17 +58,17 @@ Definition file: [zmk/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml](htt
 
 Applies to: `compatible = "zmk,behavior-hold-tap"`
 
-| Property                     | Type          | Description                                                                                                  | Default            |
-| ---------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------ | ------------------ |
-| `label`                      | string        | Unique label for the node                                                                                    |                    |
-| `#binding-cells`             | int           | Must be `<2>`                                                                                                |                    |
-| `bindings`                   | phandle array | A list of two behaviors (without parameters): one for hold and one for tap                                   |                    |
-| `flavor`                     | string        | Adjusts how the behavior chooses between hold and tap                                                        | `"hold-preferred"` |
-| `tapping-term-ms`            | int           | How long in milliseconds the key must be held to trigger a hold                                              |                    |
-| `quick-tap-ms`               | int           | Tap twice within this period (in milliseconds) to trigger a tap, even when held                              | -1 (disabled)      |
-| `global-quick-tap-ms`        | int           | Triggers a tap immediately if any non-modifier key was pressed within `global-quick-tap-ms` of the hold-tap. | -1 (disabled)      |
-| `retro-tap`                  | bool          | Triggers the tap behavior on release if no other key was pressed during a hold                               | false              |
-| `hold-trigger-key-positions` | array         | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap.                    |                    |
+| Property                     | Type          | Description                                                                                                    | Default            |
+| ---------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------- | ------------------ |
+| `label`                      | string        | Unique label for the node                                                                                      |                    |
+| `#binding-cells`             | int           | Must be `<2>`                                                                                                  |                    |
+| `bindings`                   | phandle array | A list of two behaviors (without parameters): one for hold and one for tap                                     |                    |
+| `flavor`                     | string        | Adjusts how the behavior chooses between hold and tap                                                          | `"hold-preferred"` |
+| `tapping-term-ms`            | int           | How long in milliseconds the key must be held to trigger a hold                                                |                    |
+| `quick-tap-ms`               | int           | Tap twice within this period (in milliseconds) to trigger a tap, even when held                                | -1 (disabled)      |
+| `require-prior-idle-ms`      | int           | Triggers a tap immediately if any non-modifier key was pressed within `require-prior-idle-ms` of the hold-tap. | -1 (disabled)      |
+| `retro-tap`                  | bool          | Triggers the tap behavior on release if no other key was pressed during a hold                                 | false              |
+| `hold-trigger-key-positions` | array         | If set, pressing the hold-tap and then any key position _not_ in the list triggers a tap.                      |                    |
 
 The `flavor` property may be one of:
 
diff --git a/docs/docs/config/combos.md b/docs/docs/config/combos.md
index 33622a7a869..4f5ebba3d34 100644
--- a/docs/docs/config/combos.md
+++ b/docs/docs/config/combos.md
@@ -31,13 +31,13 @@ The `zmk,combos` node itself has no properties. It should have one child node pe
 
 Each child node can have the following properties:
 
-| Property              | Type          | Description                                                                                                                             | Default       |
-| --------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
-| `bindings`            | phandle-array | A [behavior](../features/keymaps.md#behaviors) to run when the combo is triggered                                                       |               |
-| `key-positions`       | array         | A list of key position indices for the keys which should trigger the combo                                                              |               |
-| `timeout-ms`          | int           | All the keys in `key-positions` must be pressed within this time in milliseconds to trigger the combo                                   | 50            |
-| `global-quick-tap-ms` | int           | If any non-modifier key is pressed within `global-quick-tap-ms` before a key in the combo, the key will not be considered for the combo | -1 (disabled) |
-| `slow-release`        | bool          | Releases the combo when all keys are released instead of when any key is released                                                       | false         |
-| `layers`              | array         | A list of layers on which the combo may be triggered. `-1` allows all layers.                                                           | `<-1>`        |
+| Property                | Type          | Description                                                                                                                               | Default       |
+| ----------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
+| `bindings`              | phandle-array | A [behavior](../features/keymaps.md#behaviors) to run when the combo is triggered                                                         |               |
+| `key-positions`         | array         | A list of key position indices for the keys which should trigger the combo                                                                |               |
+| `timeout-ms`            | int           | All the keys in `key-positions` must be pressed within this time in milliseconds to trigger the combo                                     | 50            |
+| `require-prior-idle-ms` | int           | If any non-modifier key is pressed within `require-prior-idle-ms` before a key in the combo, the key will not be considered for the combo | -1 (disabled) |
+| `slow-release`          | bool          | Releases the combo when all keys are released instead of when any key is released                                                         | false         |
+| `layers`                | array         | A list of layers on which the combo may be triggered. `-1` allows all layers.                                                             | `<-1>`        |
 
 The `key-positions` array must not be longer than the `CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO` setting, which defaults to 4. If you want a combo that triggers when pressing 5 keys, then you must change the setting to 5.
diff --git a/docs/docs/features/combos.md b/docs/docs/features/combos.md
index 5ad061686a2..bc1353b416e 100644
--- a/docs/docs/features/combos.md
+++ b/docs/docs/features/combos.md
@@ -30,7 +30,7 @@ Combos configured in your `.keymap` file, but are separate from the `keymap` nod
 - `layers = <0 1...>` will allow limiting a combo to specific layers. This is an _optional_ parameter, when omitted it defaults to global scope.
 - `bindings` is the behavior that is activated when the behavior is pressed.
 - (advanced) you can specify `slow-release` if you want the combo binding to be released when all key-positions are released. The default is to release the combo as soon as any of the keys in the combo is released.
-- (advanced) you can specify a `global-quick-tap-ms` value much like for [hold-taps](behaviors/hold-tap.md#global-quick-tap-ms). If any non-modifier key is pressed within `global-quick-tap-ms` before a key in the combo, the combo will not trigger.
+- (advanced) you can specify a `require-prior-idle-ms` value much like for [hold-taps](behaviors/hold-tap.md#require-prior-idle-ms). If any non-modifier key is pressed within `require-prior-idle-ms` before a key in the combo, the combo will not trigger.
 
 :::info
 

From f6aa320ac6ae0b4c4dcb670d5eef412c4269a7b9 Mon Sep 17 00:00:00 2001
From: Andrew Rae <ajrae.nv@gmail.com>
Date: Sun, 24 Sep 2023 10:19:58 -0400
Subject: [PATCH 6/8] fix(tests): Updating old tests includes

---
 app/tests/combo/require-prior-idle/native_posix_64.keymap | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/tests/combo/require-prior-idle/native_posix_64.keymap b/app/tests/combo/require-prior-idle/native_posix_64.keymap
index 206b230a7fa..fcd94056c4d 100644
--- a/app/tests/combo/require-prior-idle/native_posix_64.keymap
+++ b/app/tests/combo/require-prior-idle/native_posix_64.keymap
@@ -1,6 +1,6 @@
 #include <dt-bindings/zmk/keys.h>
 #include <behaviors.dtsi>
-#include <dt-bindings/zmk/kscan-mock.h>
+#include <dt-bindings/zmk/kscan_mock.h>
 
 / {
     combos {

From b87d2372568dcf963e4547997800ad88c8f4b922 Mon Sep 17 00:00:00 2001
From: Andrew Rae <56003701+andrewjrae@users.noreply.github.com>
Date: Mon, 25 Sep 2023 09:15:57 -0400
Subject: [PATCH 7/8] refactor(docs): Apply suggestions from @caksoylar

Co-authored-by: Cem Aksoylar <caksoylar@users.noreply.github.com>
---
 docs/docs/behaviors/hold-tap.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md
index e8192f684b1..d9d86cea4a5 100644
--- a/docs/docs/behaviors/hold-tap.md
+++ b/docs/docs/behaviors/hold-tap.md
@@ -56,7 +56,7 @@ If you press a tapped hold-tap again within `quick-tap-ms` milliseconds of the f
 For example, the following hold-tap configuration enables `require-prior-idle-ms` with a 125 millisecond term, alongside `quick-tap-ms` with a 200 millisecond term.
 
 ```
-gqt: global-quick-tap {
+rpi: require_prior_idle {
     compatible = "zmk,behavior-hold-tap";
     label = "GLOBAL_QUICK_TAP";
     #binding-cells = <2>;
@@ -68,7 +68,7 @@ gqt: global-quick-tap {
 };
 ```
 
-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 `require-prior-idle-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.
+If you press `&kp A` and then `&rpi LEFT_SHIFT B` **within** 125 ms, then `ab` will be output. Importantly, `b` will be output immediately since it was within the `require-prior-idle-ms`, without waiting for a timeout or an interrupting key. In other words, the `&rpi LEFT_SHIFT B` binding will only have its underlying hold-tap behavior if it is pressed 125 ms **after** the previous key press; otherwise it will act like `&kp B`.
 
 Note that the greater the value of `require-prior-idle-ms` is, the harder it will be to invoke the hold behavior, making this feature less applicable for use-cases like capitalizing letters while typing normally. However, if the hold behavior isn't used during fast typing, then it can be an effective way to mitigate misfires.
 

From 48c9a8a950a71b59e1371a25bbc1974ee8347407 Mon Sep 17 00:00:00 2001
From: Andrew Rae <ajrae.nv@gmail.com>
Date: Tue, 26 Sep 2023 22:00:23 -0400
Subject: [PATCH 8/8] refactor(behaviors): Final global-quick-tap deprecation.

---
 app/boards/shields/cradio/cradio.keymap                  | 2 +-
 app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml    | 9 ++++++---
 .../8-require-prior-idle/1-basic/native_posix_64.keymap  | 2 +-
 .../8-require-prior-idle/1-basic/native_posix_64.keymap  | 2 +-
 .../8-require-prior-idle/1-basic/native_posix_64.keymap  | 2 +-
 .../6-require-prior-idle/1-basic/native_posix_64.keymap  | 2 +-
 docs/docs/behaviors/hold-tap.md                          | 2 +-
 7 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/app/boards/shields/cradio/cradio.keymap b/app/boards/shields/cradio/cradio.keymap
index 3f6670da725..47bf0422a5a 100644
--- a/app/boards/shields/cradio/cradio.keymap
+++ b/app/boards/shields/cradio/cradio.keymap
@@ -18,7 +18,7 @@
             flavor = "tap-preferred";
             tapping-term-ms = <220>;
             quick-tap-ms = <150>;
-            global-quick-tap;
+            require-prior-idle-ms = <100>;
             bindings = <&kp>, <&kp>;
         };
     };
diff --git a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
index 7a140f9134d..575754116b1 100644
--- a/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
+++ b/app/dts/bindings/behaviors/zmk,behavior-hold-tap.yaml
@@ -13,15 +13,18 @@ properties:
     required: true
   tapping-term-ms:
     type: int
-  tapping_term_ms: # deprecated
+  tapping_term_ms:
     type: int
+    deprecated: true
   quick-tap-ms:
     type: int
     default: -1
-  quick_tap_ms: # deprecated
+  quick_tap_ms:
     type: int
-  global-quick-tap: # deprecated
+    deprecated: true
+  global-quick-tap:
     type: boolean
+    deprecated: true
   require-prior-idle-ms:
     type: int
     default: -1
diff --git a/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/native_posix_64.keymap b/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/native_posix_64.keymap
index cdbe51bfe3c..aa629498073 100644
--- a/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/balanced/8-require-prior-idle/1-basic/native_posix_64.keymap
@@ -16,7 +16,7 @@
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_RELEASE(1,0,10)
         ZMK_MOCK_RELEASE(0,0,400)
-        /* global quick tap */
+        /* require-prior-idle */
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(1,0,10)
diff --git a/app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap b/app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
index a7ba7304c35..6db79abc381 100644
--- a/app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/hold-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
@@ -16,7 +16,7 @@
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_RELEASE(1,0,10)
         ZMK_MOCK_RELEASE(0,0,400)
-        /* global quick tap */
+        /* require-prior-idle */
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(1,0,10)
diff --git a/app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap b/app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
index cdbe51bfe3c..aa629498073 100644
--- a/app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/tap-preferred/8-require-prior-idle/1-basic/native_posix_64.keymap
@@ -16,7 +16,7 @@
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_RELEASE(1,0,10)
         ZMK_MOCK_RELEASE(0,0,400)
-        /* global quick tap */
+        /* require-prior-idle */
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(1,0,10)
diff --git a/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/native_posix_64.keymap b/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/native_posix_64.keymap
index cdbe51bfe3c..aa629498073 100644
--- a/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/native_posix_64.keymap
+++ b/app/tests/hold-tap/tap-unless-interrupted/6-require-prior-idle/1-basic/native_posix_64.keymap
@@ -16,7 +16,7 @@
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_RELEASE(1,0,10)
         ZMK_MOCK_RELEASE(0,0,400)
-        /* global quick tap */
+        /* require-prior-idle */
         ZMK_MOCK_PRESS(1,0,10)
         ZMK_MOCK_PRESS(0,0,400)
         ZMK_MOCK_RELEASE(1,0,10)
diff --git a/docs/docs/behaviors/hold-tap.md b/docs/docs/behaviors/hold-tap.md
index d9d86cea4a5..ec66b34f2af 100644
--- a/docs/docs/behaviors/hold-tap.md
+++ b/docs/docs/behaviors/hold-tap.md
@@ -58,7 +58,7 @@ For example, the following hold-tap configuration enables `require-prior-idle-ms
 ```
 rpi: require_prior_idle {
     compatible = "zmk,behavior-hold-tap";
-    label = "GLOBAL_QUICK_TAP";
+    label = "REQUIRE_PRIOR_IDLE";
     #binding-cells = <2>;
     flavor = "tap-preferred";
     tapping-term-ms = <200>;