An Optimization of QMK Mod-tap (Layer-tap) for Fast Typists

· Tech

QMK is the most powerful and popular keyboard firmware in custimzed keyboard community. You can write C code to set Macros to any key, which makes it highly playable.

Apart from programming, QMK has quite a lot of pre-set quantum keys. A big category of them is mod-tap keys. That means, if you tap the key, it prints a normal output, such a letter, digit or any other key on the keyboard; if you hold it, it works like a mod key, such as control, alt, shift or win/command/super. That’s particually useful for mini keyboards (40% layout, for example), where keys are highly reused.

However, the performance of mod-tap may not meet the need of fast typing. For example, if the mod-tap key is Control(A), and you press Control(A) and C fast, you will see “AC” on the screen, not the copy action (Control + C). The same thing happens on layer-tap key.

I haven’t read the source code of mod-tap keys, but with programming, we can avoid this issue completely.

 1 bool lctl_other_key_pressed = false;
 2 uint16_t lctl_hold_timer = 0;
 3 
 4 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 5   switch (keycode) {
 6     // Left control. Can be changed to any modifier, or MO({LAYER_NUM}) for layer-taps.
 7     case KC_LCTL:
 8       if (record->event.pressed) {
 9         // Records press time.
10 		lctl_hold_timer = timer_read();
11         // At the beginning, no other key is pressed.
12 		lctl_other_key_pressed = false;
13       } else if (timer_elapsed(lctl_timer) < 500 && !space_other_key_pressed) {
14         // Sends out 'A' if the key is held for less than 0.5s and no other key was pressed during the period. 
15 		tap_code(KC_A);
16 	  }
17       break;
18 	default:
19       // Another key is pressed.
20       lctl_other_key_pressed = true;
21   }
22   return true;
23 };

In this piece of code, we set the keycode of the mod-tap key to a normal Control key. It ensures it works perfectly as a mod key. Then we add a feature to this key when it is released - we sends a normal letter, which should be the “tap” part of mod-tap. Tap is only triggerred when the key was held shortly and no other key interrupted. This way, even fast typists can enjoy mod-tap keys happily.

I’m not sure the current behavior of mod-tap is expected by QMK developer, but I will do some investigation on it and see if I can make the solution general to the default mod-tap implementation.