diff options
| author | scauligi <scauligi@eng.ucsd.edu> | 2018-02-04 10:45:19 -0800 |
|---|---|---|
| committer | Jack Humbert <jack.humb@gmail.com> | 2018-02-04 13:45:19 -0500 |
| commit | 9fcda95363568156887c76867e843a86f8f75757 (patch) | |
| tree | d9677c75a66589f5a32453003ba814458bb50b8e | |
| parent | 2908c0f9277d021d35133940d6a4d77569229ecf (diff) | |
| download | qmk_firmware-9fcda95363568156887c76867e843a86f8f75757.tar.gz qmk_firmware-9fcda95363568156887c76867e843a86f8f75757.zip | |
Fixes to get tap dance to fire at proper places (#2272)
* tap dance fixes: fire immediately upon completion and also get properly interrupted before macros
* bugfix for tapdance improvement
* fix build
| -rw-r--r-- | quantum/process_keycode/process_tap_dance.c | 73 | ||||
| -rw-r--r-- | quantum/process_keycode/process_tap_dance.h | 7 | ||||
| -rw-r--r-- | quantum/quantum.c | 4 |
3 files changed, 53 insertions, 31 deletions
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index f196a9cb6..94dd17c2f 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c | |||
| @@ -21,6 +21,15 @@ uint8_t get_oneshot_mods(void); | |||
| 21 | static uint16_t last_td; | 21 | static uint16_t last_td; |
| 22 | static int8_t highest_td = -1; | 22 | static int8_t highest_td = -1; |
| 23 | 23 | ||
| 24 | void qk_tap_dance_pair_on_each_tap (qk_tap_dance_state_t *state, void *user_data) { | ||
| 25 | qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; | ||
| 26 | |||
| 27 | if (state->count == 2) { | ||
| 28 | register_code16 (pair->kc2); | ||
| 29 | state->finished = true; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 24 | void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { | 33 | void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { |
| 25 | qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; | 34 | qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; |
| 26 | 35 | ||
| @@ -41,6 +50,15 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { | |||
| 41 | } | 50 | } |
| 42 | } | 51 | } |
| 43 | 52 | ||
| 53 | void qk_tap_dance_dual_role_on_each_tap (qk_tap_dance_state_t *state, void *user_data) { | ||
| 54 | qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; | ||
| 55 | |||
| 56 | if (state->count == 2) { | ||
| 57 | layer_move (pair->layer); | ||
| 58 | state->finished = true; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 44 | void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) { | 62 | void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) { |
| 45 | qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; | 63 | qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; |
| 46 | 64 | ||
| @@ -92,13 +110,30 @@ static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *act | |||
| 92 | send_keyboard_report(); | 110 | send_keyboard_report(); |
| 93 | } | 111 | } |
| 94 | 112 | ||
| 95 | bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { | 113 | void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) { |
| 96 | uint16_t idx = keycode - QK_TAP_DANCE; | ||
| 97 | qk_tap_dance_action_t *action; | 114 | qk_tap_dance_action_t *action; |
| 98 | 115 | ||
| 99 | if (last_td && last_td != keycode) { | 116 | if (!record->event.pressed) |
| 100 | (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true; | 117 | return; |
| 118 | |||
| 119 | if (highest_td == -1) | ||
| 120 | return; | ||
| 121 | |||
| 122 | for (int i = 0; i <= highest_td; i++) { | ||
| 123 | action = &tap_dance_actions[i]; | ||
| 124 | if (action->state.count) { | ||
| 125 | if (keycode == action->state.keycode && keycode == last_td) | ||
| 126 | continue; | ||
| 127 | action->state.interrupted = true; | ||
| 128 | process_tap_dance_action_on_dance_finished (action); | ||
| 129 | reset_tap_dance (&action->state); | ||
| 130 | } | ||
| 101 | } | 131 | } |
| 132 | } | ||
| 133 | |||
| 134 | bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { | ||
| 135 | uint16_t idx = keycode - QK_TAP_DANCE; | ||
| 136 | qk_tap_dance_action_t *action; | ||
| 102 | 137 | ||
| 103 | switch(keycode) { | 138 | switch(keycode) { |
| 104 | case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: | 139 | case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: |
| @@ -116,34 +151,14 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { | |||
| 116 | action->state.weak_mods |= get_weak_mods(); | 151 | action->state.weak_mods |= get_weak_mods(); |
| 117 | process_tap_dance_action_on_each_tap (action); | 152 | process_tap_dance_action_on_each_tap (action); |
| 118 | 153 | ||
| 119 | if (last_td && last_td != keycode) { | ||
| 120 | qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE]; | ||
| 121 | paction->state.interrupted = true; | ||
| 122 | process_tap_dance_action_on_dance_finished (paction); | ||
| 123 | reset_tap_dance (&paction->state); | ||
| 124 | } | ||
| 125 | |||
| 126 | last_td = keycode; | 154 | last_td = keycode; |
| 155 | } else { | ||
| 156 | if (action->state.count && action->state.finished) { | ||
| 157 | reset_tap_dance (&action->state); | ||
| 158 | } | ||
| 127 | } | 159 | } |
| 128 | 160 | ||
| 129 | break; | 161 | break; |
| 130 | |||
| 131 | default: | ||
| 132 | if (!record->event.pressed) | ||
| 133 | return true; | ||
| 134 | |||
| 135 | if (highest_td == -1) | ||
| 136 | return true; | ||
| 137 | |||
| 138 | for (int i = 0; i <= highest_td; i++) { | ||
| 139 | action = &tap_dance_actions[i]; | ||
| 140 | if (action->state.count == 0) | ||
| 141 | continue; | ||
| 142 | action->state.interrupted = true; | ||
| 143 | process_tap_dance_action_on_dance_finished (action); | ||
| 144 | reset_tap_dance (&action->state); | ||
| 145 | } | ||
| 146 | break; | ||
| 147 | } | 162 | } |
| 148 | 163 | ||
| 149 | return true; | 164 | return true; |
| @@ -156,7 +171,7 @@ void matrix_scan_tap_dance () { | |||
| 156 | return; | 171 | return; |
| 157 | uint16_t tap_user_defined; | 172 | uint16_t tap_user_defined; |
| 158 | 173 | ||
| 159 | for (uint8_t i = 0; i <= highest_td; i++) { | 174 | for (uint8_t i = 0; i <= highest_td; i++) { |
| 160 | qk_tap_dance_action_t *action = &tap_dance_actions[i]; | 175 | qk_tap_dance_action_t *action = &tap_dance_actions[i]; |
| 161 | if(action->custom_tapping_term > 0 ) { | 176 | if(action->custom_tapping_term > 0 ) { |
| 162 | tap_user_defined = action->custom_tapping_term; | 177 | tap_user_defined = action->custom_tapping_term; |
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h index ab20ea04e..8b0a47c49 100644 --- a/quantum/process_keycode/process_tap_dance.h +++ b/quantum/process_keycode/process_tap_dance.h | |||
| @@ -62,12 +62,12 @@ typedef struct | |||
| 62 | } qk_tap_dance_dual_role_t; | 62 | } qk_tap_dance_dual_role_t; |
| 63 | 63 | ||
| 64 | #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ | 64 | #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ |
| 65 | .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ | 65 | .fn = { qk_tap_dance_pair_on_each_tap, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ |
| 66 | .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \ | 66 | .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \ |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | #define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) { \ | 69 | #define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) { \ |
| 70 | .fn = { NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, \ | 70 | .fn = { qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, \ |
| 71 | .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer }), \ | 71 | .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer }), \ |
| 72 | } | 72 | } |
| 73 | 73 | ||
| @@ -91,13 +91,16 @@ extern qk_tap_dance_action_t tap_dance_actions[]; | |||
| 91 | 91 | ||
| 92 | /* To be used internally */ | 92 | /* To be used internally */ |
| 93 | 93 | ||
| 94 | void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record); | ||
| 94 | bool process_tap_dance(uint16_t keycode, keyrecord_t *record); | 95 | bool process_tap_dance(uint16_t keycode, keyrecord_t *record); |
| 95 | void matrix_scan_tap_dance (void); | 96 | void matrix_scan_tap_dance (void); |
| 96 | void reset_tap_dance (qk_tap_dance_state_t *state); | 97 | void reset_tap_dance (qk_tap_dance_state_t *state); |
| 97 | 98 | ||
| 99 | void qk_tap_dance_pair_on_each_tap (qk_tap_dance_state_t *state, void *user_data); | ||
| 98 | void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); | 100 | void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); |
| 99 | void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); | 101 | void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); |
| 100 | 102 | ||
| 103 | void qk_tap_dance_dual_role_on_each_tap (qk_tap_dance_state_t *state, void *user_data); | ||
| 101 | void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data); | 104 | void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data); |
| 102 | void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data); | 105 | void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data); |
| 103 | 106 | ||
diff --git a/quantum/quantum.c b/quantum/quantum.c index f5246d9b1..d3685f50b 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
| @@ -209,6 +209,10 @@ bool process_record_quantum(keyrecord_t *record) { | |||
| 209 | // return false; | 209 | // return false; |
| 210 | // } | 210 | // } |
| 211 | 211 | ||
| 212 | #ifdef TAP_DANCE_ENABLE | ||
| 213 | preprocess_tap_dance(keycode, record); | ||
| 214 | #endif | ||
| 215 | |||
| 212 | if (!( | 216 | if (!( |
| 213 | #if defined(KEY_LOCK_ENABLE) | 217 | #if defined(KEY_LOCK_ENABLE) |
| 214 | // Must run first to be able to mask key_up events. | 218 | // Must run first to be able to mask key_up events. |
