Skip to content

Commit

Permalink
Document examples on intercepting Mod-Tap (qmk#14502)
Browse files Browse the repository at this point in the history
Co-authored-by: Ryan <[email protected]>
Co-authored-by: Dasky <[email protected]>
Co-authored-by: filterpaper <filterpaper@localhost>
  • Loading branch information
4 people authored and 0xcharly committed Oct 25, 2021
1 parent 47b52db commit 8ab5f51
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions docs/mod_tap.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,80 @@ You may also run into issues when using Remote Desktop Connection on Windows. Be
To fix this, open Remote Desktop Connection, click on "Show Options", open the the "Local Resources" tab, and in the keyboard section, change the drop down to "On this Computer". This will fix the issue, and allow the characters to work correctly.
It can also be mitigated by increasing [`TAP_CODE_DELAY`](config_options.md#behaviors-that-can-be-configured).
## Intercepting Mod-Taps
### Changing tap function
The basic keycode limitation with Mod-Tap can be worked around by intercepting it in `process_record_user`. For example, shifted keycode `KC_DQUO` cannot be used with `MT()` because it is a 16-bit keycode alias of `LSFT(KC_QUOT)`. Modifiers on `KC_DQUO` will be masked by `MT()`. But the following custom code can be used to intercept the "tap" function to manually send `KC_DQUO`:
```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case LCTL_T(KC_DQUO):
if (record->tap.count && record->event.pressed) {
tap_code16(KC_DQUO); // Send KC_DQUO on tap
return false; // Return false to ignore further processing of key
}
break;
}
return true;
}
```

### Changing hold function

Likewise, the same custom code can also be used to intercept the hold function to send custom user key code. The following example uses `LT(0, kc)` (layer-tap key with no practical use because layer 0 is always active) to add cut, copy and paste function to X,C and V keys when they are held down:

```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case LT(0,KC_X):
if (record->tap.count && record->event.pressed) {
return true; // Return true for normal processing of tap keycode
} else if (record->event.pressed) {
tap_code16(C(KC_X)); // Intercept hold function to send Ctrl-X
}
return false;
case LT(0,KC_C):
if (record->tap.count && record->event.pressed) {
return true; // Return true for normal processing of tap keycode
} else if (record->event.pressed) {
tap_code16(C(KC_C)); // Intercept hold function to send Ctrl-C
}
return false;
case LT(0,KC_V):
if (record->tap.count && record->event.pressed) {
return true; // Return true for normal processing of tap keycode
} else if (record->event.pressed) {
tap_code16(C(KC_V)); // Intercept hold function to send Ctrl-V
}
return false;
}
return true;
}
```
Enabling `IGNORE_MOD_TAP_INTERRUPT` is recommended when using Mod-Tap on alphanumeric keys to avoid hold function taking precendence when the next key is pressed quickly. See [Ignore Mod Tap Interrupt](tap_hold.md#ignore-mod-tap-interrupt) for more details.
### Changing both tap and hold
This last example implements custom tap and hold function with `LT(0,KC_NO)` to create a single copy-on-tap, paste-on-hold key:
```c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case LT(0,KC_NO):
if (record->tap.count && record->event.pressed) {
tap_code16(C(KC_C)); // Intercept tap function to send Ctrl-C
} else if (record->event.pressed) {
tap_code16(C(KC_V)); // Intercept hold function to send Ctrl-V
}
return false;
}
return true;
}
```

## Other Resources

See the [Tap-Hold Configuration Options](tap_hold.md) for additional flags that tweak Mod-Tap behavior.

0 comments on commit 8ab5f51

Please sign in to comment.