Add per-key IGNORE_MOD_TAP_INTERRUPT feature (#7838)

* Implement IGNORE_MOD_TAP_INTERRUPT_PER_KEY

- Add configurable option IGNORE_MOD_TAP_INTERRUPT_PER_KEY
- Add function get_ignore_mod_tap_interrupt iff the option is enabled

Unless IGNORE_MOD_TAP_INTERRUPT_PER_KEY is defined, this patch does not affect the resulting binary.

* Add documentation for IGNORE_MOD_TAP_INTERRUPT_PER_KEY
This commit is contained in:
zk-phi 2020-01-10 16:48:06 +09:00 committed by ridingqwerty
parent e34af631c2
commit 7f388b6553
4 changed files with 44 additions and 7 deletions

View file

@ -143,6 +143,8 @@ If you define these options you will enable the associated feature, which may in
* `#define IGNORE_MOD_TAP_INTERRUPT` * `#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. * 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 [Mod tap interrupt](feature_advanced_keycodes.md#ignore-mod-tap-interrupt) for details * See [Mod tap interrupt](feature_advanced_keycodes.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 TAPPING_FORCE_HOLD` * `#define TAPPING_FORCE_HOLD`
* makes it possible to use a dual role key as modifier shortly after having been tapped * makes it possible to use a dual role key as modifier shortly after having been tapped
* See [Hold after tap](feature_advanced_keycodes.md#tapping-force-hold) * See [Hold after tap](feature_advanced_keycodes.md#tapping-force-hold)

View file

@ -489,14 +489,24 @@ The `val` is the value of the data that you want to write to EEPROM. And the `e
# Custom Tapping Term # Custom Tapping Term
By default, the tapping term is defined globally, and is not configurable by key. For most users, this is perfectly fine. But in come cases, dual function keys would be greatly improved by different timeouts than `LT` keys, or because some keys may be easier to hold than others. Instead of using custom key codes for each, this allows for per key configurable `TAPPING_TERM`. By default, the tapping term and related options (such as `IGNORE_MOD_TAP_INTERRUPT`) are defined globally, and are not configurable by key. For most users, this is perfectly fine. But in some cases, dual function keys would be greatly improved by different timeout behaviors than `LT` keys, or because some keys may be easier to hold than others. Instead of using custom key codes for each, this allows for per key configurable timeout behaviors.
To enable this functionality, you need to add `#define TAPPING_TERM_PER_KEY` to your `config.h`, first. There are two configurable options to control per-key timeout behaviors:
- `TAPPING_TERM_PER_KEY`
- `IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
You need to add `#define` lines to your `config.h` for each feature you want.
```
#define TAPPING_TERM_PER_KEY
#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY
```
## Example `get_tapping_term` Implementation ## Example `get_tapping_term` Implementation
To change the `TAPPING TERM` based on the keycode, you'd want to add something like the following to your `keymap.c` file: To change the `TAPPING_TERM` based on the keycode, you'd want to add something like the following to your `keymap.c` file:
```c ```c
uint16_t get_tapping_term(uint16_t keycode) { uint16_t get_tapping_term(uint16_t keycode) {
@ -511,6 +521,21 @@ uint16_t get_tapping_term(uint16_t keycode) {
} }
``` ```
### `get_tapping_term` Function Documentation ## Example `get_ignore_mod_tap_interrupt` Implementation
Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum or keyboard level function. Only a user level function is useful here, so no need to mark it as such. To change the `IGNORE_MOD_TAP_INTERRUPT` value based on the keycode, you'd want to add something like the following to your `keymap.c` file:
```c
bool get_ignore_mod_tap_interrupt(uint16_t keycode) {
switch (keycode) {
case SFT_T(KC_SPC):
return true;
default:
return false;
}
}
```
## `get_tapping_term` / `get_ignore_mod_tap_interrupt` Function Documentation
Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum or keyboard level function. Only user level functions are useful here, so no need to mark them as such.

View file

@ -148,6 +148,8 @@ QMK での全ての利用可能な設定にはデフォルトがあります。
* `#define IGNORE_MOD_TAP_INTERRUPT` * `#define IGNORE_MOD_TAP_INTERRUPT`
* 両方のキーに `TAPPING_TERM` を適用することで、ホールド時に他のキーに変換するキーを使ってローリングコンボ (zx) をすることができるようにします * 両方のキーに `TAPPING_TERM` を適用することで、ホールド時に他のキーに変換するキーを使ってローリングコンボ (zx) をすることができるようにします
* 詳細は [Mod tap interrupt](ja/feature_advanced_keycodes.md#ignore-mod-tap-interrupt) を見てください * 詳細は [Mod tap interrupt](ja/feature_advanced_keycodes.md#ignore-mod-tap-interrupt) を見てください
* `#define IGNORE_MOD_TAP_INTERRUPT_PER_KEY`
* キーごとの `IGNORE_MOD_TAP_INTERRUPT` 設定の処理を有効にします
* `#define TAPPING_FORCE_HOLD` * `#define TAPPING_FORCE_HOLD`
* タップされた直後に、デュアルロールキーを修飾子として使用できるようにします * タップされた直後に、デュアルロールキーを修飾子として使用できるようにします
* [Hold after tap](ja/feature_advanced_keycodes.md#tapping-force-hold)を見てください * [Hold after tap](ja/feature_advanced_keycodes.md#tapping-force-hold)を見てください

View file

@ -47,6 +47,10 @@ int retro_tapping_counter = 0;
# include <fauxclicky.h> # include <fauxclicky.h>
#endif #endif
#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
__attribute__ ((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode) { return false; }
#endif
#ifndef TAP_CODE_DELAY #ifndef TAP_CODE_DELAY
# define TAP_CODE_DELAY 0 # define TAP_CODE_DELAY 0
#endif #endif
@ -308,8 +312,12 @@ void process_action(keyrecord_t *record, action_t action) {
default: default:
if (event.pressed) { if (event.pressed) {
if (tap_count > 0) { if (tap_count > 0) {
# ifndef IGNORE_MOD_TAP_INTERRUPT # if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
if (record->tap.interrupted) { if (
# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
!get_ignore_mod_tap_interrupt(get_event_keycode(record->event)) &&
# endif
record->tap.interrupted) {
dprint("mods_tap: tap: cancel: add_mods\n"); dprint("mods_tap: tap: cancel: add_mods\n");
// ad hoc: set 0 to cancel tap // ad hoc: set 0 to cancel tap
record->tap.count = 0; record->tap.count = 0;