diff options
| author | Dusty Pomerleau <dustypomerleau@users.noreply.github.com> | 2019-03-08 07:30:02 +1100 |
|---|---|---|
| committer | Drashna Jaelre <drashna@live.com> | 2019-03-07 12:30:02 -0800 |
| commit | 6d4f6f3f4965e3e71d878c36da71b745cc18e345 (patch) | |
| tree | 4ee35d3c4df8369adf07863fbf4d1936c4452741 /docs/feature_tap_dance.md | |
| parent | ba11a1c8072fd5d2f2d2914e76e9416be9ca1e11 (diff) | |
| download | qmk_firmware-6d4f6f3f4965e3e71d878c36da71b745cc18e345.tar.gz qmk_firmware-6d4f6f3f4965e3e71d878c36da71b745cc18e345.zip | |
[Docs] Add Tap Dance example to the docs (#5326)
* add a tapdance example for creating advanced mod-tap and layer-tap keys
* add optional curly braces to match QMK conventions
* change example to use `register_code16()` and tapdance keycodes more closely matching QMK variants
Diffstat (limited to 'docs/feature_tap_dance.md')
| -rw-r--r-- | docs/feature_tap_dance.md | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/docs/feature_tap_dance.md b/docs/feature_tap_dance.md index f2f274944..b5e5218b0 100644 --- a/docs/feature_tap_dance.md +++ b/docs/feature_tap_dance.md | |||
| @@ -314,3 +314,86 @@ qk_tap_dance_action_t tap_dance_actions[] = { | |||
| 314 | And then simply use `TD(X_CTL)` anywhere in your keymap. | 314 | And then simply use `TD(X_CTL)` anywhere in your keymap. |
| 315 | 315 | ||
| 316 | If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace. | 316 | If you want to implement this in your userspace, then you may want to check out how [DanielGGordon](https://github.com/qmk/qmk_firmware/tree/master/users/gordon) has implemented this in their userspace. |
| 317 | |||
| 318 | ### Example 5: Using tap dance for advanced mod-tap and layer-tap keys | ||
| 319 | |||
| 320 | Tap dance can be used to emulate `MT()` and `LT()` behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require `Shift`, such as parentheses or curly braces—or other modified keycodes, such as `Control + X`. | ||
| 321 | |||
| 322 | Below your layers and custom keycodes, add the following: | ||
| 323 | |||
| 324 | ```c | ||
| 325 | // tapdance keycodes | ||
| 326 | enum td_keycodes { | ||
| 327 | ALT_LP // Our example key: `LALT` when held, `(` when tapped. Add additional keycodes for each tapdance. | ||
| 328 | }; | ||
| 329 | |||
| 330 | // define a type containing as many tapdance states as you need | ||
| 331 | typedef enum { | ||
| 332 | SINGLE_TAP, | ||
| 333 | SINGLE_HOLD, | ||
| 334 | DOUBLE_SINGLE_TAP | ||
| 335 | } td_state_t; | ||
| 336 | |||
| 337 | // create a global instance of the tapdance state type | ||
| 338 | static td_state_t td_state; | ||
| 339 | |||
| 340 | // declare your tapdance functions: | ||
| 341 | |||
| 342 | // function to determine the current tapdance state | ||
| 343 | int cur_dance (qk_tap_dance_state_t *state); | ||
| 344 | |||
| 345 | // `finished` and `reset` functions for each tapdance keycode | ||
| 346 | void altlp_finished (qk_tap_dance_state_t *state, void *user_data); | ||
| 347 | void altlp_reset (qk_tap_dance_state_t *state, void *user_data); | ||
| 348 | ``` | ||
| 349 | |||
| 350 | Below your `LAYOUT`, define each of the tapdance functions: | ||
| 351 | |||
| 352 | ```c | ||
| 353 | // determine the tapdance state to return | ||
| 354 | int cur_dance (qk_tap_dance_state_t *state) { | ||
| 355 | if (state->count == 1) { | ||
| 356 | if (state->interrupted || !state->pressed) { return SINGLE_TAP; } | ||
| 357 | else { return SINGLE_HOLD; } | ||
| 358 | } | ||
| 359 | if (state->count == 2) { return DOUBLE_SINGLE_TAP; } | ||
| 360 | else { return 3; } // any number higher than the maximum state value you return above | ||
| 361 | } | ||
| 362 | |||
| 363 | // handle the possible states for each tapdance keycode you define: | ||
| 364 | |||
| 365 | void altlp_finished (qk_tap_dance_state_t *state, void *user_data) { | ||
| 366 | td_state = cur_dance(state); | ||
| 367 | switch (td_state) { | ||
| 368 | case SINGLE_TAP: | ||
| 369 | register_code16(KC_LPRN); | ||
| 370 | break; | ||
| 371 | case SINGLE_HOLD: | ||
| 372 | register_mods(MOD_BIT(KC_LALT)); // for a layer-tap key, use `layer_on(_MY_LAYER)` here | ||
| 373 | break; | ||
| 374 | case DOUBLE_SINGLE_TAP: // allow nesting of 2 parens `((` within tapping term | ||
| 375 | tap_code16(KC_LPRN); | ||
| 376 | register_code16(KC_LPRN); | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | void altlp_reset (qk_tap_dance_state_t *state, void *user_data) { | ||
| 381 | switch (td_state) { | ||
| 382 | case SINGLE_TAP: | ||
| 383 | unregister_code16(KC_LPRN); | ||
| 384 | break; | ||
| 385 | case SINGLE_HOLD: | ||
| 386 | unregister_mods(MOD_BIT(KC_LALT)); // for a layer-tap key, use `layer_off(_MY_LAYER)` here | ||
| 387 | break; | ||
| 388 | case DOUBLE_SINGLE_TAP: | ||
| 389 | unregister_code16(KC_LPRN); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | // define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions | ||
| 394 | qk_tap_dance_action_t tap_dance_actions[] = { | ||
| 395 | [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset) | ||
| 396 | }; | ||
| 397 | ``` | ||
| 398 | |||
| 399 | Wrap each tapdance keycode in `TD()` when including it in your keymap, e.g. `TD(ALT_LP)`. | ||
