From c438a6a69755ec7a96475695c4f26936651da8fd Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Wed, 3 Aug 2022 23:32:13 +0200 Subject: [PATCH 01/16] =?UTF-8?q?!get=5Fignore=5Fmod=5Ftap=5Finterrupt=20?= =?UTF-8?q?=E2=86=92=20get=5Fhold=5Fon=5Fother=5Fkey=5Fpress?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- quantum/action.c | 10 +++++----- quantum/action_tapping.c | 6 ++---- quantum/process_keycode/process_auto_shift.c | 12 ++++++------ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/quantum/action.c b/quantum/action.c index abf9834d2f39..ea6a24ea5c4e 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -55,8 +55,8 @@ int retro_tapping_counter = 0; # include "process_auto_shift.h" #endif -#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY -__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +#ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY +__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { return false; } #endif @@ -484,10 +484,10 @@ void process_action(keyrecord_t *record, action_t action) { default: if (event.pressed) { if (tap_count > 0) { -# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) +# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) if ( -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY - !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false), record) && +# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY + get_hold_on_other_key_press(get_event_keycode(record->event, false), record) && # endif record->tap.interrupted) { dprint("mods_tap: tap: cancel: add_mods\n"); diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 0350495ae578..7cd3bb293341 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -162,9 +162,7 @@ void action_tapping_process(keyrecord_t record) { # define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false # endif -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY -# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT get_ignore_mod_tap_interrupt(tapping_keycode, &tapping_key) -# elif defined(IGNORE_MOD_TAP_INTERRUPT) +# if defined(IGNORE_MOD_TAP_INTERRUPT) # define TAP_GET_IGNORE_MOD_TAP_INTERRUPT true # else # define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false @@ -216,7 +214,7 @@ bool process_tapping(keyrecord_t *keyp) { // Rolled over the two keys. (tapping_key.tap.interrupted == true && ( (TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) || - (TAP_IS_MT && !TAP_GET_IGNORE_MOD_TAP_INTERRUPT) + (TAP_IS_MT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) ) ) // 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 35d4851ee54e..43cd78e40c29 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c @@ -417,9 +417,9 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { # else ? false # endif -# if defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY - : !get_ignore_mod_tap_interrupt(keycode, record) +# if defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY + : get_hold_on_other_key_press(keycode, record) # else : false # endif @@ -454,10 +454,10 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { # endif ) { // Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set. -# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) +# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) if (autoshift_flags.in_progress -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY - && !get_ignore_mod_tap_interrupt(keycode, record) +# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY + && get_hold_on_other_key_press(keycode, record) # endif ) { autoshift_end(KC_NO, now, false, &autoshift_lastrecord); From 03bf0f91f398d0782044278687c082c4bc2781ff Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Mon, 24 Oct 2022 22:48:08 +0200 Subject: [PATCH 02/16] Remove IGNORE_MOD_TAP_INTERRUPT_PER_KEY from data files --- data/mappings/info_config.hjson | 1 - data/schemas/keyboard.jsonschema | 1 - 2 files changed, 2 deletions(-) diff --git a/data/mappings/info_config.hjson b/data/mappings/info_config.hjson index 479b1579dac2..b8789e178c7c 100644 --- a/data/mappings/info_config.hjson +++ b/data/mappings/info_config.hjson @@ -33,7 +33,6 @@ "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR": {"info_key": "dynamic_keymap.eeprom_max_addr", "value_type": "int"}, "DYNAMIC_KEYMAP_LAYER_COUNT": {"info_key": "dynamic_keymap.layer_count", "value_type": "int"}, "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "tapping.ignore_mod_tap_interrupt", "value_type": "bool"}, - "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "tapping.ignore_mod_tap_interrupt_per_key", "value_type": "bool"}, "HOLD_ON_OTHER_KEY_PRESS": {"info_key": "tapping.hold_on_other_key_press", "value_type": "bool"}, "HOLD_ON_OTHER_KEY_PRESS_PER_KEY": {"info_key": "tapping.hold_on_other_key_press_per_key", "value_type": "bool"}, "LAYOUTS": {"info_key": "layout_aliases", "value_type": "mapping"}, diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index 7844bfd57916..513564a643b0 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -620,7 +620,6 @@ "force_hold": {"type": "boolean"}, "force_hold_per_key": {"type": "boolean"}, "ignore_mod_tap_interrupt": {"type": "boolean"}, - "ignore_mod_tap_interrupt_per_key": {"type": "boolean"}, "hold_on_other_key_press": {"type": "boolean"}, "hold_on_other_key_press_per_key": {"type": "boolean"}, "permissive_hold": {"type": "boolean"}, From dfbd0e4fb945d7fb57df1618a0f3aee0bee1c2ab Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 19 Mar 2022 19:41:27 +0100 Subject: [PATCH 03/16] Remove I_M_T_I_P_K* refs from japanese docs *I_M_T_I_P_K = IGNORE_MOD_TAP_INTERRUPT_PER_KEY --- docs/ja/config_options.md | 2 -- docs/ja/tap_hold.md | 19 ------------------- 2 files changed, 21 deletions(-) diff --git a/docs/ja/config_options.md b/docs/ja/config_options.md index c95753bd5d7a..6135721a42b7 100644 --- a/docs/ja/config_options.md +++ b/docs/ja/config_options.md @@ -162,8 +162,6 @@ QMK での全ての利用可能な設定にはデフォルトがあります。 * `#define IGNORE_MOD_TAP_INTERRUPT` * 両方のキーに `TAPPING_TERM` を適用することで、ホールド時に他のキーに変換するキーを使ってローリングコンボ (zx) をすることができるようにします * 詳細は [Ignore Mod Tap Interrupt](ja/tap_hold.md#ignore-mod-tap-interrupt) を見てください -* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY` - * キーごとの `IGNORE_MOD_TAP_INTERRUPT` 設定の処理を有効にします * `#define TAPPING_FORCE_HOLD` * タップされた直後に、デュアルロールキーを修飾子として使用できるようにします * [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 07242821a998..ac64fe6ce3d7 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) { ?> `許容ホールド`を有効にすると、これは両方がどのように動作するかを変更します。通常のキーには、最初のキーが最初に放された場合、あるいは両方のキーが `TAPPING_TERM` より長くホールドされた場合に、修飾キーが追加されます。 -この機能をより細かく制御するために、以下を `config.h` に追加することができます: - -```c -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY -``` - -そして、以下の関数をキーマップに追加します: - -```c -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SFT_T(KC_SPC): - return true; - default: - return false; - } -} -``` - ## タッピング強制ホールド `タッピング強制ホールド` を有効にするには、以下を `config.h` に追加します: From 85cded3664b96ac60f9d72769a782092978c40a8 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 19 Mar 2022 19:42:26 +0100 Subject: [PATCH 04/16] Remove I_M_T_I_P_K* refs from english docs and update H_O_O_K_P* *I_M_T_I_P_K=IGNORE_MOD_TAP_INTERRUPT_PER_KEY *H_O_O_K_P=HOLD_ON_OTHER_KEY_PRESS --- docs/config_options.md | 7 ++- docs/feature_auto_shift.md | 11 +---- docs/tap_hold.md | 89 +++++++++++++++++++++++++++++++++----- 3 files changed, 84 insertions(+), 23 deletions(-) diff --git a/docs/config_options.md b/docs/config_options.md index edaa739201aa..7a91160bcdad 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 * `#define IGNORE_MOD_TAP_INTERRUPT` * 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. * See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for details -* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY` - * enables handling for per key `IGNORE_MOD_TAP_INTERRUPT` settings * `#define QUICK_TAP_TERM 100` * tap-then-hold timing to use a dual role key to repeat keycode * 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 * Defaults to `TAPPING_TERM` if not defined * `#define QUICK_TAP_TERM_PER_KEY` * enables handling for per key `QUICK_TAP_TERM` settings +* `#define HOLD_ON_OTHER_KEY_PRESS` + * 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. + * See "[hold on other key press](tap_hold.md#hold-on-other-key-press)" for details +* `#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY` + * enables handling for per key `HOLD_ON_OTHER_KEY_PRESS` settings * `#define LEADER_TIMEOUT 300` * how long before the leader key times out * 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 d3437a9c6070..1719807e2688 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. Referencing `TAPPING_TERM` makes little sense, as holding longer would result in shifting one of the keys. -`IGNORE_MOD_TAP_INTERRUPT` changes *only* rolling from a mod tap (releasing it -first), sending both keys instead of the modifier on the second. Its effects on -nested presses are ignored. - -As nested taps were changed to act as though `PERMISSIVE_HOLD` is set unless only -`IGNORE_MOD_TAP_INTERRUPT` is (outside of Retro Shift), and Retro Shift ignores -`IGNORE_MOD_TAP_INTERRUPT`, `PERMISSIVE_HOLD` has no effect on Mod Taps. - -Nested taps will *always* act as though the `TAPPING_TERM` was exceeded for both -Mod and Layer Tap keys. +`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. ## Using Auto Shift Setup diff --git a/docs/tap_hold.md b/docs/tap_hold.md index fa6c6abc14de..bffe77d6f2e2 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 The 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: -1. 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. +1. 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. 2. 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. @@ -126,6 +126,73 @@ The code which decides between the tap and hold actions of dual-role keys suppor Note 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. +### Illustration :id=illustration + +To 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. + +By 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`. + +Note: "`kc` held" in the "Physical key event" column means that the key wasn't physically released yet at this point in time. + +#### Distinct taps (AABB) :id=distinct-taps + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 199 | `LSFT_T(KC_A)` up | a | a | a | +| 210 | `KC_B` down | ab | ab | ab | +| 220 | `KC_B` up | ab | ab | ab | + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 200 | `LSFT_T(KC_A)` held|Shift| Shift | Shift | +| 201 | `LSFT_T(KC_A)` up |Shift| Shift | Shift | +| 205 | `KC_B` down | b | b | b | +| 210 | `KC_B` up | b | b | b | + +#### Nested tap (ABBA) :id=nested-tap + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 110 | `KC_B` down | | | B | +| 120 | `KC_B` up | | B | B | +| 199 | `LSFT_T(KC_A)` up | ab | B | B | + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 110 | `KC_B` down | | | B | +| 120 | `KC_B` up | | B | B | +| 200 | `LSFT_T(KC_A)` held| B | B | B | +| 210 | `LSFT_T(KC_A)` up | B | B | B | + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 200 | `LSFT_T(KC_A)` held|Shift| Shift | Shift | +| 205 | `KC_B` down | B | B | B | +| 210 | `KC_B` up | B | B | B | +| 220 | `LSFT_T(KC_A)` up | B | B | B | + +#### Rolling keys (ABAB) :id=rolling-keys + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 110 | `KC_B` down | | | B | +| 130 | `LSFT_T(KC_A)` up | ab | ab | B | +| 140 | `KC_B` up | ab | ab | B | + +| Time | Physical key event |Ignore Interrupt| `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | +|------|--------------------|----------------|-------------------|----------------------------| +| 0 | `LSFT_T(KC_A)` down| | | | +| 110 | `KC_B` down | | | B | +| 200 | `LSFT_T(KC_A)` held| B | B | B | +| 205 | `LSFT_T(KC_A)` up | B | B | B | +| 210 | `KC_B` up | B | B | B | + ### Default Mode Example sequence 1 (the `L` key is also mapped to `KC_RGHT` on layer 2): @@ -179,8 +246,6 @@ since `SFT_T(KC_A)` is NOT held longer than the `TAPPING_TERM`. However, the actual output would be capital `X` (`SHIFT` + `x`) due to reasons explained under [Ignore Mod Tap Interrupt](#ignore-mod-tap-interrupt). - - ### Permissive Hold The “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: +---------------------------|--------+ ``` -Normally, 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). +Normally, 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). However, this slightly different sequence will not be affected by the “permissive hold” mode: @@ -235,7 +300,7 @@ However, this slightly different sequence will not be affected by the “permiss In 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). -?> 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. +?> 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. For more granular control of this feature, you can add the following to your `config.h`: @@ -291,7 +356,7 @@ An example of a sequence that is affected by the “hold on other key press” m Normally, 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). -?> 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. +?> 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. For more granular control of this feature, you can add the following to your `config.h`: @@ -355,26 +420,28 @@ However, if the `HOLD_ON_OTHER_KEY_PRESS` option is enabled in addition to `IGNO For more granular control of this feature, you can add the following to your `config.h`: ```c -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY ``` You can then add the following function to your keymap: ```c -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case SFT_T(KC_SPC): // Do not force the mod-tap key press to be handled as a modifier // if any other key was pressed while the mod-tap key is held down. - return true; + return false; default: - // Force the mod-tap key press to be handled as a modifier if any + // Force the dual-role key press to be handled as a modifier if any // other key was pressed while the mod-tap key is held down. - return false; + return true; } } ``` +Keep in mind that the `keycode` argument of the `get_hold_on_other_key_press` function can be any dual-role key; it is not limited to mod-taps. + ## Quick Tap Term When 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. From 9f8e2431755879ea19534ce802cb1b343ad02572 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 19 Mar 2022 19:38:56 +0100 Subject: [PATCH 05/16] =?UTF-8?q?tap=5Fmod=5Ftap=5Fkey=5Fwhile=5Fmod=5Ftap?= =?UTF-8?q?=5Fkey=5Fis=5Fheld=20=E2=86=92=20tap=5Fa=5Fmod=5Ftap=5Fkey=5Fwh?= =?UTF-8?q?ile=5Fanother=5Fmod=5Ftap=5Fkey=5Fis=5Fheld?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/tap_hold_configurations/default_mod_tap/config.h | 2 +- tests/tap_hold_configurations/default_mod_tap/test_tap_hold.cpp | 2 +- tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h | 2 +- tests/tap_hold_configurations/permissive_hold/test_tap_hold.cpp | 2 +- .../permissive_hold_ignore_mod_tap_interrupt/config.h | 2 +- .../permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/tap_hold_configurations/default_mod_tap/config.h b/tests/tap_hold_configurations/default_mod_tap/config.h index 5955b8600a87..f22448845e62 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 @@ #include "test_common.h" -#define IGNORE_MOD_TAP_INTERRUPT \ No newline at end of file +#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 b70efe4aeda9..01943c10d261 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) { testing::Mock::VerifyAndClearExpectations(&driver); } -TEST_F(DefaultTapHold, tap_mod_tap_key_while_mod_tap_key_is_held) { +TEST_F(DefaultTapHold, tap_a_mod_tap_key_while_another_mod_tap_key_is_held) { TestDriver driver; InSequence s; 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 index 5955b8600a87..f22448845e62 100644 --- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h +++ b/tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h @@ -18,4 +18,4 @@ #include "test_common.h" -#define IGNORE_MOD_TAP_INTERRUPT \ No newline at end of file +#define IGNORE_MOD_TAP_INTERRUPT 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 74e81f347f6a..e6ecc8640150 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) { testing::Mock::VerifyAndClearExpectations(&driver); } -TEST_F(PermissiveHold, tap_mod_tap_key_while_mod_tap_key_is_held) { +TEST_F(PermissiveHold, tap_a_mod_tap_key_while_another_mod_tap_key_is_held) { TestDriver driver; InSequence s; 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 index a6abd50bbee7..a16736f43cad 100644 --- 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 @@ -19,4 +19,4 @@ #include "test_common.h" #define IGNORE_MOD_TAP_INTERRUPT -#define PERMISSIVE_HOLD \ No newline at end of file +#define PERMISSIVE_HOLD 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 index ee7e707c948e..490952b6dadb 100644 --- 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 @@ -62,7 +62,7 @@ TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_regular_key_while_mod_tap_key_i testing::Mock::VerifyAndClearExpectations(&driver); } -TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_mod_tap_key_while_mod_tap_key_is_held) { +TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_a_mod_tap_key_while_another_mod_tap_key_is_held) { TestDriver driver; InSequence s; auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); From dcda4a68aa264c63fc34625064c589f9a3e3192e Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Wed, 13 Apr 2022 12:59:47 +0200 Subject: [PATCH 06/16] Delete ignore_mod_tap_interrupt tests folder --- .../ignore_mod_tap_interrupt/config.h | 21 --- .../ignore_mod_tap_interrupt/test.mk | 18 --- .../test_tap_hold.cpp | 136 ------------------ 3 files changed, 175 deletions(-) delete mode 100644 tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h delete mode 100644 tests/tap_hold_configurations/ignore_mod_tap_interrupt/test.mk delete mode 100644 tests/tap_hold_configurations/ignore_mod_tap_interrupt/test_tap_hold.cpp 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 f22448845e62..000000000000 --- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/config.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2021 Stefan Kerkmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "test_common.h" - -#define IGNORE_MOD_TAP_INTERRUPT 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 efecca2c22f0..000000000000 --- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test.mk +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2021 Stefan Kerkmann -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# -------------------------------------------------------------------------------- -# Keep this file, even if it is empty, as a marker that this folder contains tests -# -------------------------------------------------------------------------------- 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 319de6107031..000000000000 --- a/tests/tap_hold_configurations/ignore_mod_tap_interrupt/test_tap_hold.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright 2021 Stefan Kerkmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "keyboard_report_util.hpp" -#include "keycode.h" -#include "test_common.hpp" -#include "action_tapping.h" -#include "test_fixture.hpp" -#include "test_keymap_key.hpp" - -using testing::_; -using testing::InSequence; - -class IgnoreModTapInterrupt : public TestFixture {}; - -TEST_F(IgnoreModTapInterrupt, tap_regular_key_while_mod_tap_key_is_held) { - TestDriver driver; - InSequence s; - auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); - auto regular_key = KeymapKey(0, 2, 0, KC_A); - - set_keymap({mod_tap_hold_key, regular_key}); - - /* Press mod-tap-hold key */ - EXPECT_NO_REPORT(driver); - mod_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Press regular key */ - EXPECT_NO_REPORT(driver); - regular_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release regular key */ - EXPECT_NO_REPORT(driver); - regular_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release mod-tap-hold key */ - EXPECT_REPORT(driver, (KC_P)); - EXPECT_REPORT(driver, (KC_A, KC_P)); - EXPECT_REPORT(driver, (KC_P)); - EXPECT_EMPTY_REPORT(driver); - mod_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); -} - -TEST_F(IgnoreModTapInterrupt, tap_mod_tap_key_while_mod_tap_key_is_held) { - TestDriver driver; - InSequence s; - auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); - auto second_mod_tap_hold_key = KeymapKey(0, 2, 0, RSFT_T(KC_A)); - - set_keymap({first_mod_tap_hold_key, second_mod_tap_hold_key}); - - /* Press first mod-tap-hold key */ - EXPECT_NO_REPORT(driver); - first_mod_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Press second tap-hold key */ - EXPECT_NO_REPORT(driver); - second_mod_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release second tap-hold key */ - EXPECT_NO_REPORT(driver); - second_mod_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release first mod-tap-hold key */ - EXPECT_REPORT(driver, (KC_P)); - EXPECT_REPORT(driver, (KC_A, KC_P)); - EXPECT_REPORT(driver, (KC_P)); - EXPECT_EMPTY_REPORT(driver); - first_mod_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); -} - -TEST_F(IgnoreModTapInterrupt, tap_regular_key_while_layer_tap_key_is_held) { - TestDriver driver; - InSequence s; - auto layer_tap_hold_key = KeymapKey(0, 1, 0, LT(1, KC_P)); - auto regular_key = KeymapKey(0, 2, 0, KC_A); - auto layer_key = KeymapKey(1, 2, 0, KC_B); - - set_keymap({layer_tap_hold_key, regular_key, layer_key}); - - /* Press layer-tap-hold key */ - EXPECT_NO_REPORT(driver); - layer_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Press regular key */ - EXPECT_NO_REPORT(driver); - regular_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release regular key */ - EXPECT_NO_REPORT(driver); - regular_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release layer-tap-hold key */ - EXPECT_REPORT(driver, (KC_P)); - EXPECT_REPORT(driver, (KC_P, regular_key.report_code)); - EXPECT_REPORT(driver, (KC_P)); - EXPECT_EMPTY_REPORT(driver); - layer_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); -} From c4d85035bc10b627f2c876361ab6fee80cdc707a Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Wed, 13 Apr 2022 14:34:37 +0200 Subject: [PATCH 07/16] Delete permissive_hold_ignore_mod_tap_interrupt/ --- .../config.h | 22 --- .../test.mk | 18 --- .../test_tap_hold.cpp | 133 ------------------ 3 files changed, 173 deletions(-) delete mode 100644 tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/config.h delete mode 100644 tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test.mk delete mode 100644 tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp 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 a16736f43cad..000000000000 --- a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/config.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2021 Stefan Kerkmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#pragma once - -#include "test_common.h" - -#define IGNORE_MOD_TAP_INTERRUPT -#define PERMISSIVE_HOLD 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 efecca2c22f0..000000000000 --- a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test.mk +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2021 Stefan Kerkmann -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# -------------------------------------------------------------------------------- -# Keep this file, even if it is empty, as a marker that this folder contains tests -# -------------------------------------------------------------------------------- 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 490952b6dadb..000000000000 --- a/tests/tap_hold_configurations/permissive_hold_ignore_mod_tap_interrupt/test_tap_hold.cpp +++ /dev/null @@ -1,133 +0,0 @@ - -/* Copyright 2021 Stefan Kerkmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "keyboard_report_util.hpp" -#include "keycode.h" -#include "test_common.hpp" -#include "action_tapping.h" -#include "test_fixture.hpp" -#include "test_keymap_key.hpp" - -using testing::_; -using testing::InSequence; - -class PermissiveHold_IgnoreModTapInterrupt : public TestFixture {}; - -TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_regular_key_while_mod_tap_key_is_held) { - TestDriver driver; - InSequence s; - auto mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); - auto regular_key = KeymapKey(0, 2, 0, KC_A); - - set_keymap({mod_tap_hold_key, regular_key}); - - /* Press mod-tap-hold key */ - EXPECT_NO_REPORT(driver); - mod_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Press regular key */ - EXPECT_NO_REPORT(driver); - regular_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release regular key */ - EXPECT_REPORT(driver, (KC_LSFT)); - EXPECT_REPORT(driver, (KC_LSFT, KC_A)); - EXPECT_REPORT(driver, (KC_LSFT)); - regular_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release mod-tap-hold key */ - EXPECT_EMPTY_REPORT(driver); - mod_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); -} - -TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_a_mod_tap_key_while_another_mod_tap_key_is_held) { - TestDriver driver; - InSequence s; - auto first_mod_tap_hold_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); - auto second_mod_tap_hold_key = KeymapKey(0, 2, 0, RSFT_T(KC_A)); - - set_keymap({first_mod_tap_hold_key, second_mod_tap_hold_key}); - - /* Press first mod-tap-hold key */ - EXPECT_NO_REPORT(driver); - first_mod_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Press second tap-hold key */ - EXPECT_NO_REPORT(driver); - second_mod_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release second tap-hold key */ - EXPECT_REPORT(driver, (KC_LSFT)); - EXPECT_REPORT(driver, (KC_LSFT, KC_A)); - EXPECT_REPORT(driver, (KC_LSFT)); - second_mod_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release first mod-tap-hold key */ - EXPECT_EMPTY_REPORT(driver); - first_mod_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); -} - -TEST_F(PermissiveHold_IgnoreModTapInterrupt, tap_regular_key_while_layer_tap_key_is_held) { - TestDriver driver; - InSequence s; - auto layer_tap_hold_key = KeymapKey(0, 1, 0, LT(1, KC_P)); - auto regular_key = KeymapKey(0, 2, 0, KC_A); - auto layer_key = KeymapKey(1, 2, 0, KC_B); - - set_keymap({layer_tap_hold_key, regular_key, layer_key}); - - /* Press layer-tap-hold key */ - EXPECT_NO_REPORT(driver); - layer_tap_hold_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Press regular key */ - EXPECT_NO_REPORT(driver); - regular_key.press(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release regular key */ - EXPECT_REPORT(driver, (KC_B)); - EXPECT_EMPTY_REPORT(driver); - regular_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); - - /* Release layer-tap-hold key */ - EXPECT_NO_REPORT(driver); - layer_tap_hold_key.release(); - run_one_scan_loop(); - testing::Mock::VerifyAndClearExpectations(&driver); -} From 490101480e2b858829bc03989363a1dca5a8dd39 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Sat, 18 Jun 2022 09:18:04 +0200 Subject: [PATCH 08/16] Flag IGNORE_MOD_TAP_INTERRUPT_PER_KEY as invalid in lint checks --- data/mappings/info_config.hjson | 1 + 1 file changed, 1 insertion(+) diff --git a/data/mappings/info_config.hjson b/data/mappings/info_config.hjson index b8789e178c7c..7a4d42bae4e7 100644 --- a/data/mappings/info_config.hjson +++ b/data/mappings/info_config.hjson @@ -128,6 +128,7 @@ "QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true}, "TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true}, "TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true}, + "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true} // USB params, need to mark as failure when specified in config.h, rather than deprecated "PRODUCT_ID": {"info_key": "usb.pid", "value_type": "hex", "deprecated": true, "replace_with": "`usb.pid` in info.json"}, From 9050d21d48b5d4240bcb2167086aac4391173fab Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Wed, 3 Aug 2022 23:23:49 +0200 Subject: [PATCH 09/16] Flag IGNORE_MOD_TAP_INTERRUPT as deprecated in lint --- data/mappings/info_config.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/mappings/info_config.hjson b/data/mappings/info_config.hjson index 7a4d42bae4e7..7645598c776d 100644 --- a/data/mappings/info_config.hjson +++ b/data/mappings/info_config.hjson @@ -32,7 +32,6 @@ "FORCE_NKRO": {"info_key": "usb.force_nkro", "value_type": "bool"}, "DYNAMIC_KEYMAP_EEPROM_MAX_ADDR": {"info_key": "dynamic_keymap.eeprom_max_addr", "value_type": "int"}, "DYNAMIC_KEYMAP_LAYER_COUNT": {"info_key": "dynamic_keymap.layer_count", "value_type": "int"}, - "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "tapping.ignore_mod_tap_interrupt", "value_type": "bool"}, "HOLD_ON_OTHER_KEY_PRESS": {"info_key": "tapping.hold_on_other_key_press", "value_type": "bool"}, "HOLD_ON_OTHER_KEY_PRESS_PER_KEY": {"info_key": "tapping.hold_on_other_key_press_per_key", "value_type": "bool"}, "LAYOUTS": {"info_key": "layout_aliases", "value_type": "mapping"}, @@ -128,6 +127,7 @@ "QMK_KEYS_PER_SCAN": {"info_key": "qmk.keys_per_scan", "value_type": "int", "deprecated": true}, "TAPPING_FORCE_HOLD": {"info_key": "tapping.force_hold", "value_type": "bool", "deprecated": true}, "TAPPING_FORCE_HOLD_PER_KEY": {"info_key": "tapping.force_hold_per_key", "value_type": "bool", "deprecated": true}, + "IGNORE_MOD_TAP_INTERRUPT": {"info_key": "_deprecated.ignore_mod_tap_interrupt", "value_type": "bool", "deprecated": true}, "IGNORE_MOD_TAP_INTERRUPT_PER_KEY": {"info_key": "_invalid.ignore_mod_tap_interrupt_per_key", "invalid": true} // USB params, need to mark as failure when specified in config.h, rather than deprecated From e25f36fe5db6bfc6828130c4e730b997da2999a1 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Tue, 3 May 2022 18:47:10 +0200 Subject: [PATCH 10/16] Backwards compatibility with defunct `get_ignore_mod_tap_interrupt`. --- keyboards/adm42/rev4/keymaps/default/config.h | 1 - keyboards/adm42/rev4/keymaps/default/keymap.c | 18 ++++++------------ .../bastardkb/scylla/keymaps/cykedev/config.h | 7 ++----- .../bastardkb/scylla/keymaps/cykedev/keymap.c | 13 +++++++------ .../usb_usb/keymaps/chriskopher/config.h | 3 +-- .../usb_usb/keymaps/chriskopher/keymap.c | 10 +++++----- keyboards/crkbd/keymaps/snowe/config.h | 1 - keyboards/crkbd/keymaps/snowe/keymap.c | 10 ++++++---- keyboards/ergodox_ez/keymaps/stamm/config.h | 4 ++-- keyboards/ergodox_ez/keymaps/stamm/keymap.c | 4 ++-- .../5x6_5/keymaps/cykedev/config.h | 5 +---- .../5x6_5/keymaps/cykedev/keymap.c | 12 ++++++------ keyboards/lily58/keymaps/cykedev/config.h | 2 +- keyboards/lily58/keymaps/cykedev/keymap.c | 4 +++- keyboards/planck/keymaps/adamtabrams/config.h | 4 ++-- keyboards/planck/keymaps/adamtabrams/keymap.c | 4 ++-- keyboards/planck/keymaps/rootiest/config.h | 2 +- keyboards/planck/keymaps/rootiest/keymap.c | 6 ++++-- keyboards/torn/keymaps/kinesish/config.h | 2 +- keyboards/torn/keymaps/kinesish/keymap.c | 12 ++++++------ users/drashna/config.h | 1 - users/drashna/keyrecords/tapping.c | 15 --------------- 22 files changed, 58 insertions(+), 82 deletions(-) diff --git a/keyboards/adm42/rev4/keymaps/default/config.h b/keyboards/adm42/rev4/keymaps/default/config.h index 4082d84a3aa3..abfaf9af7892 100644 --- a/keyboards/adm42/rev4/keymaps/default/config.h +++ b/keyboards/adm42/rev4/keymaps/default/config.h @@ -1,3 +1,2 @@ #define HOLD_ON_OTHER_KEY_PRESS_PER_KEY #define QUICK_TAP_TERM_PER_KEY -#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 245a3bd4ded5..154073beb767 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] = { ), }; -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case RC_QUT: - return true; - default: +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { + // Special if-condition outside the switch because `RC_QUT` overlaps with + // the `QK_MOD_TAP ... QK_MOD_TAP_MAX` range. + if (keycode == RC_QUT) { return false; } -} - -bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { - case LLS_ESC: - case LLS_RALT: - case LLE_ENT: - case LLA_DEL: + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: return true; default: return false; diff --git a/keyboards/bastardkb/scylla/keymaps/cykedev/config.h b/keyboards/bastardkb/scylla/keymaps/cykedev/config.h index 43037350f6d0..6119f2738b69 100644 --- a/keyboards/bastardkb/scylla/keymaps/cykedev/config.h +++ b/keyboards/bastardkb/scylla/keymaps/cykedev/config.h @@ -28,15 +28,12 @@ #define TAPPING_TERM 200 -// Prevent normal rollover on alphas from accidentally triggering mods. -// #define IGNORE_MOD_TAP_INTERRUPT - // Enable rapid switch from tap to hold, disables double tap hold auto-repeat. // #define QUICK_TAP_TERM 0 // Apply the modifier on keys that are tapped during a short hold of a modtap // #define PERMISSIVE_HOLD -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY -#define FORCE_NKRO \ No newline at end of file +#define FORCE_NKRO diff --git a/keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c b/keyboards/bastardkb/scylla/keymaps/cykedev/keymap.c index 9f497e2c1421..a51f5b9d3869 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] = { ) }; -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case CM_SPAR: - return true; - default: - return false; +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { + if (keycode == CM_SPAR) { + return false; + } else if (QK_MOD_TAP <= keycode && keycode <= QK_MOD_TAP_MAX) { + return true; + } else { + return false; } } diff --git a/keyboards/converter/usb_usb/keymaps/chriskopher/config.h b/keyboards/converter/usb_usb/keymaps/chriskopher/config.h index 7714f713bd81..04066edc0279 100644 --- a/keyboards/converter/usb_usb/keymaps/chriskopher/config.h +++ b/keyboards/converter/usb_usb/keymaps/chriskopher/config.h @@ -18,8 +18,7 @@ #define TAPPING_TERM 200 // Delay for tap modifiers until it is considered a hold -#define IGNORE_MOD_TAP_INTERRUPT // Enable ignore mod tap interrupt: https://docs.qmk.fm/#/tap_hold?id=ignore-mod-tap-interrupt -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY // Allows configuration of ignore mod tap interrupt per key in keymap.c +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY // Allows configuration of hold on other key press per key in keymap.c #define COMBO_COUNT 2 // Number of defined combos #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 4113cdc67ce8..76cf31146299 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] = { }; // clang-format on -// Configure ignore mod tap interrupt per key -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +// Configure hold on other key press per key +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { - // I don't like how mod tap interrupt feels with these keys specifically when I'm typing + // I don't like how ignore interrupt feels with these keys specifically when I'm typing case LCTL_T(KC_ESC): - return false; - default: return true; + default: + return false; } } diff --git a/keyboards/crkbd/keymaps/snowe/config.h b/keyboards/crkbd/keymaps/snowe/config.h index b091cd790320..57a253428b87 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 . // fix for me putting alt under A and being a fast typist #define IGNORE_MOD_TAP_INTERRUPT -//#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY #define LAYER_STATE_8BIT #define SPLIT_WPM_ENABLE diff --git a/keyboards/crkbd/keymaps/snowe/keymap.c b/keyboards/crkbd/keymaps/snowe/keymap.c index 685491903e54..91f0ceafeb6e 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) { // } //} // -// bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +// bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { +// if (keycode == ALT_T(KC_A) || keycode == SH_BKSP) { +// return false; +// } // switch (keycode) { -// case ALT_T(KC_A): -// case SH_BKSP: +// case QK_MOD_TAP ... QK_MOD_TAP_MAX: // return true; // default: // return false; // } -//} \ No newline at end of file +//} diff --git a/keyboards/ergodox_ez/keymaps/stamm/config.h b/keyboards/ergodox_ez/keymaps/stamm/config.h index f9e89d276fa0..1262ce655976 100644 --- a/keyboards/ergodox_ez/keymaps/stamm/config.h +++ b/keyboards/ergodox_ez/keymaps/stamm/config.h @@ -29,8 +29,8 @@ #define PERMISSIVE_HOLD /* #define PERMISSIVE_HOLD_PER_KEY */ -#define IGNORE_MOD_TAP_INTERRUPT -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#define HOLD_ON_OTHER_KEY_PRESS +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY #define QUICK_TAP_TERM 0 #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 aa9debfe57cc..8a3e30f5f6f3 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) { return TAPPING_TERM; } } -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case E_NUMBERS: case R_MOUSE: @@ -219,7 +219,7 @@ bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { case RCTL_T(KC_L): case RSFT_T(KC_SEMICOLON): case ARROWS: - return true; + return false; default: return false; } 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 7b43dcb5d449..6a28251c6bf2 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 @@ // Configure the global tapping term (default: 200ms) #define TAPPING_TERM 200 -// Prevent normal rollover on alphas from accidentally triggering mods. -#define IGNORE_MOD_TAP_INTERRUPT -//#define IGNORE_MOD_TAP_INTERRUPT -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY // Enable rapid switch from tap to hold, disables double tap hold auto-repeat. #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 413fa70492bd..9687e77d884e 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) { return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); } -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case SPC_L: - return false; - case SPC_R: return true; - case ENT_L: + case SPC_R: return false; + case ENT_L: + return true; case ENT_R: - return false; - default: return true; + default: + return false; } } diff --git a/keyboards/lily58/keymaps/cykedev/config.h b/keyboards/lily58/keymaps/cykedev/config.h index dac88dff7743..d9e43606a40f 100644 --- a/keyboards/lily58/keymaps/cykedev/config.h +++ b/keyboards/lily58/keymaps/cykedev/config.h @@ -17,4 +17,4 @@ #define MASTER_LEFT #define TAPPING_TERM 200 -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#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 94db33771a3e..88d9728469e0 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] = { ) }; -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case SY_SPC: + return false; + case QK_MOD_TAP ... QK_MOD_TAP_MAX: return true; default: return false; diff --git a/keyboards/planck/keymaps/adamtabrams/config.h b/keyboards/planck/keymaps/adamtabrams/config.h index 8ff86760b450..d47e552434ab 100644 --- a/keyboards/planck/keymaps/adamtabrams/config.h +++ b/keyboards/planck/keymaps/adamtabrams/config.h @@ -33,7 +33,7 @@ // Tap-Hold Configs #define TAPPING_TERM 180 #define PERMISSIVE_HOLD -#define IGNORE_MOD_TAP_INTERRUPT -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#define HOLD_ON_OTHER_KEY_PRESS +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY #define QUICK_TAP_TERM 0 #define QUICK_TAP_TERM_PER_KEY diff --git a/keyboards/planck/keymaps/adamtabrams/keymap.c b/keyboards/planck/keymaps/adamtabrams/keymap.c index 2203ecd30f40..ce1acd437b5b 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) { } } -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case ALT__A: case ALTSCLN: @@ -272,7 +272,7 @@ bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { case CTL__J: case CTL__T: case CTL__N: - return true; + return false; default: return false; } diff --git a/keyboards/planck/keymaps/rootiest/config.h b/keyboards/planck/keymaps/rootiest/config.h index bdb5cea91b92..1cca7e5ba9a5 100644 --- a/keyboards/planck/keymaps/rootiest/config.h +++ b/keyboards/planck/keymaps/rootiest/config.h @@ -118,7 +118,7 @@ */ #define RETRO_TAPPING_PER_KEY // Control Retro-Tap individually by key #define QUICK_TAP_TERM_PER_KEY // Control Quick-Tap individually by key -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY // Control Mod-Tap-Interrupt individually by key +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY // Control Hold-on-Other-Key-Press individually by key #define PERMISSIVE_HOLD_PER_KEY // Control Permissive-Hold individually by key #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 cc43aff67381..9b6bc9cc1823 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) { return false; } } -// Handles per-key configuration of Mod-Tap-Interrupt -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t* record) { +// Handles per-key configuration of Hold-on-Other-Key-Press +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t* record) { switch (keycode) { + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + return true; default: return false; } diff --git a/keyboards/torn/keymaps/kinesish/config.h b/keyboards/torn/keymaps/kinesish/config.h index 734512e6cde5..5c4de67989ac 100644 --- a/keyboards/torn/keymaps/kinesish/config.h +++ b/keyboards/torn/keymaps/kinesish/config.h @@ -17,5 +17,5 @@ #pragma once #define TAPPING_TERM 200 -#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY +#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY #define PERMISSIVE_HOLD_PER_KEY diff --git a/keyboards/torn/keymaps/kinesish/keymap.c b/keyboards/torn/keymaps/kinesish/keymap.c index 13f3304068de..9ddbac3601bf 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) { } /* - * Enable `IGNORE_MOD_TAP_INTERRUPT` for all modifiers except `Shift`. - * For more info see `IGNORE_MOD_TAP_INTERRUPT_PER_KEY` in `docs/tap_hold.md`. + * Enable `HOLD_ON_OTHER_KEY_PRESS` only for `Shift`. + * For more info see `HOLD_ON_OTHER_KEY_PRESS_PER_KEY` in `docs/tap_hold.md`. */ -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case S_EQL: - return false; + return true; case S_MINS: - return false; - default: return true; + default: + return false; } } diff --git a/users/drashna/config.h b/users/drashna/config.h index 22c789b8c689..9edbfff56b2a 100644 --- a/users/drashna/config.h +++ b/users/drashna/config.h @@ -81,7 +81,6 @@ #endif // !ONESHOT_TIMEOUT #if defined(PER_KEY_TAPPING) -# define IGNORE_MOD_TAP_INTERRUPT_PER_KEY # define PERMISSIVE_HOLD_PER_KEY # define QUICK_TAP_TERM_PER_KEY # define HOLD_ON_OTHER_KEY diff --git a/users/drashna/keyrecords/tapping.c b/users/drashna/keyrecords/tapping.c index 37945d2f67a7..6a26a02aca33 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 } #endif // HOLD_ON_OTHER_KEY_PRESS_PER_KEY -#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY -__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { - // Do not force the mod-tap key press to be handled as a modifier - // if any other key was pressed while the mod-tap key is held down. - // return true; - // Force the mod-tap key press to be handled as a modifier if any - // other key was pressed while the mod-tap key is held down. - // return false; - switch (keycode) { - default: - return true; - } -} -#endif // IGNORE_MOD_TAP_INTERRUPT_PER_KEY - #ifdef QUICK_TAP_TERM_PER_KEY __attribute__((weak)) uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { switch (keycode) { From cc5a570f35d81f68af5282969d45572a44a8f4d6 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Wed, 3 Aug 2022 23:12:31 +0200 Subject: [PATCH 11/16] Message announcing deprecation of IGNORE_MOD_TAP_INTERRUPT Remove mention of layer-taps in IMTI* deprecation message IMTI* = IGNORE_MOD_TAP_INTERRUPT --- quantum/action_tapping.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 7cd3bb293341..f985d3b33bdf 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -15,6 +15,14 @@ #ifndef NO_ACTION_TAPPING +# if defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) +# 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." +# elif !defined(IGNORE_MOD_TAP_INTERRUPT) +# if !defined(PERMISSIVE_HOLD) && !defined(PERMISSIVE_HOLD_PER_KEY) && !defined(HOLD_ON_OTHER_KEY_PRESS) && !defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +# pragma message "IGNORE_MOD_TAP_INTERRUPT has been deprecated and will become the new standard behavior of mod-taps in the future. Please use HOLD_ON_OTHER_KEY_PRESS if you want to keep the old behavior of mod-taps." +# endif +# endif + # define IS_TAPPING() !IS_NOEVENT(tapping_key.event) # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) From 04bf58e05d94e484c48d793b4cadc0358abf6a4d Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Thu, 4 Aug 2022 00:14:23 +0200 Subject: [PATCH 12/16] Replace auto shift's ternary from hell by a bool `is_hold_on_interrupt` --- quantum/process_keycode/process_auto_shift.c | 35 +++++++------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index 43cd78e40c29..b7ac449198e5 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) { break; # endif } - // If Retro Shift is disabled, possible custom actions shouldn't happen. - // clang-format off + // If Retro Shift is disabled, possible custom actions shouldn't happen. + // clang-format off +# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) +# if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) + const bool is_hold_on_interrupt = get_hold_on_other_key_press(keycode, record); +# elif defined(IGNORE_MOD_TAP_INTERRUPT) + const bool is_hold_on_interrupt = false; +# else + const bool is_hold_on_interrupt = IS_MT(keycode); +# endif +# endif if (IS_RETRO(keycode) # if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) // 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) { # ifdef RETRO_TAPPING_PER_KEY || !get_retro_tapping(keycode, record) # endif - || (record->tap.interrupted && (IS_LT(keycode) -# if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - ? get_hold_on_other_key_press(keycode, record) -# else - ? true -# endif -# else - ? false -# endif -# if defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - : get_hold_on_other_key_press(keycode, record) -# else - : false -# endif -# else - : true -# endif - )) - ) + || (record->tap.interrupted && is_hold_on_interrupt)) # endif ) { // clang-format on From 11fa40d42ceac22e055ae190635479c2e3bdbe71 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Mon, 28 Nov 2022 20:36:36 +0100 Subject: [PATCH 13/16] Reword message to emphasize changes in the *default* behavior of MTs --- quantum/action_tapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index f985d3b33bdf..ca0f31f12e4f 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -19,7 +19,7 @@ # 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." # elif !defined(IGNORE_MOD_TAP_INTERRUPT) # if !defined(PERMISSIVE_HOLD) && !defined(PERMISSIVE_HOLD_PER_KEY) && !defined(HOLD_ON_OTHER_KEY_PRESS) && !defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) -# pragma message "IGNORE_MOD_TAP_INTERRUPT has been deprecated and will become the new standard behavior of mod-taps in the future. Please use HOLD_ON_OTHER_KEY_PRESS if you want to keep the old behavior of mod-taps." +# 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." # endif # endif From 694e5933c3c3438af5e82e0656a4c0316bad2f7e Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Mon, 12 Dec 2022 09:43:43 +0100 Subject: [PATCH 14/16] =?UTF-8?q?Rename=20=E2=80=9CIllustration=E2=80=9D?= =?UTF-8?q?=20section=20by=20=E2=80=9CComparison=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tap_hold.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tap_hold.md b/docs/tap_hold.md index bffe77d6f2e2..244f80f6ca42 100644 --- a/docs/tap_hold.md +++ b/docs/tap_hold.md @@ -126,7 +126,7 @@ The code which decides between the tap and hold actions of dual-role keys suppor Note 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. -### Illustration :id=illustration +### Comparison :id=comparison To 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. From 8d91044f9affb551c68171eaa367e3a7fa1a5907 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Mon, 12 Dec 2022 10:01:46 +0100 Subject: [PATCH 15/16] =?UTF-8?q?More=20explanations=20on=20using=20`get?= =?UTF-8?q?=5Fhold=5Fon=E2=80=A6`=20to=20obtain=20ignore-interrupt=20behav?= =?UTF-8?q?ior.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/tap_hold.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/tap_hold.md b/docs/tap_hold.md index 244f80f6ca42..348e2655eb76 100644 --- a/docs/tap_hold.md +++ b/docs/tap_hold.md @@ -130,7 +130,7 @@ Note that until the tap-or-hold decision completes (which happens when either th To 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. -By 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`. +By 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. Note: "`kc` held" in the "Physical key event" column means that the key wasn't physically released yet at this point in time. @@ -423,6 +423,8 @@ For more granular control of this feature, you can add the following to your `co #define HOLD_ON_OTHER_KEY_PRESS_PER_KEY ``` +?> This option affects *all* dual-role keys. + You can then add the following function to your keymap: ```c @@ -440,7 +442,9 @@ bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { } ``` -Keep in mind that the `keycode` argument of the `get_hold_on_other_key_press` function can be any dual-role key; it is not limited to mod-taps. +Note 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. + +?> `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. ## Quick Tap Term From 478d8a549ce19fecc12dfec806ca1efe0938c399 Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Tue, 13 Dec 2022 01:46:04 +0100 Subject: [PATCH 16/16] Add changelog for #15741 --- docs/ChangeLog/20230226/PR15741.md | 43 ++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 docs/ChangeLog/20230226/PR15741.md diff --git a/docs/ChangeLog/20230226/PR15741.md b/docs/ChangeLog/20230226/PR15741.md new file mode 100644 index 000000000000..385816d65ba0 --- /dev/null +++ b/docs/ChangeLog/20230226/PR15741.md @@ -0,0 +1,43 @@ +`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. + +In place of the now removed `IGNORE_MOD_TAP_INTERRUPT_PER_KEY`, one must use the pre-existing `HOLD_ON_OTHER_KEY_PRESS` option. + +In 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. + +To 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. + +An old way to do this would be via the following code: + +```c +bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + case LCTL_T(KC_A): + return true; + default: + return false; + } +} +``` + +The correct way to update this code without accidentally changing how the layer-taps work would be the following: + +```c +bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { + switch(keycode) { + // Capture all mod-tap keycodes. + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + if (keycode == LCTL_T(KC_A)) { + // Disable HOLD_ON_OTHER_KEY_PRESS for LCTL_T(KC_A) + // aka enable IGNORE_MOD_TAP_INTERRUPT for LCTL_T(KC_A). + return false; + } else { + // Enable HOLD_ON_OTHER_KEY_PRESS for every other mod-tap keycode. + return true; + } + default: + return false; + } +} +``` + +For 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).