summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorprecondition <57645186+precondition@users.noreply.github.com>2022-12-13 12:20:07 +0100
committerGitHub <noreply@github.com>2022-12-13 22:20:07 +1100
commit515dd18c2801663bbac0e59f683c2a93e4bd9b1a (patch)
treea60fa641a1d5e0e3ff08fbb0a6718c8aa5280f15
parentca13734f912e64c632daf816e700b1b176d0ac8e (diff)
Remove IGNORE_MOD_TAP_INTERRUPT_PER_KEY in favour of HOLD_ON_OTHER_KEY_PRESS_PER_KEY (#15741)
-rw-r--r--data/mappings/info_config.hjson4
-rw-r--r--data/schemas/keyboard.jsonschema1
-rw-r--r--docs/ChangeLog/20230226/PR15741.md43
-rw-r--r--docs/config_options.md7
-rw-r--r--docs/feature_auto_shift.md11
-rw-r--r--docs/ja/config_options.md2
-rw-r--r--docs/ja/tap_hold.md19
-rw-r--r--docs/tap_hold.md93
-rw-r--r--keyboards/adm42/rev4/keymaps/default/config.h1
-rw-r--r--keyboards/adm42/rev4/keymaps/default/keymap.c18
-rw-r--r--keyboards/bastardkb/scylla/keymaps/cykedev/config.h7
-rw-r--r--keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c13
-rw-r--r--keyboards/converter/usb_usb/keymaps/chriskopher/config.h3
-rw-r--r--keyboards/converter/usb_usb/keymaps/chriskopher/keymap.c10
-rw-r--r--keyboards/crkbd/keymaps/snowe/config.h1
-rw-r--r--keyboards/crkbd/keymaps/snowe/keymap.c10
-rw-r--r--keyboards/ergodox_ez/keymaps/stamm/config.h4
-rw-r--r--keyboards/ergodox_ez/keymaps/stamm/keymap.c4
-rw-r--r--keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/config.h5
-rw-r--r--keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/keymap.c12
-rw-r--r--keyboards/lily58/keymaps/cykedev/config.h2
-rw-r--r--keyboards/lily58/keymaps/cykedev/keymap.c4
-rw-r--r--keyboards/planck/keymaps/adamtabrams/config.h4
-rw-r--r--keyboards/planck/keymaps/adamtabrams/keymap.c4
-rw-r--r--keyboards/planck/keymaps/rootiest/config.h2
-rw-r--r--keyboards/planck/keymaps/rootiest/keymap.c6
-rw-r--r--keyboards/torn/keymaps/kinesish/config.h2
-rw-r--r--keyboards/torn/keymaps/kinesish/keymap.c12
-rw-r--r--quantum/action.c10
-rw-r--r--quantum/action_tapping.c14
-rw-r--r--quantum/process_keycode/process_auto_shift.c41
-rw-r--r--tests/tap_hold_configurations/default_mod_tap/config.h2
-rw-r--r--tests/tap_hold_configurations/default_mod_tap/test_tap_hold.cpp2
-rw-r--r--tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h21
-rw-r--r--tests/tap_hold_configurations/ignore_mod_tap_interrupt/test.mk18
-rw-r--r--tests/tap_hold_configurations/ignore_mod_tap_interrupt/test_tap_hold.cpp136
-rw-r--r--tests/tap_hold_configurations/permissive_hold/test_tap_hold.cpp2
-rw-r--r--tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/config.h22
-rw-r--r--tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test.mk18
-rw-r--r--tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp133
-rw-r--r--users/drashna/config.h1
-rw-r--r--users/drashna/keyrecords/tapping.c15
42 files changed, 224 insertions, 515 deletions
diff --git a/data/mappings/info_config.hjson b/data/mappings/info_config.hjson
index 479b1579da..7645598c77 100644
--- a/data/mappings/info_config.hjson
+++ b/data/mappings/info_config.hjson
@@ -32,8 +32,6 @@
32 "FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"}, 32 "FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"},
33 "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR": {"info_key": "dynamic_keymap.eeprom_max_addr", "value_type": "int"}, 33 "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR": {"info_key": "dynamic_keymap.eeprom_max_addr", "value_type": "int"},
34 "DYNAMIC_KEYMAP_LAYER_COUNT": {"info_key": "dynamic_keymap.layer_count", "value_type": "int"}, 34 "DYNAMIC_KEYMAP_LAYER_COUNT": {"info_key": "dynamic_keymap.layer_count", "value_type": "int"},
35 "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "tapping.ignore_mod_tap_interrupt", "value_type": "bool"},
36 "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "tapping.ignore_mod_tap_interrupt_per_key", "value_type": "bool"},
37 "HOLD_ON_OTHER_KEY_PRESS": {"info_key": "tapping.hold_on_other_key_press", "value_type": "bool"}, 35 "HOLD_ON_OTHER_KEY_PRESS": {"info_key": "tapping.hold_on_other_key_press", "value_type": "bool"},
38 "HOLD_ON_OTHER_KEY_PRESS_PER_KEY": {"info_key": "tapping.hold_on_other_key_press_per_key", "value_type": "bool"}, 36 "HOLD_ON_OTHER_KEY_PRESS_PER_KEY": {"info_key": "tapping.hold_on_other_key_press_per_key", "value_type": "bool"},
39 "LAYOUTS": {"info_key": "layout_aliases", "value_type": "mapping"}, 37 "LAYOUTS": {"info_key": "layout_aliases", "value_type": "mapping"},
@@ -129,6 +127,8 @@
129 "QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true}, 127 "QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true},
130 "TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true}, 128 "TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true},
131 "TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true}, 129 "TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true},
130 "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "_deprecated.ignore_mod_tap_interrupt", "value_type": "bool", "deprecated": true},
131 "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true}
132 132
133 // USB params, need to mark as failure when specified in config.h, rather than deprecated 133 // USB params, need to mark as failure when specified in config.h, rather than deprecated
134 "PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.pid` in info.json"}, 134 "PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.pid` in info.json"},
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index 7844bfd579..513564a643 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -620,7 +620,6 @@
620 "force_hold": {"type": "boolean"}, 620 "force_hold": {"type": "boolean"},
621 "force_hold_per_key": {"type": "boolean"}, 621 "force_hold_per_key": {"type": "boolean"},
622 "ignore_mod_tap_interrupt": {"type": "boolean"}, 622 "ignore_mod_tap_interrupt": {"type": "boolean"},
623 "ignore_mod_tap_interrupt_per_key": {"type": "boolean"},
624 "hold_on_other_key_press": {"type": "boolean"}, 623 "hold_on_other_key_press": {"type": "boolean"},
625 "hold_on_other_key_press_per_key": {"type": "boolean"}, 624 "hold_on_other_key_press_per_key": {"type": "boolean"},
626 "permissive_hold": {"type": "boolean"}, 625 "permissive_hold": {"type": "boolean"},
diff --git a/docs/ChangeLog/20230226/PR15741.md b/docs/ChangeLog/20230226/PR15741.md
new file mode 100644
index 0000000000..385816d65b
--- /dev/null
+++ b/docs/ChangeLog/20230226/PR15741.md
@@ -0,0 +1,43 @@
1`IGNORE_MOD_TAP_INTERRUPT_PER_KEY` has been removed and `IGNORE_MOD_TAP_INTERRUPT` deprecated as a stepping stone towards making `IGNORE_MOD_TAP_INTERRUPT` the new default behavior for mod-taps in the future.
2
3In place of the now removed `IGNORE_MOD_TAP_INTERRUPT_PER_KEY`, one must use the pre-existing `HOLD_ON_OTHER_KEY_PRESS` option.
4
5In most cases, updating `get_ignore_mod_tap_interrupt` to `get_hold_on_other_key_press` is simply a matter of renaming the function and swapping every `true` by `false` and vice versa. The one subtlety you may need to look out for is that the `get_ignore_mod_tap_interrupt` was only ever called with mod-taps passed in as the `keycode` argument, while the `keycode` argument of `get_hold_on_other_key_press` can be any dual-role key. This includes not only mod-taps, but also layer-taps, one shot keys, `TT(layer)` and more. This has an impact on the effect of the `default` case in a typical per-key configuration making use of a `switch(keycode)` statement.
6
7To illustrate, let's take the example of a configuration where we'd want all mod-taps to activate the modifier if another key is pressed while held with the exception of `LCTL_T(KC_A)`, which should ignore keys pressed while it is held and activate the modifier only if it has been held for longer than the tapping term. In addition, we would like to keep the default "ignore-interrupt" behavior of layer taps.
8
9An old way to do this would be via the following code:
10
11```c
12bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
13 switch(keycode) {
14 case LCTL_T(KC_A):
15 return true;
16 default:
17 return false;
18 }
19}
20```
21
22The correct way to update this code without accidentally changing how the layer-taps work would be the following:
23
24```c
25bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
26 switch(keycode) {
27 // Capture all mod-tap keycodes.
28 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
29 if (keycode == LCTL_T(KC_A)) {
30 // Disable HOLD_ON_OTHER_KEY_PRESS for LCTL_T(KC_A)
31 // aka enable IGNORE_MOD_TAP_INTERRUPT for LCTL_T(KC_A).
32 return false;
33 } else {
34 // Enable HOLD_ON_OTHER_KEY_PRESS for every other mod-tap keycode.
35 return true;
36 }
37 default:
38 return false;
39 }
40}
41```
42
43For more information, you are invited to read the sections on [IGNORE_MOD_TAP_INTERRUPT](tap_hold.md#ignore-mod-tap-interrupt) and [HOLD_ON_OTHER_KEY_PRESS](tap_hold.md#hold-on-other-key-press) in the page on [Tap-Hold configuration options](tap_hold.md).
diff --git a/docs/config_options.md b/docs/config_options.md
index edaa739201..7a91160bcd 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -169,8 +169,6 @@ If you define these options you will enable the associated feature, which may in
169* `#define IGNORE_MOD_TAP_INTERRUPT` 169* `#define IGNORE_MOD_TAP_INTERRUPT`
170 * makes it possible to do rolling combos (zx) with keys that convert to other keys on hold, by enforcing the `TAPPING_TERM` for both keys. 170 * makes it possible to do rolling combos (zx) with keys that convert to other keys on hold, by enforcing the `TAPPING_TERM` for both keys.
171 * See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for details 171 * See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for details
172* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
173 * enables handling for per key `IGNORE_MOD_TAP_INTERRUPT` settings
174* `#define QUICK_TAP_TERM 100` 172* `#define QUICK_TAP_TERM 100`
175 * tap-then-hold timing to use a dual role key to repeat keycode 173 * tap-then-hold timing to use a dual role key to repeat keycode
176 * See [Quick Tap Term](tap_hold.md#quick-tap-term) 174 * See [Quick Tap Term](tap_hold.md#quick-tap-term)
@@ -178,6 +176,11 @@ If you define these options you will enable the associated feature, which may in
178 * Defaults to `TAPPING_TERM` if not defined 176 * Defaults to `TAPPING_TERM` if not defined
179* `#define QUICK_TAP_TERM_PER_KEY` 177* `#define QUICK_TAP_TERM_PER_KEY`
180 * enables handling for per key `QUICK_TAP_TERM` settings 178 * enables handling for per key `QUICK_TAP_TERM` settings
179* `#define HOLD_ON_OTHER_KEY_PRESS`
180 * selects the hold action of a dual-role key as soon as the tap of the dual-role key is interrupted by the press of another key.
181 * See "[hold on other key press](tap_hold.md#hold-on-other-key-press)" for details
182* `#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY`
183 * enables handling for per key `HOLD_ON_OTHER_KEY_PRESS` settings
181* `#define LEADER_TIMEOUT 300` 184* `#define LEADER_TIMEOUT 300`
182 * how long before the leader key times out 185 * how long before the leader key times out
183 * If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped. 186 * If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped.
diff --git a/docs/feature_auto_shift.md b/docs/feature_auto_shift.md
index d3437a9c60..1719807e26 100644
--- a/docs/feature_auto_shift.md
+++ b/docs/feature_auto_shift.md
@@ -281,16 +281,7 @@ Tap Hold Configurations work a little differently when using Retro Shift.
281Referencing `TAPPING_TERM` makes little sense, as holding longer would result in 281Referencing `TAPPING_TERM` makes little sense, as holding longer would result in
282shifting one of the keys. 282shifting one of the keys.
283 283
284`IGNORE_MOD_TAP_INTERRUPT` changes *only* rolling from a mod tap (releasing it 284`RETRO_SHIFT` enables [`PERMISSIVE_HOLD`-like behaviour](tap_hold.md#permissive-hold) (even if not explicitly enabled) on all mod-taps for which `RETRO_SHIFT` applies.
285first), sending both keys instead of the modifier on the second. Its effects on
286nested presses are ignored.
287
288As nested taps were changed to act as though `PERMISSIVE_HOLD` is set unless only
289`IGNORE_MOD_TAP_INTERRUPT` is (outside of Retro Shift), and Retro Shift ignores
290`IGNORE_MOD_TAP_INTERRUPT`, `PERMISSIVE_HOLD` has no effect on Mod Taps.
291
292Nested taps will *always* act as though the `TAPPING_TERM` was exceeded for both
293Mod and Layer Tap keys.
294 285
295## Using Auto Shift Setup 286## Using Auto Shift Setup
296 287
diff --git a/docs/ja/config_options.md b/docs/ja/config_options.md
index c95753bd5d..6135721a42 100644
--- a/docs/ja/config_options.md
+++ b/docs/ja/config_options.md
@@ -162,8 +162,6 @@ QMK での全ての利用可能な設定にはデフォルトがあります。
162* `#define IGNORE_MOD_TAP_INTERRUPT` 162* `#define IGNORE_MOD_TAP_INTERRUPT`
163 * 両方のキーに `TAPPING_TERM` を適用することで、ホールド時に他のキーに変換するキーを使ってローリングコンボ (zx) をすることができるようにします 163 * 両方のキーに `TAPPING_TERM` を適用することで、ホールド時に他のキーに変換するキーを使ってローリングコンボ (zx) をすることができるようにします
164 * 詳細は [Ignore Mod Tap Interrupt](ja/tap_hold.md#ignore-mod-tap-interrupt) を見てください 164 * 詳細は [Ignore Mod Tap Interrupt](ja/tap_hold.md#ignore-mod-tap-interrupt) を見てください
165* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
166 * キーごとの `IGNORE_MOD_TAP_INTERRUPT` 設定の処理を有効にします
167* `#define TAPPING_FORCE_HOLD` 165* `#define TAPPING_FORCE_HOLD`
168 * タップされた直後に、デュアルロールキーを修飾子として使用できるようにします 166 * タップされた直後に、デュアルロールキーを修飾子として使用できるようにします
169 * [Tapping Force Hold](ja/tap_hold.md#tapping-force-hold)を見てください 167 * [Tapping Force Hold](ja/tap_hold.md#tapping-force-hold)を見てください
diff --git a/docs/ja/tap_hold.md b/docs/ja/tap_hold.md
index 07242821a9..ac64fe6ce3 100644
--- a/docs/ja/tap_hold.md
+++ b/docs/ja/tap_hold.md
@@ -110,25 +110,6 @@ bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
110 110
111?> `許容ホールド`を有効にすると、これは両方がどのように動作するかを変更します。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。 111?> `許容ホールド`を有効にすると、これは両方がどのように動作するかを変更します。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。
112 112
113この機能をより細かく制御するために、以下を `config.h` に追加することができます:
114
115```c
116#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
117```
118
119そして、以下の関数をキーマップに追加します:
120
121```c
122bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
123 switch (keycode) {
124 case SFT_T(KC_SPC):
125 return true;
126 default:
127 return false;
128 }
129}
130```
131
132## タッピング強制ホールド 113## タッピング強制ホールド
133 114
134`タッピング強制ホールド` を有効にするには、以下を `config.h` に追加します: 115`タッピング強制ホールド` を有効にするには、以下を `config.h` に追加します:
diff --git a/docs/tap_hold.md b/docs/tap_hold.md
index fa6c6abc14..348e2655eb 100644
--- a/docs/tap_hold.md
+++ b/docs/tap_hold.md
@@ -118,7 +118,7 @@ The reason is that `TAPPING_TERM` is a macro that expands to a constant integer
118 118
119The code which decides between the tap and hold actions of dual-role keys supports three different modes, in increasing order of preference for the hold action: 119The code which decides between the tap and hold actions of dual-role keys supports three different modes, in increasing order of preference for the hold action:
120 120
1211. The default mode selects the hold action only if the dual-role key is held down longer than the tapping term. In this mode pressing other keys while the dual-role key is held down does not influence the tap-or-hold decision. 1211. The default mode selects the hold action only if the dual-role key is held down longer than the tapping term. In this mode pressing other keys while the dual-role key is held down does not influence the tap-or-hold decision. In other words, this mode ignores interrupts.
122 122
1232. The “permissive hold” mode, in addition to the default behavior, immediately selects the hold action when another key is tapped (pressed and then released) while the dual-role key is held down, even if this happens earlier than the tapping term. If another key is just pressed, but then the dual-role key is released before that other key (and earlier than the tapping term), this mode will still select the tap action. 1232. The “permissive hold” mode, in addition to the default behavior, immediately selects the hold action when another key is tapped (pressed and then released) while the dual-role key is held down, even if this happens earlier than the tapping term. If another key is just pressed, but then the dual-role key is released before that other key (and earlier than the tapping term), this mode will still select the tap action.
124 124
@@ -126,6 +126,73 @@ The code which decides between the tap and hold actions of dual-role keys suppor
126 126
127Note that until the tap-or-hold decision completes (which happens when either the dual-role key is released, or the tapping term has expired, or the extra condition for the selected decision mode is satisfied), key events are delayed and not transmitted to the host immediately. The default mode gives the most delay (if the dual-role key is held down, this mode always waits for the whole tapping term), and the other modes may give less delay when other keys are pressed, because the hold action may be selected earlier. 127Note that until the tap-or-hold decision completes (which happens when either the dual-role key is released, or the tapping term has expired, or the extra condition for the selected decision mode is satisfied), key events are delayed and not transmitted to the host immediately. The default mode gives the most delay (if the dual-role key is held down, this mode always waits for the whole tapping term), and the other modes may give less delay when other keys are pressed, because the hold action may be selected earlier.
128 128
129### Comparison :id=comparison
130
131To better illustrate the tap-or-hold decision modes, let us compare the expected output of each decision mode in a handful of tapping scenarios involving a mod-tap key (`LSFT_T(KC_A)`) and a regular key (`KC_B`) with the `TAPPING_TERM` set to 200ms.
132
133By default, mod-taps behave like `HOLD_ON_OTHER_KEY_PRESS`, while layer-taps behave like "Ignore Interrupt" out of the box. If you want "Ignore Interrupt"-like behaviour for mod-taps, you must enable `IGNORE_MOD_TAP_INTERRUPT`, or return `false` in the `get_hold_on_other_key_press` function for all mod-taps.
134
135Note: "`kc` held" in the "Physical key event" column means that the key wasn't physically released yet at this point in time.
136
137#### Distinct taps (AABB) :id=distinct-taps
138
139| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
140|------|--------------------|----------------|-------------------|----------------------------|
141| 0 | `LSFT_T(KC_A)` down| | | |
142| 199 | `LSFT_T(KC_A)` up | a | a | a |
143| 210 | `KC_B` down | ab | ab | ab |
144| 220 | `KC_B` up | ab | ab | ab |
145
146| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
147|------|--------------------|----------------|-------------------|----------------------------|
148| 0 | `LSFT_T(KC_A)` down| | | |
149| 200 | `LSFT_T(KC_A)` held|<kbd>Shift</kbd>| <kbd>Shift</kbd> | <kbd>Shift</kbd> |
150| 201 | `LSFT_T(KC_A)` up |<kbd>Shift</kbd>| <kbd>Shift</kbd> | <kbd>Shift</kbd> |
151| 205 | `KC_B` down | b | b | b |
152| 210 | `KC_B` up | b | b | b |
153
154#### Nested tap (ABBA) :id=nested-tap
155
156| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
157|------|--------------------|----------------|-------------------|----------------------------|
158| 0 | `LSFT_T(KC_A)` down| | | |
159| 110 | `KC_B` down | | | B |
160| 120 | `KC_B` up | | B | B |
161| 199 | `LSFT_T(KC_A)` up | ab | B | B |
162
163| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
164|------|--------------------|----------------|-------------------|----------------------------|
165| 0 | `LSFT_T(KC_A)` down| | | |
166| 110 | `KC_B` down | | | B |
167| 120 | `KC_B` up | | B | B |
168| 200 | `LSFT_T(KC_A)` held| B | B | B |
169| 210 | `LSFT_T(KC_A)` up | B | B | B |
170
171| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
172|------|--------------------|----------------|-------------------|----------------------------|
173| 0 | `LSFT_T(KC_A)` down| | | |
174| 200 | `LSFT_T(KC_A)` held|<kbd>Shift</kbd>| <kbd>Shift</kbd> | <kbd>Shift</kbd> |
175| 205 | `KC_B` down | B | B | B |
176| 210 | `KC_B` up | B | B | B |
177| 220 | `LSFT_T(KC_A)` up | B | B | B |
178
179#### Rolling keys (ABAB) :id=rolling-keys
180
181| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
182|------|--------------------|----------------|-------------------|----------------------------|
183| 0 | `LSFT_T(KC_A)` down| | | |
184| 110 | `KC_B` down | | | B |
185| 130 | `LSFT_T(KC_A)` up | ab | ab | B |
186| 140 | `KC_B` up | ab | ab | B |
187
188| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` |
189|------|--------------------|----------------|-------------------|----------------------------|
190| 0 | `LSFT_T(KC_A)` down| | | |
191| 110 | `KC_B` down | | | B |
192| 200 | `LSFT_T(KC_A)` held| B | B | B |
193| 205 | `LSFT_T(KC_A)` up | B | B | B |
194| 210 | `KC_B` up | B | B | B |
195
129### Default Mode 196### Default Mode
130Example sequence 1 (the `L` key is also mapped to `KC_RGHT` on layer 2): 197Example sequence 1 (the `L` key is also mapped to `KC_RGHT` on layer 2):
131 198
@@ -179,8 +246,6 @@ since `SFT_T(KC_A)` is NOT held longer than the `TAPPING_TERM`.
179However, the actual output would be capital `X` (`SHIFT` + `x`) due to reasons 246However, the actual output would be capital `X` (`SHIFT` + `x`) due to reasons
180explained under [Ignore Mod Tap Interrupt](#ignore-mod-tap-interrupt). 247explained under [Ignore Mod Tap Interrupt](#ignore-mod-tap-interrupt).
181 248
182
183
184### Permissive Hold 249### Permissive Hold
185 250
186The “permissive hold” mode can be enabled for all dual-role keys by adding the corresponding option to `config.h`: 251The “permissive hold” mode can be enabled for all dual-role keys by adding the corresponding option to `config.h`:
@@ -212,7 +277,7 @@ An example of a sequence that is affected by the “permissive hold” mode:
212 +---------------------------|--------+ 277 +---------------------------|--------+
213``` 278```
214 279
215Normally, if you do all this within the `TAPPING_TERM` (default: 200ms), this will be registered as `al` by the firmware and host system. With the `PERMISSIVE_HOLD` option enabled, the Layer Tap key is considered as a layer switch if another key is tapped, and the above sequence would be registered as `KC_RGHT` (the mapping of `L` on layer 2). We could describe this sequence as a “nested press” (the modified key's key down and key up events are “nested” between the dual-role key's key down and key up events). 280Normally, if you do all this within the `TAPPING_TERM` (default: 200ms), this will be registered as `al` by the firmware and host system. With the `PERMISSIVE_HOLD` option enabled, the Layer Tap key is considered as a layer switch if another key is tapped, and the above sequence would be registered as `KC_RGHT` (the mapping of `L` on layer 2). We could describe this sequence as a “nested tap” (the modified key's key down and key up events are “nested” between the dual-role key's key down and key up events).
216 281
217However, this slightly different sequence will not be affected by the “permissive hold” mode: 282However, this slightly different sequence will not be affected by the “permissive hold” mode:
218 283
@@ -235,7 +300,7 @@ However, this slightly different sequence will not be affected by the “permiss
235 300
236In the sequence above the dual-role key is released before the other key is released, and if that happens within the tapping term, the “permissive hold” mode will still choose the tap action for the dual-role key, and the sequence will be registered as `al` by the host. We could describe this as a “rolling press” (the two keys' key down and key up events behave as if you were rolling a ball across the two keys, first pressing each key down in sequence and then releasing them in the same order). 301In the sequence above the dual-role key is released before the other key is released, and if that happens within the tapping term, the “permissive hold” mode will still choose the tap action for the dual-role key, and the sequence will be registered as `al` by the host. We could describe this as a “rolling press” (the two keys' key down and key up events behave as if you were rolling a ball across the two keys, first pressing each key down in sequence and then releasing them in the same order).
237 302
238?> The `PERMISSIVE_HOLD` option also affects Mod Tap keys, but this may not be noticeable if you do not also enable the `IGNORE_MOD_TAP_INTERRUPT` option for those keys, because the default handler for Mod Tap keys also considers both the “nested press” and “rolling press” sequences like shown above as a modifier hold, not the tap action. If you do not enable `IGNORE_MOD_TAP_INTERRUPT`, the effect of `PERMISSIVE_HOLD` on Mod Tap keys would be limited to reducing the delay before the key events are made visible to the host. 303?> The `PERMISSIVE_HOLD` option is not noticeable if you also enable `HOLD_ON_OTHER_KEY_PRESS` because the latter option considers both the “nested tap” and “rolling press” sequences like shown above as a hold action, not the tap action. `HOLD_ON_OTHER_KEY_PRESS` makes the Tap-Or-Hold decision earlier in the chain of key events, thus taking a precedence over `PERMISSIVE_HOLD`. This remark also applies to default mod-taps.
239 304
240For more granular control of this feature, you can add the following to your `config.h`: 305For more granular control of this feature, you can add the following to your `config.h`:
241 306
@@ -291,7 +356,7 @@ An example of a sequence that is affected by the “hold on other key press” m
291 356
292Normally, if you do all this within the `TAPPING_TERM` (default: 200ms), this will be registered as `al` by the firmware and host system. With the `HOLD_ON_OTHER_KEY_PRESS` option enabled, the Layer Tap key is considered as a layer switch if another key is pressed, and the above sequence would be registered as `KC_RGHT` (the mapping of `L` on layer 2). 357Normally, if you do all this within the `TAPPING_TERM` (default: 200ms), this will be registered as `al` by the firmware and host system. With the `HOLD_ON_OTHER_KEY_PRESS` option enabled, the Layer Tap key is considered as a layer switch if another key is pressed, and the above sequence would be registered as `KC_RGHT` (the mapping of `L` on layer 2).
293 358
294?> The `HOLD_ON_OTHER_KEY_PRESS` option also affects Mod Tap keys, but this may not be noticeable if you do not also enable the `IGNORE_MOD_TAP_INTERRUPT` option for those keys, because the default handler for Mod Tap keys also considers the “rolling press” sequence like shown above as a modifier hold, not the tap action. If you do not enable `IGNORE_MOD_TAP_INTERRUPT`, the effect of `HOLD_ON_OTHER_KEY_PRESS` on Mod Tap keys would be limited to reducing the delay before the key events are made visible to the host. 359?> The `HOLD_ON_OTHER_KEY_PRESS` option is essentially redundant with the default mod-tap behaviour. The only notable difference is that `HOLD_ON_OTHER_KEY_PRESS` reduces the delay before the key events are made visible to the host.
295 360
296For more granular control of this feature, you can add the following to your `config.h`: 361For more granular control of this feature, you can add the following to your `config.h`:
297 362
@@ -355,26 +420,32 @@ However, if the `HOLD_ON_OTHER_KEY_PRESS` option is enabled in addition to `IGNO
355For more granular control of this feature, you can add the following to your `config.h`: 420For more granular control of this feature, you can add the following to your `config.h`:
356 421
357```c 422```c
358#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY 423#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
359``` 424```
360 425
426?> This option affects *all* dual-role keys.
427
361You can then add the following function to your keymap: 428You can then add the following function to your keymap:
362 429
363```c 430```c
364bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 431bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
365 switch (keycode) { 432 switch (keycode) {
366 case SFT_T(KC_SPC): 433 case SFT_T(KC_SPC):
367 // Do not force the mod-tap key press to be handled as a modifier 434 // Do not force the mod-tap key press to be handled as a modifier
368 // if any other key was pressed while the mod-tap key is held down. 435 // if any other key was pressed while the mod-tap key is held down.
369 return true; 436 return false;
370 default: 437 default:
371 // Force the mod-tap key press to be handled as a modifier if any 438 // Force the dual-role key press to be handled as a modifier if any
372 // other key was pressed while the mod-tap key is held down. 439 // other key was pressed while the mod-tap key is held down.
373 return false; 440 return true;
374 } 441 }
375} 442}
376``` 443```
377 444
445Note that you must return `false` in `get_hold_on_other_key_press` in order to apply `IGNORE_MOD_TAP_INTERRUPT` for a certain mod-tap key.
446
447?> `IGNORE_MOD_TAP_INTERRUPT[_PER_KEY]` is being progressively phased out to align the (default) behavior and configuration of mod-taps with the rest of dual-role keys.
448
378## Quick Tap Term 449## Quick Tap Term
379 450
380When the user holds a key after tapping it, the tapping function is repeated by default, rather than activating the hold function. This allows keeping the ability to auto-repeat the tapping function of a dual-role key. `QUICK_TAP_TERM` enables fine tuning of that ability. If set to `0`, it will remove the auto-repeat ability and activate the hold function instead. 451When the user holds a key after tapping it, the tapping function is repeated by default, rather than activating the hold function. This allows keeping the ability to auto-repeat the tapping function of a dual-role key. `QUICK_TAP_TERM` enables fine tuning of that ability. If set to `0`, it will remove the auto-repeat ability and activate the hold function instead.
diff --git a/keyboards/adm42/rev4/keymaps/default/config.h b/keyboards/adm42/rev4/keymaps/default/config.h
index 4082d84a3a..abfaf9af78 100644
--- a/keyboards/adm42/rev4/keymaps/default/config.h
+++ b/keyboards/adm42/rev4/keymaps/default/config.h
@@ -1,3 +1,2 @@
1#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY 1#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
2#define QUICK_TAP_TERM_PER_KEY 2#define QUICK_TAP_TERM_PER_KEY
3#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
diff --git a/keyboards/adm42/rev4/keymaps/default/keymap.c b/keyboards/adm42/rev4/keymaps/default/keymap.c
index 245a3bd4de..154073beb7 100644
--- a/keyboards/adm42/rev4/keymaps/default/keymap.c
+++ b/keyboards/adm42/rev4/keymaps/default/keymap.c
@@ -93,21 +93,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
93 ), 93 ),
94}; 94};
95 95
96bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 96bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
97 switch (keycode) { 97 // Special if-condition outside the switch because `RC_QUT` overlaps with
98 case RC_QUT: 98 // the `QK_MOD_TAP ... QK_MOD_TAP_MAX` range.
99 return true; 99 if (keycode == RC_QUT) {
100 default:
101 return false; 100 return false;
102 } 101 }
103}
104
105bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
106 switch (keycode) { 102 switch (keycode) {
107 case LLS_ESC: 103 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
108 case LLS_RALT: 104 case QK_LAYER_TAP ... QK_LAYER_TAP_MAX:
109 case LLE_ENT:
110 case LLA_DEL:
111 return true; 105 return true;
112 default: 106 default:
113 return false; 107 return false;
diff --git a/keyboards/bastardkb/scylla/keymaps/cykedev/config.h b/keyboards/bastardkb/scylla/keymaps/cykedev/config.h
index 43037350f6..6119f2738b 100644
--- a/keyboards/bastardkb/scylla/keymaps/cykedev/config.h
+++ b/keyboards/bastardkb/scylla/keymaps/cykedev/config.h
@@ -28,15 +28,12 @@
28 28
29#define TAPPING_TERM 200 29#define TAPPING_TERM 200
30 30
31// Prevent normal rollover on alphas from accidentally triggering mods.
32// #define IGNORE_MOD_TAP_INTERRUPT
33
34// Enable rapid switch from tap to hold, disables double tap hold auto-repeat. 31// Enable rapid switch from tap to hold, disables double tap hold auto-repeat.
35// #define QUICK_TAP_TERM 0 32// #define QUICK_TAP_TERM 0
36 33
37// Apply the modifier on keys that are tapped during a short hold of a modtap 34// Apply the modifier on keys that are tapped during a short hold of a modtap
38// #define PERMISSIVE_HOLD 35// #define PERMISSIVE_HOLD
39 36
40#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY 37#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
41 38
42#define FORCE_NKRO \ No newline at end of file 39#define FORCE_NKRO
diff --git a/keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c b/keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c
index 9f497e2c14..a51f5b9d38 100644
--- a/keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c
+++ b/keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c
@@ -169,12 +169,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
169 ) 169 )
170}; 170};
171 171
172bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 172bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
173 switch (keycode) { 173 if (keycode == CM_SPAR) {
174 case CM_SPAR: 174 return false;
175 return true; 175 } else if (QK_MOD_TAP <= keycode && keycode <= QK_MOD_TAP_MAX) {
176 default: 176 return true;
177 return false; 177 } else {
178 return false;
178 } 179 }
179} 180}
180 181
diff --git a/keyboards/converter/usb_usb/keymaps/chriskopher/config.h b/keyboards/converter/usb_usb/keymaps/chriskopher/config.h
index 7714f713bd..04066edc02 100644
--- a/keyboards/converter/usb_usb/keymaps/chriskopher/config.h
+++ b/keyboards/converter/usb_usb/keymaps/chriskopher/config.h
@@ -18,8 +18,7 @@
18 18
19#define TAPPING_TERM 200 // Delay for tap modifiers until it is considered a hold 19#define TAPPING_TERM 200 // Delay for tap modifiers until it is considered a hold
20 20
21#define IGNORE_MOD_TAP_INTERRUPT // Enable ignore mod tap interrupt: https://docs.qmk.fm/#/tap_hold?id=ignore-mod-tap-interrupt 21#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY // Allows configuration of hold on other key press per key in keymap.c
22#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY // Allows configuration of ignore mod tap interrupt per key in keymap.c
23 22
24#define COMBO_COUNT 2 // Number of defined combos 23#define COMBO_COUNT 2 // Number of defined combos
25#define COMBO_TERM 20 // Delay for combo keys to be chained together 24#define COMBO_TERM 20 // Delay for combo keys to be chained together
diff --git a/keyboards/converter/usb_usb/keymaps/chriskopher/keymap.c b/keyboards/converter/usb_usb/keymaps/chriskopher/keymap.c
index 4113cdc67c..76cf311462 100644
--- a/keyboards/converter/usb_usb/keymaps/chriskopher/keymap.c
+++ b/keyboards/converter/usb_usb/keymaps/chriskopher/keymap.c
@@ -174,13 +174,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
174}; 174};
175// clang-format on 175// clang-format on
176 176
177// Configure ignore mod tap interrupt per key 177// Configure hold on other key press per key
178bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 178bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
179 switch (keycode) { 179 switch (keycode) {
180 // I don't like how mod tap interrupt feels with these keys specifically when I'm typing 180 // I don't like how ignore interrupt feels with these keys specifically when I'm typing
181 case LCTL_T(KC_ESC): 181 case LCTL_T(KC_ESC):
182 return false;
183 default:
184 return true; 182 return true;
183 default:
184 return false;
185 } 185 }
186} 186}
diff --git a/keyboards/crkbd/keymaps/snowe/config.h b/keyboards/crkbd/keymaps/snowe/config.h
index b091cd7903..57a253428b 100644
--- a/keyboards/crkbd/keymaps/snowe/config.h
+++ b/keyboards/crkbd/keymaps/snowe/config.h
@@ -57,7 +57,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
57 57
58// fix for me putting alt under A and being a fast typist 58// fix for me putting alt under A and being a fast typist
59#define IGNORE_MOD_TAP_INTERRUPT 59#define IGNORE_MOD_TAP_INTERRUPT
60//#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
61 60
62#define LAYER_STATE_8BIT 61#define LAYER_STATE_8BIT
63#define SPLIT_WPM_ENABLE 62#define SPLIT_WPM_ENABLE
diff --git a/keyboards/crkbd/keymaps/snowe/keymap.c b/keyboards/crkbd/keymaps/snowe/keymap.c
index 685491903e..91f0ceafeb 100644
--- a/keyboards/crkbd/keymaps/snowe/keymap.c
+++ b/keyboards/crkbd/keymaps/snowe/keymap.c
@@ -198,12 +198,14 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
198// } 198// }
199//} 199//}
200// 200//
201// bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 201// bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
202// if (keycode == ALT_T(KC_A) || keycode == SH_BKSP) {
203// return false;
204// }
202// switch (keycode) { 205// switch (keycode) {
203// case ALT_T(KC_A): 206// case QK_MOD_TAP ... QK_MOD_TAP_MAX:
204// case SH_BKSP:
205// return true; 207// return true;
206// default: 208// default:
207// return false; 209// return false;
208// } 210// }
209//} \ No newline at end of file 211//}
diff --git a/keyboards/ergodox_ez/keymaps/stamm/config.h b/keyboards/ergodox_ez/keymaps/stamm/config.h
index f9e89d276f..1262ce6559 100644
--- a/keyboards/ergodox_ez/keymaps/stamm/config.h
+++ b/keyboards/ergodox_ez/keymaps/stamm/config.h
@@ -29,8 +29,8 @@
29#define PERMISSIVE_HOLD 29#define PERMISSIVE_HOLD
30/* #define PERMISSIVE_HOLD_PER_KEY */ 30/* #define PERMISSIVE_HOLD_PER_KEY */
31 31
32#define IGNORE_MOD_TAP_INTERRUPT 32#define HOLD_ON_OTHER_KEY_PRESS
33#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY 33#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
34 34
35#define QUICK_TAP_TERM 0 35#define QUICK_TAP_TERM 0
36#define QUICK_TAP_TERM_PER_KEY 36#define QUICK_TAP_TERM_PER_KEY
diff --git a/keyboards/ergodox_ez/keymaps/stamm/keymap.c b/keyboards/ergodox_ez/keymaps/stamm/keymap.c
index aa9debfe57..8a3e30f5f6 100644
--- a/keyboards/ergodox_ez/keymaps/stamm/keymap.c
+++ b/keyboards/ergodox_ez/keymaps/stamm/keymap.c
@@ -206,7 +206,7 @@ uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
206 return TAPPING_TERM; 206 return TAPPING_TERM;
207 } 207 }
208} 208}
209bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 209bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
210 switch (keycode) { 210 switch (keycode) {
211 case E_NUMBERS: 211 case E_NUMBERS:
212 case R_MOUSE: 212 case R_MOUSE:
@@ -219,7 +219,7 @@ bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
219 case RCTL_T(KC_L): 219 case RCTL_T(KC_L):
220 case RSFT_T(KC_SEMICOLON): 220 case RSFT_T(KC_SEMICOLON):
221 case ARROWS: 221 case ARROWS:
222 return true; 222 return false;
223 default: 223 default:
224 return false; 224 return false;
225 } 225 }
diff --git a/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/config.h b/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/config.h
index 7b43dcb5d4..6a28251c6b 100644
--- a/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/config.h
+++ b/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/config.h
@@ -45,10 +45,7 @@
45// Configure the global tapping term (default: 200ms) 45// Configure the global tapping term (default: 200ms)
46#define TAPPING_TERM 200 46#define TAPPING_TERM 200
47 47
48// Prevent normal rollover on alphas from accidentally triggering mods. 48#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
49#define IGNORE_MOD_TAP_INTERRUPT
50//#define IGNORE_MOD_TAP_INTERRUPT
51#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
52 49
53// Enable rapid switch from tap to hold, disables double tap hold auto-repeat. 50// Enable rapid switch from tap to hold, disables double tap hold auto-repeat.
54#define QUICK_TAP_TERM 0 51#define QUICK_TAP_TERM 0
diff --git a/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/keymap.c b/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/keymap.c
index 413fa70492..9687e77d88 100644
--- a/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/keymap.c
+++ b/keyboards/handwired/dactyl_manuform/5x6_5/keymaps/cykedev/keymap.c
@@ -195,18 +195,18 @@ layer_state_t layer_state_set_user(layer_state_t state) {
195 return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); 195 return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
196} 196}
197 197
198bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 198bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
199 switch (keycode) { 199 switch (keycode) {
200 case SPC_L: 200 case SPC_L:
201 return false;
202 case SPC_R:
203 return true; 201 return true;
204 case ENT_L: 202 case SPC_R:
205 return false; 203 return false;
204 case ENT_L:
205 return true;
206 case ENT_R: 206 case ENT_R:
207 return false;
208 default:
209 return true; 207 return true;
208 default:
209 return false;
210 } 210 }
211} 211}
212 212
diff --git a/keyboards/lily58/keymaps/cykedev/config.h b/keyboards/lily58/keymaps/cykedev/config.h
index dac88dff77..d9e43606a4 100644
--- a/keyboards/lily58/keymaps/cykedev/config.h
+++ b/keyboards/lily58/keymaps/cykedev/config.h
@@ -17,4 +17,4 @@
17 17
18#define MASTER_LEFT 18#define MASTER_LEFT
19#define TAPPING_TERM 200 19#define TAPPING_TERM 200
20#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY 20#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
diff --git a/keyboards/lily58/keymaps/cykedev/keymap.c b/keyboards/lily58/keymaps/cykedev/keymap.c
index 94db33771a..88d9728469 100644
--- a/keyboards/lily58/keymaps/cykedev/keymap.c
+++ b/keyboards/lily58/keymaps/cykedev/keymap.c
@@ -96,9 +96,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
96) 96)
97}; 97};
98 98
99bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 99bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
100 switch (keycode) { 100 switch (keycode) {
101 case SY_SPC: 101 case SY_SPC:
102 return false;
103 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
102 return true; 104 return true;
103 default: 105 default:
104 return false; 106 return false;
diff --git a/keyboards/planck/keymaps/adamtabrams/config.h b/keyboards/planck/keymaps/adamtabrams/config.h
index 8ff86760b4..d47e552434 100644
--- a/keyboards/planck/keymaps/adamtabrams/config.h
+++ b/keyboards/planck/keymaps/adamtabrams/config.h
@@ -33,7 +33,7 @@
33// Tap-Hold Configs 33// Tap-Hold Configs
34#define TAPPING_TERM 180 34#define TAPPING_TERM 180
35#define PERMISSIVE_HOLD 35#define PERMISSIVE_HOLD
36#define IGNORE_MOD_TAP_INTERRUPT 36#define HOLD_ON_OTHER_KEY_PRESS
37#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY 37#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
38#define QUICK_TAP_TERM 0 38#define QUICK_TAP_TERM 0
39#define QUICK_TAP_TERM_PER_KEY 39#define QUICK_TAP_TERM_PER_KEY
diff --git a/keyboards/planck/keymaps/adamtabrams/keymap.c b/keyboards/planck/keymaps/adamtabrams/keymap.c
index 2203ecd30f..ce1acd437b 100644
--- a/keyboards/planck/keymaps/adamtabrams/keymap.c
+++ b/keyboards/planck/keymaps/adamtabrams/keymap.c
@@ -255,7 +255,7 @@ uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) {
255 } 255 }
256} 256}
257 257
258bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 258bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
259 switch (keycode) { 259 switch (keycode) {
260 case ALT__A: 260 case ALT__A:
261 case ALTSCLN: 261 case ALTSCLN:
@@ -272,7 +272,7 @@ bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
272 case CTL__J: 272 case CTL__J:
273 case CTL__T: 273 case CTL__T:
274 case CTL__N: 274 case CTL__N:
275 return true; 275 return false;
276 default: 276 default:
277 return false; 277 return false;
278 } 278 }
diff --git a/keyboards/planck/keymaps/rootiest/config.h b/keyboards/planck/keymaps/rootiest/config.h
index bdb5cea91b..1cca7e5ba9 100644
--- a/keyboards/planck/keymaps/rootiest/config.h
+++ b/keyboards/planck/keymaps/rootiest/config.h
@@ -118,7 +118,7 @@
118 */ 118 */
119#define RETRO_TAPPING_PER_KEY // Control Retro-Tap individually by key 119#define RETRO_TAPPING_PER_KEY // Control Retro-Tap individually by key
120#define QUICK_TAP_TERM_PER_KEY // Control Quick-Tap individually by key 120#define QUICK_TAP_TERM_PER_KEY // Control Quick-Tap individually by key
121#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY // Control Mod-Tap-Interrupt individually by key 121#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY // Control Hold-on-Other-Key-Press individually by key
122#define PERMISSIVE_HOLD_PER_KEY // Control Permissive-Hold individually by key 122#define PERMISSIVE_HOLD_PER_KEY // Control Permissive-Hold individually by key
123 123
124#define MK_KINETIC_SPEED // Use kinetic acceleration for mouse-keys 124#define MK_KINETIC_SPEED // Use kinetic acceleration for mouse-keys
diff --git a/keyboards/planck/keymaps/rootiest/keymap.c b/keyboards/planck/keymaps/rootiest/keymap.c
index cc43aff673..9b6bc9cc18 100644
--- a/keyboards/planck/keymaps/rootiest/keymap.c
+++ b/keyboards/planck/keymaps/rootiest/keymap.c
@@ -1369,9 +1369,11 @@ bool get_retro_tapping(uint16_t keycode, keyrecord_t* record) {
1369 return false; 1369 return false;
1370 } 1370 }
1371} 1371}
1372// Handles per-key configuration of Mod-Tap-Interrupt 1372// Handles per-key configuration of Hold-on-Other-Key-Press
1373bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t* record) { 1373bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t* record) {
1374 switch (keycode) { 1374 switch (keycode) {
1375 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
1376 return true;
1375 default: 1377 default:
1376 return false; 1378 return false;
1377 } 1379 }
diff --git a/keyboards/torn/keymaps/kinesish/config.h b/keyboards/torn/keymaps/kinesish/config.h
index 734512e6cd..5c4de67989 100644
--- a/keyboards/torn/keymaps/kinesish/config.h
+++ b/keyboards/torn/keymaps/kinesish/config.h
@@ -17,5 +17,5 @@
17#pragma once 17#pragma once
18 18
19#define TAPPING_TERM 200 19#define TAPPING_TERM 200
20#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY 20#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY
21#define PERMISSIVE_HOLD_PER_KEY 21#define PERMISSIVE_HOLD_PER_KEY
diff --git a/keyboards/torn/keymaps/kinesish/keymap.c b/keyboards/torn/keymaps/kinesish/keymap.c
index 13f3304068..9ddbac3601 100644
--- a/keyboards/torn/keymaps/kinesish/keymap.c
+++ b/keyboards/torn/keymaps/kinesish/keymap.c
@@ -133,18 +133,18 @@ layer_state_t layer_state_set_user(layer_state_t state) {
133} 133}
134 134
135/* 135/*
136 * Enable `IGNORE_MOD_TAP_INTERRUPT` for all modifiers except `Shift`. 136 * Enable `HOLD_ON_OTHER_KEY_PRESS` only for `Shift`.
137 * For more info see `IGNORE_MOD_TAP_INTERRUPT_PER_KEY` in `docs/tap_hold.md`. 137 * For more info see `HOLD_ON_OTHER_KEY_PRESS_PER_KEY` in `docs/tap_hold.md`.
138 */ 138 */
139 139
140bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 140bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
141 switch (keycode) { 141 switch (keycode) {
142 case S_EQL: 142 case S_EQL:
143 return false; 143 return true;
144 case S_MINS: 144 case S_MINS:
145 return false;
146 default:
147 return true; 145 return true;
146 default:
147 return false;
148 } 148 }
149} 149}
150 150
diff --git a/quantum/action.c b/quantum/action.c
index abf9834d2f..ea6a24ea5c 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -55,8 +55,8 @@ int retro_tapping_counter = 0;
55# include "process_auto_shift.h" 55# include "process_auto_shift.h"
56#endif 56#endif
57 57
58#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY 58#ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
59__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { 59__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) {
60 return false; 60 return false;
61} 61}
62#endif 62#endif
@@ -484,10 +484,10 @@ void process_action(keyrecord_t *record, action_t action) {
484 default: 484 default:
485 if (event.pressed) { 485 if (event.pressed) {
486 if (tap_count > 0) { 486 if (tap_count > 0) {
487# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) 487# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
488 if ( 488 if (
489# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY 489# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
490 !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false), record) && 490 get_hold_on_other_key_press(get_event_keycode(record->event, false), record) &&
491# endif 491# endif
492 record->tap.interrupted) { 492 record->tap.interrupted) {
493 dprint("mods_tap: tap: cancel: add_mods\n"); 493 dprint("mods_tap: tap: cancel: add_mods\n");
diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c
index 0350495ae5..ca0f31f12e 100644
--- a/quantum/action_tapping.c
+++ b/quantum/action_tapping.c
@@ -15,6 +15,14 @@
15 15
16#ifndef NO_ACTION_TAPPING 16#ifndef NO_ACTION_TAPPING
17 17
18# if defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
19# error "IGNORE_MOD_TAP_INTERRUPT_PER_KEY has been removed; the code needs to be ported to use HOLD_ON_OTHER_KEY_PRESS_PER_KEY instead."
20# elif !defined(IGNORE_MOD_TAP_INTERRUPT)
21# if !defined(PERMISSIVE_HOLD) && !defined(PERMISSIVE_HOLD_PER_KEY) && !defined(HOLD_ON_OTHER_KEY_PRESS) && !defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
22# pragma message "The default behavior of mod-taps will change to mimic IGNORE_MOD_TAP_INTERRUPT in the future.\nIf you wish to keep the old default behavior of mod-taps, please use HOLD_ON_OTHER_KEY_PRESS."
23# endif
24# endif
25
18# define IS_TAPPING() !IS_NOEVENT(tapping_key.event) 26# define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
19# define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) 27# define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
20# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) 28# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
@@ -162,9 +170,7 @@ void action_tapping_process(keyrecord_t record) {
162# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false 170# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false
163# endif 171# endif
164 172
165# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY 173# if defined(IGNORE_MOD_TAP_INTERRUPT)
166# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT get_ignore_mod_tap_interrupt(tapping_keycode, &tapping_key)
167# elif defined(IGNORE_MOD_TAP_INTERRUPT)
168# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT true 174# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT true
169# else 175# else
170# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false 176# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false
@@ -216,7 +222,7 @@ bool process_tapping(keyrecord_t *keyp) {
216 // Rolled over the two keys. 222 // Rolled over the two keys.
217 (tapping_key.tap.interrupted == true && ( 223 (tapping_key.tap.interrupted == true && (
218 (TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) || 224 (TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) ||
219 (TAP_IS_MT && !TAP_GET_IGNORE_MOD_TAP_INTERRUPT) 225 (TAP_IS_MT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS)
220 ) 226 )
221 ) 227 )
222 // Makes Retro Shift ignore [IGNORE_MOD_TAP_INTERRUPT's 228 // Makes Retro Shift ignore [IGNORE_MOD_TAP_INTERRUPT's
diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c
index 35d4851ee5..b7ac449198 100644
--- a/quantum/process_keycode/process_auto_shift.c
+++ b/quantum/process_keycode/process_auto_shift.c
@@ -397,8 +397,17 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
397 break; 397 break;
398# endif 398# endif
399 } 399 }
400 // If Retro Shift is disabled, possible custom actions shouldn't happen. 400 // If Retro Shift is disabled, possible custom actions shouldn't happen.
401 // clang-format off 401 // clang-format off
402# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
403# if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
404 const bool is_hold_on_interrupt = get_hold_on_other_key_press(keycode, record);
405# elif defined(IGNORE_MOD_TAP_INTERRUPT)
406 const bool is_hold_on_interrupt = false;
407# else
408 const bool is_hold_on_interrupt = IS_MT(keycode);
409# endif
410# endif
402 if (IS_RETRO(keycode) 411 if (IS_RETRO(keycode)
403# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) 412# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
404 // Not tapped or #defines mean that rolls should use hold action. 413 // Not tapped or #defines mean that rolls should use hold action.
@@ -407,27 +416,7 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
407# ifdef RETRO_TAPPING_PER_KEY 416# ifdef RETRO_TAPPING_PER_KEY
408 || !get_retro_tapping(keycode, record) 417 || !get_retro_tapping(keycode, record)
409# endif 418# endif
410 || (record->tap.interrupted && (IS_LT(keycode) 419 || (record->tap.interrupted && is_hold_on_interrupt))
411# if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
412# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
413 ? get_hold_on_other_key_press(keycode, record)
414# else
415 ? true
416# endif
417# else
418 ? false
419# endif
420# if defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
421# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
422 : !get_ignore_mod_tap_interrupt(keycode, record)
423# else
424 : false
425# endif
426# else
427 : true
428# endif
429 ))
430 )
431# endif 420# endif
432 ) { 421 ) {
433 // clang-format on 422 // clang-format on
@@ -454,10 +443,10 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
454# endif 443# endif
455 ) { 444 ) {
456 // Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set. 445 // Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set.
457# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) 446# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
458 if (autoshift_flags.in_progress 447 if (autoshift_flags.in_progress
459# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY 448# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
460 && !get_ignore_mod_tap_interrupt(keycode, record) 449 && get_hold_on_other_key_press(keycode, record)
461# endif 450# endif
462 ) { 451 ) {
463 autoshift_end(KC_NO, now, false, &autoshift_lastrecord); 452 autoshift_end(KC_NO, now, false, &autoshift_lastrecord);
diff --git a/tests/tap_hold_configurations/default_mod_tap/config.h b/tests/tap_hold_configurations/default_mod_tap/config.h
index 5955b8600a..f22448845e 100644
--- a/tests/tap_hold_configurations/default_mod_tap/config.h
+++ b/tests/tap_hold_configurations/default_mod_tap/config.h
@@ -18,4 +18,4 @@
18 18
19#include "test_common.h" 19#include "test_common.h"
20 20
21#define IGNORE_MOD_TAP_INTERRUPT \ No newline at end of file 21#define IGNORE_MOD_TAP_INTERRUPT
diff --git a/tests/tap_hold_configurations/default_mod_tap/test_tap_hold.cpp b/tests/tap_hold_configurations/default_mod_tap/test_tap_hold.cpp
index b70efe4aed..01943c10d2 100644
--- a/tests/tap_hold_configurations/default_mod_tap/test_tap_hold.cpp
+++ b/tests/tap_hold_configurations/default_mod_tap/test_tap_hold.cpp
@@ -66,7 +66,7 @@ TEST_F(DefaultTapHold, tap_regular_key_while_mod_tap_key_is_held) {
66 testing::Mock::VerifyAndClearExpectations(&driver); 66 testing::Mock::VerifyAndClearExpectations(&driver);
67} 67}
68 68
69TEST_F(DefaultTapHold, tap_mod_tap_key_while_mod_tap_key_is_held) { 69TEST_F(DefaultTapHold, tap_a_mod_tap_key_while_another_mod_tap_key_is_held) {
70 TestDriver driver; 70 TestDriver driver;
71 InSequence s; 71 InSequence s;
72 auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 72 auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P));
diff --git a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h b/tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h
deleted file mode 100644
index 5955b8600a..0000000000
--- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/* Copyright 2021 Stefan Kerkmann
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include "test_common.h"
20
21#define IGNORE_MOD_TAP_INTERRUPT \ No newline at end of file
diff --git a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test.mk b/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test.mk
deleted file mode 100644
index efecca2c22..0000000000
--- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test.mk
+++ /dev/null
@@ -1,18 +0,0 @@
1# Copyright 2021 Stefan Kerkmann
2#
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16# --------------------------------------------------------------------------------
17# Keep this file, even if it is empty, as a marker that this folder contains tests
18# --------------------------------------------------------------------------------
diff --git a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test_tap_hold.cpp b/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test_tap_hold.cpp
deleted file mode 100644
index 319de61070..0000000000
--- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test_tap_hold.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
1/* Copyright 2021 Stefan Kerkmann
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "keyboard_report_util.hpp"
18#include "keycode.h"
19#include "test_common.hpp"
20#include "action_tapping.h"
21#include "test_fixture.hpp"
22#include "test_keymap_key.hpp"
23
24using testing::_;
25using testing::InSequence;
26
27class IgnoreModTapInterrupt : public TestFixture {};
28
29TEST_F(IgnoreModTapInterrupt, tap_regular_key_while_mod_tap_key_is_held) {
30 TestDriver driver;
31 InSequence s;
32 auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P));
33 auto regular_key = KeymapKey(0, 2, 0, KC_A);
34
35 set_keymap({mod_tap_hold_key, regular_key});
36
37 /* Press mod-tap-hold key */
38 EXPECT_NO_REPORT(driver);
39 mod_tap_hold_key.press();
40 run_one_scan_loop();
41 testing::Mock::VerifyAndClearExpectations(&driver);
42
43 /* Press regular key */
44 EXPECT_NO_REPORT(driver);
45 regular_key.press();
46 run_one_scan_loop();
47 testing::Mock::VerifyAndClearExpectations(&driver);
48
49 /* Release regular key */
50 EXPECT_NO_REPORT(driver);
51 regular_key.release();
52 run_one_scan_loop();
53 testing::Mock::VerifyAndClearExpectations(&driver);
54
55 /* Release mod-tap-hold key */
56 EXPECT_REPORT(driver, (KC_P));
57 EXPECT_REPORT(driver, (KC_A, KC_P));
58 EXPECT_REPORT(driver, (KC_P));
59 EXPECT_EMPTY_REPORT(driver);
60 mod_tap_hold_key.release();
61 run_one_scan_loop();
62 testing::Mock::VerifyAndClearExpectations(&driver);
63}
64
65TEST_F(IgnoreModTapInterrupt, tap_mod_tap_key_while_mod_tap_key_is_held) {
66 TestDriver driver;
67 InSequence s;
68 auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P));
69 auto second_mod_tap_hold_key = KeymapKey(0, 2, 0, RSFT_T(KC_A));
70
71 set_keymap({first_mod_tap_hold_key, second_mod_tap_hold_key});
72
73 /* Press first mod-tap-hold key */
74 EXPECT_NO_REPORT(driver);
75 first_mod_tap_hold_key.press();
76 run_one_scan_loop();
77 testing::Mock::VerifyAndClearExpectations(&driver);
78
79 /* Press second tap-hold key */
80 EXPECT_NO_REPORT(driver);
81 second_mod_tap_hold_key.press();
82 run_one_scan_loop();
83 testing::Mock::VerifyAndClearExpectations(&driver);
84
85 /* Release second tap-hold key */
86 EXPECT_NO_REPORT(driver);
87 second_mod_tap_hold_key.release();
88 run_one_scan_loop();
89 testing::Mock::VerifyAndClearExpectations(&driver);
90
91 /* Release first mod-tap-hold key */
92 EXPECT_REPORT(driver, (KC_P));
93 EXPECT_REPORT(driver, (KC_A, KC_P));
94 EXPECT_REPORT(driver, (KC_P));
95 EXPECT_EMPTY_REPORT(driver);
96 first_mod_tap_hold_key.release();
97 run_one_scan_loop();
98 testing::Mock::VerifyAndClearExpectations(&driver);
99}
100
101TEST_F(IgnoreModTapInterrupt, tap_regular_key_while_layer_tap_key_is_held) {
102 TestDriver driver;
103 InSequence s;
104 auto layer_tap_hold_key = KeymapKey(0, 1, 0, LT(1, KC_P));
105 auto regular_key = KeymapKey(0, 2, 0, KC_A);
106 auto layer_key = KeymapKey(1, 2, 0, KC_B);
107
108 set_keymap({layer_tap_hold_key, regular_key, layer_key});
109
110 /* Press layer-tap-hold key */
111 EXPECT_NO_REPORT(driver);
112 layer_tap_hold_key.press();
113 run_one_scan_loop();
114 testing::Mock::VerifyAndClearExpectations(&driver);
115
116 /* Press regular key */
117 EXPECT_NO_REPORT(driver);
118 regular_key.press();
119 run_one_scan_loop();
120 testing::Mock::VerifyAndClearExpectations(&driver);
121
122 /* Release regular key */
123 EXPECT_NO_REPORT(driver);
124 regular_key.release();
125 run_one_scan_loop();
126 testing::Mock::VerifyAndClearExpectations(&driver);
127
128 /* Release layer-tap-hold key */
129 EXPECT_REPORT(driver, (KC_P));
130 EXPECT_REPORT(driver, (KC_P, regular_key.report_code));
131 EXPECT_REPORT(driver, (KC_P));
132 EXPECT_EMPTY_REPORT(driver);
133 layer_tap_hold_key.release();
134 run_one_scan_loop();
135 testing::Mock::VerifyAndClearExpectations(&driver);
136}
diff --git a/tests/tap_hold_configurations/permissive_hold/test_tap_hold.cpp b/tests/tap_hold_configurations/permissive_hold/test_tap_hold.cpp
index 74e81f347f..e6ecc86401 100644
--- a/tests/tap_hold_configurations/permissive_hold/test_tap_hold.cpp
+++ b/tests/tap_hold_configurations/permissive_hold/test_tap_hold.cpp
@@ -60,7 +60,7 @@ TEST_F(PermissiveHold, tap_regular_key_while_mod_tap_key_is_held) {
60 testing::Mock::VerifyAndClearExpectations(&driver); 60 testing::Mock::VerifyAndClearExpectations(&driver);
61} 61}
62 62
63TEST_F(PermissiveHold, tap_mod_tap_key_while_mod_tap_key_is_held) { 63TEST_F(PermissiveHold, tap_a_mod_tap_key_while_another_mod_tap_key_is_held) {
64 TestDriver driver; 64 TestDriver driver;
65 InSequence s; 65 InSequence s;
66 auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 66 auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P));
diff --git a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/config.h b/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/config.h
deleted file mode 100644
index a6abd50bbe..0000000000
--- a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/config.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/* Copyright 2021 Stefan Kerkmann
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include "test_common.h"
20
21#define IGNORE_MOD_TAP_INTERRUPT
22#define PERMISSIVE_HOLD \ No newline at end of file
diff --git a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test.mk b/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test.mk
deleted file mode 100644
index efecca2c22..0000000000
--- a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test.mk
+++ /dev/null
@@ -1,18 +0,0 @@
1# Copyright 2021 Stefan Kerkmann
2#
3# This program is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16# --------------------------------------------------------------------------------
17# Keep this file, even if it is empty, as a marker that this folder contains tests
18# --------------------------------------------------------------------------------
diff --git a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp b/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp
deleted file mode 100644
index ee7e707c94..0000000000
--- a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
1
2/* Copyright 2021 Stefan Kerkmann
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "keyboard_report_util.hpp"
19#include "keycode.h"
20#include "test_common.hpp"
21#include "action_tapping.h"
22#include "test_fixture.hpp"
23#include "test_keymap_key.hpp"
24
25using testing::_;
26using testing::InSequence;
27
28class PermissiveHold_IgnoreModTapInterrupt : public TestFixture {};
29
30TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_regular_key_while_mod_tap_key_is_held) {
31 TestDriver driver;
32 InSequence s;
33 auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P));
34 auto regular_key = KeymapKey(0, 2, 0, KC_A);
35
36 set_keymap({mod_tap_hold_key, regular_key});
37
38 /* Press mod-tap-hold key */
39 EXPECT_NO_REPORT(driver);
40 mod_tap_hold_key.press();
41 run_one_scan_loop();
42 testing::Mock::VerifyAndClearExpectations(&driver);
43
44 /* Press regular key */
45 EXPECT_NO_REPORT(driver);
46 regular_key.press();
47 run_one_scan_loop();
48 testing::Mock::VerifyAndClearExpectations(&driver);
49
50 /* Release regular key */
51 EXPECT_REPORT(driver, (KC_LSFT));
52 EXPECT_REPORT(driver, (KC_LSFT, KC_A));
53 EXPECT_REPORT(driver, (KC_LSFT));
54 regular_key.release();
55 run_one_scan_loop();
56 testing::Mock::VerifyAndClearExpectations(&driver);
57
58 /* Release mod-tap-hold key */
59 EXPECT_EMPTY_REPORT(driver);
60 mod_tap_hold_key.release();
61 run_one_scan_loop();
62 testing::Mock::VerifyAndClearExpectations(&driver);
63}
64
65TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_mod_tap_key_while_mod_tap_key_is_held) {
66 TestDriver driver;
67 InSequence s;
68 auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P));
69 auto second_mod_tap_hold_key = KeymapKey(0, 2, 0, RSFT_T(KC_A));
70
71 set_keymap({first_mod_tap_hold_key, second_mod_tap_hold_key});
72
73 /* Press first mod-tap-hold key */
74 EXPECT_NO_REPORT(driver);
75 first_mod_tap_hold_key.press();
76 run_one_scan_loop();
77 testing::Mock::VerifyAndClearExpectations(&driver);
78
79 /* Press second tap-hold key */
80 EXPECT_NO_REPORT(driver);
81 second_mod_tap_hold_key.press();
82 run_one_scan_loop();
83 testing::Mock::VerifyAndClearExpectations(&driver);
84
85 /* Release second tap-hold key */
86 EXPECT_REPORT(driver, (KC_LSFT));
87 EXPECT_REPORT(driver, (KC_LSFT, KC_A));
88 EXPECT_REPORT(driver, (KC_LSFT));
89 second_mod_tap_hold_key.release();
90 run_one_scan_loop();
91 testing::Mock::VerifyAndClearExpectations(&driver);
92
93 /* Release first mod-tap-hold key */
94 EXPECT_EMPTY_REPORT(driver);
95 first_mod_tap_hold_key.release();
96 run_one_scan_loop();
97 testing::Mock::VerifyAndClearExpectations(&driver);
98}
99
100TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_regular_key_while_layer_tap_key_is_held) {
101 TestDriver driver;
102 InSequence s;
103 auto layer_tap_hold_key = KeymapKey(0, 1, 0, LT(1, KC_P));
104 auto regular_key = KeymapKey(0, 2, 0, KC_A);
105 auto layer_key = KeymapKey(1, 2, 0, KC_B);
106
107 set_keymap({layer_tap_hold_key, regular_key, layer_key});
108
109 /* Press layer-tap-hold key */
110 EXPECT_NO_REPORT(driver);
111 layer_tap_hold_key.press();
112 run_one_scan_loop();
113 testing::Mock::VerifyAndClearExpectations(&driver);
114
115 /* Press regular key */
116 EXPECT_NO_REPORT(driver);
117 regular_key.press();
118 run_one_scan_loop();
119 testing::Mock::VerifyAndClearExpectations(&driver);
120
121 /* Release regular key */
122 EXPECT_REPORT(driver, (KC_B));
123 EXPECT_EMPTY_REPORT(driver);
124 regular_key.release();
125 run_one_scan_loop();
126 testing::Mock::VerifyAndClearExpectations(&driver);
127
128 /* Release layer-tap-hold key */
129 EXPECT_NO_REPORT(driver);
130 layer_tap_hold_key.release();
131 run_one_scan_loop();
132 testing::Mock::VerifyAndClearExpectations(&driver);
133}
diff --git a/users/drashna/config.h b/users/drashna/config.h
index 22c789b8c6..9edbfff56b 100644
--- a/users/drashna/config.h
+++ b/users/drashna/config.h
@@ -81,7 +81,6 @@
81#endif // !ONESHOT_TIMEOUT 81#endif // !ONESHOT_TIMEOUT
82 82
83#if defined(PER_KEY_TAPPING) 83#if defined(PER_KEY_TAPPING)
84# define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
85# define PERMISSIVE_HOLD_PER_KEY 84# define PERMISSIVE_HOLD_PER_KEY
86# define QUICK_TAP_TERM_PER_KEY 85# define QUICK_TAP_TERM_PER_KEY
87# define HOLD_ON_OTHER_KEY 86# define HOLD_ON_OTHER_KEY
diff --git a/users/drashna/keyrecords/tapping.c b/users/drashna/keyrecords/tapping.c
index 37945d2f67..6a26a02aca 100644
--- a/users/drashna/keyrecords/tapping.c
+++ b/users/drashna/keyrecords/tapping.c
@@ -42,21 +42,6 @@ __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyreco
42} 42}
43#endif // HOLD_ON_OTHER_KEY_PRESS_PER_KEY 43#endif // HOLD_ON_OTHER_KEY_PRESS_PER_KEY
44 44
45#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
46__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) {
47 // Do not force the mod-tap key press to be handled as a modifier
48 // if any other key was pressed while the mod-tap key is held down.
49 // return true;
50 // Force the mod-tap key press to be handled as a modifier if any
51 // other key was pressed while the mod-tap key is held down.
52 // return false;
53 switch (keycode) {
54 default:
55 return true;
56 }
57}
58#endif // IGNORE_MOD_TAP_INTERRUPT_PER_KEY
59
60#ifdef QUICK_TAP_TERM_PER_KEY 45#ifdef QUICK_TAP_TERM_PER_KEY
61__attribute__((weak)) uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { 46__attribute__((weak)) uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) {
62 switch (keycode) { 47 switch (keycode) {