Skip to content

Commit

Permalink
New feature: TAP_TERM_KEYS_ENABLE
Browse files Browse the repository at this point in the history
3 new quantum keys to configure the tapping term on the fly.
  • Loading branch information
precondition committed Mar 19, 2021
1 parent 6f7466b commit 4a7fe01
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 6 deletions.
7 changes: 6 additions & 1 deletion common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -685,4 +685,9 @@ ifeq ($(strip $(USBPD_ENABLE)), yes)
# Board designers can add their own driver to $(SRC)
endif
endif
endif
endif

ifeq ($(strip $(TAP_TERM_KEYS_ENABLE)), yes)
SRC += $(QUANTUM_DIR)/process_keycode/process_tap_term_keys.c
OPT_DEFS += -DTAP_TERM_KEYS_ENABLE
endif
2 changes: 2 additions & 0 deletions docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ Use these to enable or disable building certain features. The more you have enab
* Forces the keyboard to wait for a USB connection to be established before it starts up
* `NO_USB_STARTUP_CHECK`
* Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master.
* `TAP_TERM_KEYS_ENABLE`
* Allows to configure the global tapping term on the fly.
## USB Endpoint Limitations
Expand Down
10 changes: 10 additions & 0 deletions docs/keycodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,16 @@ See also: [Mod-Tap](mod_tap.md)
|`MEH_T(kc)` | |Left Control, Shift and Alt when held, `kc` when tapped |
|`HYPR_T(kc)` |`ALL_T(kc)` |Left Control, Shift, Alt and GUI when held, `kc` when tapped - more info [here](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)|

## Tapping Term Keys :id=tapping-term-keys

