diff options
| author | Daniel Gordon <Dgordon8765@gmail.com> | 2018-05-04 12:39:57 -0500 |
|---|---|---|
| committer | Drashna Jaelre <drashna@live.com> | 2018-05-04 10:39:57 -0700 |
| commit | e6be4484e9afe190246d17dd2f2dc3d688ac709f (patch) | |
| tree | f4bbb841979efc0cd7117fe41ba53f40915b75d2 /docs/feature_tap_dance.md | |
| parent | 1806509ad5d34d6eabf2968097d6f68f048fc761 (diff) | |
| download | qmk_firmware-e6be4484e9afe190246d17dd2f2dc3d688ac709f.tar.gz qmk_firmware-e6be4484e9afe190246d17dd2f2dc3d688ac709f.zip | |
Update to tap dance docs (#2895)
* Added more comments
* Documentation for 'quad function' tap dance now suggests to use the
user's directory, and explains how to do so.
Diffstat (limited to 'docs/feature_tap_dance.md')
| -rw-r--r-- | docs/feature_tap_dance.md | 122 |
1 files changed, 104 insertions, 18 deletions
diff --git a/docs/feature_tap_dance.md b/docs/feature_tap_dance.md index 0521826b2..141c3108d 100644 --- a/docs/feature_tap_dance.md +++ b/docs/feature_tap_dance.md | |||
| @@ -179,42 +179,124 @@ Below is a specific example: | |||
| 179 | * Double Tap = Send `Escape` | 179 | * Double Tap = Send `Escape` |
| 180 | * Double Tap and Hold = Send `Alt` | 180 | * Double Tap and Hold = Send `Alt` |
| 181 | 181 | ||
| 182 | The following example can be easily expanded to more than 4 quite easily: | 182 | ## Setup |
| 183 | |||
| 184 | You will need a few things that can be used for 'Quad Function Tap-Dance'. The suggested setup is to create a user directory for yourself. This directory will contain rules.mk `<your_name>.c` and `<your_name>.h`. This directory should be called `<your_name>`, and located in the top level `users` directory. There should already be a few examples to look at there. | ||
| 185 | |||
| 186 | ### In `/qmk_firmware/users/<your_name>/rules.mk` | ||
| 187 | |||
| 188 | Put the following: | ||
| 183 | ```c | 189 | ```c |
| 184 | //**************** Definitions needed for quad function to work *********************// | 190 | TAP_DANCE_ENABLE = yes |
| 185 | //Enums used to clearly convey the state of the tap dance | 191 | SRC += your_name.c |
| 192 | ``` | ||
| 193 | |||
| 194 | Pretty simple. It is a nice way to keep some rules common on all your keymaps. | ||
| 195 | |||
| 196 | |||
| 197 | ### In `/qmk_firmware/users/<your_name>/<you_name>.h` | ||
| 198 | |||
| 199 | You will need a few things in this file: | ||
| 200 | |||
| 201 | ```c | ||
| 202 | #ifndef YOUR_NAME | ||
| 203 | #define YOUR_NAME | ||
| 204 | |||
| 205 | #include "quantum.h" | ||
| 206 | #include "process_keycode/process_tap_dance.h" | ||
| 207 | |||
| 208 | |||
| 209 | typedef struct { | ||
| 210 | bool is_press_action; | ||
| 211 | int state; | ||
| 212 | } xtap; | ||
| 213 | |||
| 186 | enum { | 214 | enum { |
| 187 | SINGLE_TAP = 1, | 215 | SINGLE_TAP = 1, |
| 188 | SINGLE_HOLD = 2, | 216 | SINGLE_HOLD = 2, |
| 189 | DOUBLE_TAP = 3, | 217 | DOUBLE_TAP = 3, |
| 190 | DOUBLE_HOLD = 4, | 218 | DOUBLE_HOLD = 4, |
| 191 | DOUBLE_SINGLE_TAP = 5 //send SINGLE_TAP twice - NOT DOUBLE_TAP | 219 | DOUBLE_SINGLE_TAP = 5, //send two single taps |
| 192 | // Add more enums here if you want for triple, quadruple, etc. | 220 | TRIPLE_TAP = 6, |
| 221 | TRIPLE_HOLD = 7 | ||
| 193 | }; | 222 | }; |
| 194 | 223 | ||
| 195 | typedef struct { | 224 | //Tap dance enums |
| 196 | bool is_press_action; | 225 | enum { |
| 197 | int state; | 226 | CTL_X = 0, |
| 198 | } tap; | 227 | SOME_OTHER_DANCE |
| 228 | } | ||
| 229 | |||
| 230 | int cur_dance (qk_tap_dance_state_t *state); | ||
| 231 | |||
| 232 | //for the x tap dance. Put it here so it can be used in any keymap | ||
| 233 | void x_finished (qk_tap_dance_state_t *state, void *user_data); | ||
| 234 | void x_reset (qk_tap_dance_state_t *state, void *user_data); | ||
| 235 | ``` | ||
| 236 | |||
| 237 | ### In `/qmk_firmware/users/<your_name>/<your_name>.c` | ||
| 199 | 238 | ||
| 239 | And then in your user's `.c` file you implement the functions above: | ||
| 240 | |||
| 241 | ```c | ||
| 242 | #include "gordon.h" | ||
| 243 | #include "quantum.h" | ||
| 244 | #include "action.h" | ||
| 245 | #include "process_keycode/process_tap_dance.h" | ||
| 246 | |||
| 247 | /* Return an integer that corresponds to what kind of tap dance should be executed. | ||
| 248 | * | ||
| 249 | * How to figure out tap dance state: interrupted and pressed. | ||
| 250 | * | ||
| 251 | * Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit | ||
| 252 | * under the tapping term. This is typically indicitive that you are trying to "tap" the key. | ||
| 253 | * | ||
| 254 | * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term | ||
| 255 | * has ended, but the key is still being pressed down. This generally means the key is being "held". | ||
| 256 | * | ||
| 257 | * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold" | ||
| 258 | * feature. In general, advanced tap dances do not work well if they are used with commonly typed letters. | ||
| 259 | * For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters. | ||
| 260 | * | ||
| 261 | * Good places to put an advanced tap dance: | ||
| 262 | * z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon | ||
| 263 | * | ||
| 264 | * Criteria for "good placement" of a tap dance key: | ||
| 265 | * Not a key that is hit frequently in a sentence | ||
| 266 | * Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or | ||
| 267 | * in a web form. So 'tab' would be a poor choice for a tap dance. | ||
| 268 | * Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the | ||
| 269 | * letter 'p', the word 'pepper' would be quite frustating to type. | ||
| 270 | * | ||
| 271 | * For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested | ||
| 272 | * | ||
| 273 | */ | ||
| 200 | int cur_dance (qk_tap_dance_state_t *state) { | 274 | int cur_dance (qk_tap_dance_state_t *state) { |
| 201 | if (state->count == 1) { | 275 | if (state->count == 1) { |
| 202 | //If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP | 276 | if (state->interrupted || !state->pressed) return SINGLE_TAP; |
| 203 | if (state->interrupted || state->pressed==0) return SINGLE_TAP; | 277 | //key has not been interrupted, but they key is still held. Means you want to send a 'HOLD'. |
| 204 | else return SINGLE_HOLD; | 278 | else return SINGLE_HOLD; |
| 205 | } | 279 | } |
| 206 | //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated | ||
| 207 | //with single tap. In example below, that means to send `xx` instead of `Escape`. | ||
| 208 | else if (state->count == 2) { | 280 | else if (state->count == 2) { |
| 281 | /* | ||
| 282 | * DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap | ||
| 283 | * action when hitting 'pp'. Suggested use case for this return value is when you want to send two | ||
| 284 | * keystrokes of the key, and not the 'double tap' action/macro. | ||
| 285 | */ | ||
| 209 | if (state->interrupted) return DOUBLE_SINGLE_TAP; | 286 | if (state->interrupted) return DOUBLE_SINGLE_TAP; |
| 210 | else if (state->pressed) return DOUBLE_HOLD; | 287 | else if (state->pressed) return DOUBLE_HOLD; |
| 211 | else return DOUBLE_TAP; | 288 | else return DOUBLE_TAP; |
| 212 | } | 289 | } |
| 213 | else return 6; //magic number. At some point this method will expand to work for more presses | 290 | //Assumes no one is trying to type the same letter three times (at least not quickly). |
| 291 | //If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add | ||
| 292 | //an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP' | ||
| 293 | if (state->count == 3) { | ||
| 294 | if (state->interrupted || !state->pressed) return TRIPLE_TAP; | ||
| 295 | else return TRIPLE_HOLD; | ||
| 296 | } | ||
| 297 | else return 8; //magic number. At some point this method will expand to work for more presses | ||
| 214 | } | 298 | } |
| 215 | 299 | ||
| 216 | //**************** Definitions needed for quad function to work *********************// | ||
| 217 | |||
| 218 | //instanalize an instance of 'tap' for the 'x' tap dance. | 300 | //instanalize an instance of 'tap' for the 'x' tap dance. |
| 219 | static tap xtap_state = { | 301 | static tap xtap_state = { |
| 220 | .is_press_action = true, | 302 | .is_press_action = true, |
| @@ -245,6 +327,10 @@ void x_reset (qk_tap_dance_state_t *state, void *user_data) { | |||
| 245 | } | 327 | } |
| 246 | xtap_state.state = 0; | 328 | xtap_state.state = 0; |
| 247 | } | 329 | } |
| 330 | |||
| 331 | qk_tap_dance_action_t tap_dance_actions[] = { | ||
| 332 | [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL,x_finished, x_reset) | ||
| 333 | }; | ||
| 248 | ``` | 334 | ``` |
| 249 | And then simply add this to your list of tap dance functions: | 335 | |
| 250 | `[X_TAP_DANCE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset)` | 336 | And then simply use TD(X_CTL) anywhere in your keymap. |
