Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
Import manna-harbour/bilateral-combinations.
Browse files Browse the repository at this point in the history
manna-harbour#29

Perhaps this will tame my home row mods?
  • Loading branch information
manna-harbour authored and matthewtodd committed Jun 2, 2024
1 parent 94d7d7e commit 4e0b573
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
24 changes: 24 additions & 0 deletions docs/tap_hold.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,30 @@ uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) {
?> If `QUICK_TAP_TERM` is set higher than `TAPPING_TERM`, it will default to `TAPPING_TERM`.
## Bilateral Combinations
The last mod-tap hold will be converted to the corresponding mod-tap tap if another key on the same hand is tapped during the hold, unless a key on the other hand is tapped first.
This option can be used to prevent accidental modifier combinations with mod-tap, in particular those caused by rollover on home row mods. As only the last mod-tap hold is affected, it should be enabled after adjusting settings and typing style so that accidental mods happen only occasionally, e.g. with a long enough tapping term, ignore mod tap interrupt, and deliberately brief keypresses.
To enable bilateral combinations, add the following to your `config.h`:
```c
#define BILATERAL_COMBINATIONS
```

If `BILATERAL_COMBINATIONS` is defined to a value, hold times greater than that value will permit same hand combinations. For example:

```c
#define BILATERAL_COMBINATIONS 500
```
To monitor activations in the background, enable debugging, enable the console, enable terminal bell, add `#define DEBUG_ACTION` to `config.h`, and use something like the following shell command line:
```sh
hid_listen | sed -u 's/BILATERAL_COMBINATIONS: change/&\a/g'
```

## Retro Tapping

To enable `retro tapping`, add the following to your `config.h`:
Expand Down
92 changes: 92 additions & 0 deletions quantum/action.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyreco
}
#endif

#if (BILATERAL_COMBINATIONS + 0)
# include "quantum.h"
#endif

#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { return false; }
#endif

#ifdef RETRO_TAPPING_PER_KEY
__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) {
return false;
Expand Down Expand Up @@ -358,6 +366,68 @@ void register_mouse(uint8_t mouse_keycode, bool pressed) {
#endif
}

#ifdef BILATERAL_COMBINATIONS
static struct {
bool active;
uint8_t code;
uint8_t tap;
uint8_t mods;
bool left;
# if (BILATERAL_COMBINATIONS + 0)
uint16_t time;
# endif
} bilateral_combinations = { false };

static bool bilateral_combinations_left(keypos_t key) {
# ifdef SPLIT_KEYBOARD
return key.row < MATRIX_ROWS / 2;
# else
if (MATRIX_COLS > MATRIX_ROWS) {
return key.col < MATRIX_COLS / 2;
} else {
return key.row < MATRIX_ROWS / 2;
}
# endif
}

static void bilateral_combinations_hold(action_t action, keyevent_t event) {
dprint("BILATERAL_COMBINATIONS: hold\n");
bilateral_combinations.active = true;
bilateral_combinations.code = action.key.code;
bilateral_combinations.tap = action.layer_tap.code;
bilateral_combinations.mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4;
bilateral_combinations.left = bilateral_combinations_left(event.key);
# if (BILATERAL_COMBINATIONS + 0)
bilateral_combinations.time = event.time;
# endif
}

static void bilateral_combinations_release(uint8_t code) {
dprint("BILATERAL_COMBINATIONS: release\n");
if (bilateral_combinations.active && (code == bilateral_combinations.code)) {
bilateral_combinations.active = false;
}
}

static void bilateral_combinations_tap(keyevent_t event) {
dprint("BILATERAL_COMBINATIONS: tap\n");
if (bilateral_combinations.active) {
if (bilateral_combinations_left(event.key) == bilateral_combinations.left) {
# if (BILATERAL_COMBINATIONS + 0)
if (TIMER_DIFF_16(event.time, bilateral_combinations.time) > BILATERAL_COMBINATIONS) {
dprint("BILATERAL_COMBINATIONS: timeout\n");
return;
}
# endif
dprint("BILATERAL_COMBINATIONS: change\n");
unregister_mods(bilateral_combinations.mods);
tap_code(bilateral_combinations.tap);
}
bilateral_combinations.active = false;
}
}
#endif

/** \brief Take an action and processes it.
*
* FIXME: Needs documentation.
Expand Down Expand Up @@ -403,6 +473,12 @@ void process_action(keyrecord_t *record, action_t action) {
}
send_keyboard_report();
}
#ifdef BILATERAL_COMBINATIONS
if (!(IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO)) {
// regular keycode tap during mod-tap hold
bilateral_combinations_tap(event);
}
#endif
register_code(action.key.code);
} else {
unregister_code(action.key.code);
Expand Down Expand Up @@ -510,12 +586,20 @@ void process_action(keyrecord_t *record, action_t action) {
} else
# endif
{
# ifdef BILATERAL_COMBINATIONS
// mod-tap tap
bilateral_combinations_tap(event);
# endif
ac_dprintf("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
} else {
ac_dprintf("MODS_TAP: No tap: add_mods\n");
register_mods(mods);
# ifdef BILATERAL_COMBINATIONS
// mod-tap hold
bilateral_combinations_hold(action, event);
# endif
}
} else {
if (tap_count > 0) {
Expand All @@ -536,6 +620,10 @@ void process_action(keyrecord_t *record, action_t action) {
}
# endif
unregister_mods(mods);
# ifdef BILATERAL_COMBINATIONS
// mod-tap release
bilateral_combinations_release(action.key.code);
# endif
}
}
break;
Expand Down Expand Up @@ -693,6 +781,10 @@ void process_action(keyrecord_t *record, action_t action) {
# ifndef NO_ACTION_TAPPING /* tap key */
if (event.pressed) {
if (tap_count > 0) {
# ifdef BILATERAL_COMBINATIONS
// layer-tap tap
bilateral_combinations_tap(event);
# endif
ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n");
register_code(action.layer_tap.code);
} else {
Expand Down

0 comments on commit 4e0b573

Please sign in to comment.