Open amarakon opened 3 months ago
It is a non-trivial request to implement this into QMK's core action tapping code. But you can easily do so in your user keymap code using the pre_process_record_user
function with something like:
// Decision macro for mod-tap keys to override
#define IS_HOMEROW_MOD_TAP(kc) ( \
IS_QK_MOD_TAP(kc) && \
QK_MOD_TAP_GET_TAP_KEYCODE(kc) >= KC_A && \
QK_MOD_TAP_GET_TAP_KEYCODE(kc) <= KC_Z )
// Decision macro for preceding trigger key and typing interval
#define IS_TYPING(k) ( \
((uint8_t)(k) <= KC_Z || (uint8_t)(k) == KC_SPC) && \
(last_input_activity_elapsed() < QUICK_TAP_TERM) )
bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) {
static bool is_pressed[UINT8_MAX];
static uint16_t prev_keycode;
const uint16_t tap_keycode = QK_MOD_TAP_GET_TAP_KEYCODE(keycode);
if (record->event.pressed) {
// Press the tap keycode if the tap-hold key follows the previous key swiftly
if (IS_HOMEROW_MOD_TAP(keycode) && IS_TYPING(prev_keycode)) {
is_pressed[tap_keycode] = true;
record->keycode = tap_keycode;
}
// Cache the keycode for subsequent tap decision
prev_keycode = keycode;
}
// Release the tap keycode if pressed
else if (is_pressed[tap_keycode]) {
is_pressed[tap_keycode] = false;
record->keycode = tap_keycode;
}
return true;
}
The preprocessor macros can be adjusted to your preference. Unlike ZMK, you can choose the preceding keycode that will trigger the feature. It uses the keycode
container in the keyrecord_t
. If you don't have COMBO_ENABLE
, enable REPEAT_KEY_ENABLE
.
First, thanks a lot for the code. I tested it and it works for home row mods. However, I also like to use my spacebar as a mod-tap key. This is how I set up my mod-taps:
I changed the IS_HOMEROW_MOD_TAP
macro to the following:
#define IS_HOMEROW_MOD_TAP(kc) ( \
IS_QK_MOD_TAP(kc) && \
((QK_MOD_TAP_GET_TAP_KEYCODE(kc) >= KC_A && \
QK_MOD_TAP_GET_TAP_KEYCODE(kc) <= KC_Z) || \
QK_MOD_TAP_GET_TAP_KEYCODE(kc) == KC_SPC))
This makes it so that KC_SPC
can also be considered a mod-tap key. It works for the most part, but sometimes it won't work and there'll be an unexpected delay when pressing space during a typing streak, as if I was using standard mod-taps.
I attached a video. I used keyd to monitor my keystrokes. Notice how there's a delay when typing the space right before the word The
. Also notice how the difference in time between space down
and f down
is one millisecond. This probably means that the space is delayed until the F key is pressed. By the way, I'm using the Colemak layout so I press the F key to type the letter T.
https://github.com/user-attachments/assets/96b35bea-0999-4a32-a3da-edf997f1311e
Edit: I forgot to mention that my QUICK_TAP_TERM
is defined as 200
.
I just realized that the reason I was experiencing that issue was because I also had a key-remapping daemon running which does the same thing. I was using it as a temporary solution for this problem and forgot to turn it off when I re-flashed my firmware. I'll still keep this issue open because I'd like to see this get implemented as a core QMK feature.
Feature Request Type
Description
ZMK has the configuration option require-prior-idle-ms for tap-hold keys. It effectively makes all tap-hold keys resolve as tapped when typing quickly. Aside from decreasing the possibility of accidentally triggering modifiers, it has the added benefit of eliminating the delay when typing quickly.
I did find a pull request on Manna Harbour's fork of the QMK firmware, but it's from two years ago and I can't merge it into my clone of this repository without a lot of merge conflicts. There's also the achordion userspace library, but it can't get rid of the delay; it can only prevent modifiers from being triggered.