Browse Source

Implement HOLD_TAP.

This changes the behavior of tap and hold so that the hold action
happens immediately, and if we later decide that we actually have a tap,
we release the hold action just before sending the tap.

This is very helpful when the hold action changes the behavior of some
external device, such as altering the behavior of mouse button clicks.
pull/23351/head
Elizabeth Loss-Cutler-Hull 1 month ago
parent
commit
dadbdc91d6
4 changed files with 26 additions and 0 deletions
  1. +3
    -0
      docs/config_options.md
  2. +8
    -0
      docs/tap_hold.md
  3. +8
    -0
      quantum/action.c
  4. +7
    -0
      quantum/action_tapping.c

+ 3
- 0
docs/config_options.md View File

@ -173,6 +173,9 @@ If you define these options you will enable the associated feature, which may in
* 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 HOLD_TAP`
* alters the behavior of tap and hold so that the mod hold is immediate.
* See "[hold tap](tap_hold.md#hold-tap)" for details
* `#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.


+ 8
- 0
docs/tap_hold.md View File

@ -4,6 +4,14 @@ While Tap-Hold options are fantastic, they are not without their issues. We hav
These options let you modify the behavior of the Tap-Hold keys.
## Hold Tap :id=hold-tap
By default, Tap-Hold only sends the record indicating the modifier hold after the logic has determined that we do not have a tap.
?> `HOLD_TAP` changes this behavior, so that the modifier is set immediately, and if we later decide that we have a tap, we release the modifier and then send the tap records.
This is very helpful when the modifier alters the behavior of some other device, such as what mouse clicks do.
## 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. The exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key.


+ 8
- 0
quantum/action.c View File

@ -510,6 +510,11 @@ void process_action(keyrecord_t *record, action_t action) {
} else
# endif
{
# ifdef HOLD_TAP
ac_dprintf("HOLD_TOP: Unregister mods.\n");
unregister_mods(mods);
# endif
ac_dprintf("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
@ -694,6 +699,9 @@ void process_action(keyrecord_t *record, action_t action) {
if (event.pressed) {
if (tap_count > 0) {
ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n");
# ifdef HOLD_TAP
layer_off(action.layer_tap.val);
# endif
register_code(action.layer_tap.code);
} else {
ac_dprintf("KEYMAP_TAP_KEY: No tap: On on press\n");


+ 7
- 0
quantum/action_tapping.c View File

@ -179,6 +179,11 @@ bool process_tapping(keyrecord_t *keyp) {
process_record_tap_hint(&tapping_key);
waiting_buffer_scan_tap();
debug_tapping_key();
# ifdef HOLD_TAP
// Hold and tap, process the key immediately.
process_record(keyp);
# endif
} else {
// the current key is just a regular key, pass it on for regular
// processing
@ -336,7 +341,9 @@ bool process_tapping(keyrecord_t *keyp) {
ac_dprintf("Tapping: End. Timeout. Not tap(0): ");
debug_event(event);
ac_dprintf("\n");
# ifndef HOLD_TAP
process_record(&tapping_key);
# endif
tapping_key = (keyrecord_t){0};
debug_tapping_key();
return false;


Loading…
Cancel
Save