See also: [Tapping Term Keys](tap_hold#tapping-term-keys)

| Key | Description |
|-----------|-----------------------------------------------------------------------|
| `KC_TAPP` | "Tapping Term Print": Types the current tapping term, in milliseconds |
| `KC_TAPU` | "Tapping Term Up": Increases the current tapping term by 5ms |
| `KC_TAPD` | "Tapping Term Down": Decreases the current tapping term by 5ms |

## RGB Lighting :id=rgb-lighting

See also: [RGB Lighting](feature_rgblight.md)
Expand Down
25 changes: 24 additions & 1 deletion docs/tap_hold.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ These options let you modify the behavior of the Tap-Hold keys.

## Tapping Term

The crux of all of the following features is the tapping term setting. This determines what is a tap and what is a hold. And the exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key.
The crux of all of the following features is the tapping term setting. This determines what is a tap and what is a hold. The exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key.

?> `TAP_TERM_KEYS_ENABLE` enables three special keys that can help you quickly find a comfortable tapping term for you. See "Tapping Term Keys" for more details.

You can set the global time for this by adding the following setting to your `config.h`:

Expand Down Expand Up @@ -36,6 +38,27 @@ uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
}
```
### Tapping Term Keys :id=tapping-term-keys
Not to be confused with `TAPPING_TERM_PER_KEY`, `TAP_TERM_KEYS_ENABLE` is a feature you can enable in `rules.mk` that lets you use three special keys in your keymap to configure the tapping term on the fly.
| Key | Description |
|-----------|-----------------------------------------------------------------------|
| `KC_TAPP` | "Tapping Term Print": Types the current tapping term, in milliseconds |
| `KC_TAPU` | "Tapping Term Up": Increases the current tapping term by 5ms |
| `KC_TAPD` | "Tapping Term Down": Decreases the current tapping term by 5ms |
Set the tapping term as usual with `#define TAPPING_TERM <value>` in `config.h` and add `TAP_TERM_KEYS_ENABLE = yes` in `rules.mk`. Then, place the above three keys somewhere in your keymap and flash the new firmware onto your board.
Now, you can try using your dual-role keys, such as layer-taps and mod-taps, and use `KC_TAPD` and `KC_TAPU` to adjust the tapping term immediately. If you find that you frequently trigger the modifier of your mod-tap(s) by accident for example, that's a sign that your tapping term may be too low so, tap `KC_TAPU` a few times to increase the tapping term until that no longer happens. On the flip side, if you get superfluous characters when you actually intended to momentarily activate a layer, tap `KC_TAPD` to lower the tapping term. Do note that these keys affect the *global* tapping term, you cannot change the tapping term of a specific key on the fly.
Once you're satisfied with the current tapping term value, open `config.h` and replace whatever value you first wrote for the tapping term by the output of the `KC_TAPP` key.
It's important to update `TAPPING_TERM` with the new value because the adjustments made using `KC_TAPU` and `KC_TAPD` are not persistent.
In order for this feature to be effective if you use per-key tapping terms, you need to make a few changes to the syntax of the `get_tapping_term` function. All you need to do is replace every occurrence of `TAPPING_TERM` in the `get_tapping_term` function by lowercase `tapping_term`.
The reason being that `TAPPING_TERM` is a macro that expands to a constant integer and thus cannot be changed at runtime whereas `tapping_term` is a variable whose value can be changed at runtime. If you want, you can temporarily enable `TAP_TERM_KEYS_ENABLE` to find a suitable tapping term value and then disable that feature and revert back to using the classic syntax for per-key tapping term settings.
## Permissive Hold
Expand Down
1 change: 1 addition & 0 deletions docs/understanding_qmk.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ The `process_record()` function itself is deceptively simple, but hidden within
* [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115)
* [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77)
* [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94)
* `bool process_tap_term_keys(uint16_t keycode, keyrecord_t *record)`
* [`bool process_terminal(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_terminal.c#L264)
* [Identify and process Quantum-specific keycodes](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291)

Expand Down
45 changes: 45 additions & 0 deletions quantum/process_keycode/process_tap_term_keys.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* Copyright 2020 Vladislav Kucheriavykh
*
* 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 <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include "process_tap_term_keys.h"

void tapping_term_report(void) {
char display[8];

snprintf(display, 8, "%d", tapping_term);

send_string((const char *)display);
}

bool process_tap_term_keys(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
switch (keycode) {
case KC_TAPP:
tapping_term_report();
return true;

case KC_TAPU:
tapping_term += 5;
return true;

case KC_TAPD:
tapping_term -= 5;
return true;
}
}
return true;
}
22 changes: 22 additions & 0 deletions quantum/process_keycode/process_tap_term_keys.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Copyright 2020 Vladislav Kucheriavykh
*
* 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "quantum.h"
#include "action_tapping.h"

bool process_tap_term_keys(uint16_t keycode, keyrecord_t *record);
3 changes: 3 additions & 0 deletions quantum/quantum.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ bool process_record_quantum(keyrecord_t *record) {
#endif
#ifdef JOYSTICK_ENABLE
process_joystick(keycode, record) &&
#endif
#ifdef TAP_TERM_KEYS_ENABLE
process_tap_term_keys(keycode, record) &&
#endif
true)) {
return false;
Expand Down
3 changes: 3 additions & 0 deletions quantum/quantum.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ extern layer_state_t layer_state;
#ifdef WPM_ENABLE
# include "wpm.h"
#endif
#ifdef TAP_TERM_KEYS_ENABLE
# include "process_tap_term_keys.h"
#endif

#ifdef USBPD_ENABLE
# include "usbpd.h"
Expand Down
7 changes: 7 additions & 0 deletions quantum/quantum_keycodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,13 @@ enum quantum_keycodes {
ONESHOT_DISABLE,
ONESHOT_TOGGLE,

// Tapping term setup
#ifdef TAP_TERM_KEYS_ENABLE
KC_TAPP,
KC_TAPU,
KC_TAPD,
#endif

// always leave at the end
SAFE_RANGE
};
Expand Down
3 changes: 2 additions & 1 deletion show_options.mk
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ OTHER_OPTION_NAMES = \
RGB_MATRIX_KEYPRESSES \
LED_MIRRORED \
RGBLIGHT_FULL_POWER \
LTO_ENABLE
LTO_ENABLE \
TAP_TERM_KEYS_ENABLE

define NAME_ECHO
@echo " $1 = $($1) # $(origin $1)"
Expand Down
8 changes: 5 additions & 3 deletions tmk_core/common/action_tapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
# define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))

__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return TAPPING_TERM; }
uint16_t tapping_term = TAPPING_TERM;

__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { return tapping_term; }

# ifdef TAPPING_TERM_PER_KEY
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event, false), &tapping_key))
# else
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < tapping_term)
# endif

# ifdef TAPPING_FORCE_HOLD_PER_KEY
Expand Down Expand Up @@ -119,7 +121,7 @@ bool process_tapping(keyrecord_t *keyp) {
* This can register the key before settlement of tapping,
* useful for long TAPPING_TERM but may prevent fast typing.
*/
# if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
# if defined(TAPPING_TERM_PER_KEY) || (tapping_term >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
else if (
# ifdef TAPPING_TERM_PER_KEY
(get_tapping_term(get_event_keycode(tapping_key.event, false), keyp) >= 500) &&
Expand Down
5 changes: 5 additions & 0 deletions tmk_core/common/action_tapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NO_ACTION_TAPPING
uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
void action_tapping_process(keyrecord_t record);
#endif

uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record);
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record);
bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record);
bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record);
bool get_retro_tapping(uint16_t keycode, keyrecord_t *record);

#ifdef TAP_TERM_KEYS_ENABLE
extern uint16_t tapping_term;
#endif

0 comments on commit 4a7fe01

Please sign in to comment.