aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode/process_tap_dance.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode/process_tap_dance.c')
-rw-r--r--quantum/process_keycode/process_tap_dance.c268
1 files changed, 125 insertions, 143 deletions
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index 16d33ddde..c27fe4834 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -17,7 +17,7 @@
17#include "action_tapping.h" 17#include "action_tapping.h"
18 18
19#ifndef TAPPING_TERM 19#ifndef TAPPING_TERM
20#define TAPPING_TERM 200 20# define TAPPING_TERM 200
21#endif 21#endif
22 22
23#ifndef NO_ACTION_ONESHOT 23#ifndef NO_ACTION_ONESHOT
@@ -25,191 +25,173 @@ uint8_t get_oneshot_mods(void);
25#endif 25#endif
26 26
27static uint16_t last_td; 27static uint16_t last_td;
28static int8_t highest_td = -1; 28static int8_t highest_td = -1;
29 29
30void qk_tap_dance_pair_on_each_tap (qk_tap_dance_state_t *state, void *user_data) { 30void qk_tap_dance_pair_on_each_tap(qk_tap_dance_state_t *state, void *user_data) {
31 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; 31 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
32 32
33 if (state->count == 2) { 33 if (state->count == 2) {
34 register_code16 (pair->kc2); 34 register_code16(pair->kc2);
35 state->finished = true; 35 state->finished = true;
36 } 36 }
37} 37}
38 38
39void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { 39void qk_tap_dance_pair_finished(qk_tap_dance_state_t *state, void *user_data) {
40 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; 40 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
41 41
42 if (state->count == 1) { 42 if (state->count == 1) {
43 register_code16 (pair->kc1); 43 register_code16(pair->kc1);
44 } else if (state->count == 2) { 44 } else if (state->count == 2) {
45 register_code16 (pair->kc2); 45 register_code16(pair->kc2);
46 } 46 }
47} 47}
48 48
49void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { 49void qk_tap_dance_pair_reset(qk_tap_dance_state_t *state, void *user_data) {
50 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; 50 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
51 51
52 if (state->count == 1) { 52 if (state->count == 1) {
53 unregister_code16 (pair->kc1); 53 unregister_code16(pair->kc1);
54 } else if (state->count == 2) { 54 } else if (state->count == 2) {
55 unregister_code16 (pair->kc2); 55 unregister_code16(pair->kc2);
56 } 56 }
57} 57}
58 58
59void qk_tap_dance_dual_role_on_each_tap (qk_tap_dance_state_t *state, void *user_data) { 59void qk_tap_dance_dual_role_on_each_tap(qk_tap_dance_state_t *state, void *user_data) {
60 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; 60 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
61 61
62 if (state->count == 2) { 62 if (state->count == 2) {
63 layer_move (pair->layer); 63 layer_move(pair->layer);
64 state->finished = true; 64 state->finished = true;
65 } 65 }
66} 66}
67 67
68void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) { 68void qk_tap_dance_dual_role_finished(qk_tap_dance_state_t *state, void *user_data) {
69 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; 69 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
70 70
71 if (state->count == 1) { 71 if (state->count == 1) {
72 register_code16 (pair->kc); 72 register_code16(pair->kc);
73 } else if (state->count == 2) { 73 } else if (state->count == 2) {
74 layer_move (pair->layer); 74 layer_move(pair->layer);
75 } 75 }
76} 76}
77 77
78void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data) { 78void qk_tap_dance_dual_role_reset(qk_tap_dance_state_t *state, void *user_data) {
79 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; 79 qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
80 80
81 if (state->count == 1) { 81 if (state->count == 1) {
82 unregister_code16 (pair->kc); 82 unregister_code16(pair->kc);
83 } 83 }
84} 84}
85 85
86static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, 86static inline void _process_tap_dance_action_fn(qk_tap_dance_state_t *state, void *user_data, qk_tap_dance_user_fn_t fn) {
87 void *user_data, 87 if (fn) {
88 qk_tap_dance_user_fn_t fn) 88 fn(state, user_data);
89{ 89 }
90 if (fn) {
91 fn(state, user_data);
92 }
93} 90}
94 91
95static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t *action) 92static inline void process_tap_dance_action_on_each_tap(qk_tap_dance_action_t *action) { _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_tap); }
96{
97 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_each_tap);
98}
99 93
100static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t *action) 94static inline void process_tap_dance_action_on_dance_finished(qk_tap_dance_action_t *action) {
101{ 95 if (action->state.finished) return;
102 if (action->state.finished) 96 action->state.finished = true;
103 return; 97 add_mods(action->state.oneshot_mods);
104 action->state.finished = true; 98 add_weak_mods(action->state.weak_mods);
105 add_mods(action->state.oneshot_mods); 99 send_keyboard_report();
106 add_weak_mods(action->state.weak_mods); 100 _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_dance_finished);
107 send_keyboard_report();
108 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished);
109} 101}
110 102
111static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action) 103static inline void process_tap_dance_action_on_reset(qk_tap_dance_action_t *action) {
112{ 104 _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_reset);
113 _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset); 105 del_mods(action->state.oneshot_mods);
114 del_mods(action->state.oneshot_mods); 106 del_weak_mods(action->state.weak_mods);
115 del_weak_mods(action->state.weak_mods); 107 send_keyboard_report();
116 send_keyboard_report();
117} 108}
118 109
119void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) { 110void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
120 qk_tap_dance_action_t *action; 111 qk_tap_dance_action_t *action;
121 112
122 if (!record->event.pressed) 113 if (!record->event.pressed) return;
123 return; 114
124 115 if (highest_td == -1) return;
125 if (highest_td == -1) 116
126 return; 117 for (int i = 0; i <= highest_td; i++) {
127 118 action = &tap_dance_actions[i];
128 for (int i = 0; i <= highest_td; i++) { 119 if (action->state.count) {
129 action = &tap_dance_actions[i]; 120 if (keycode == action->state.keycode && keycode == last_td) continue;
130 if (action->state.count) { 121 action->state.interrupted = true;
131 if (keycode == action->state.keycode && keycode == last_td) 122 action->state.interrupting_keycode = keycode;
132 continue; 123 process_tap_dance_action_on_dance_finished(action);
133 action->state.interrupted = true; 124 reset_tap_dance(&action->state);
134 action->state.interrupting_keycode = keycode; 125 }
135 process_tap_dance_action_on_dance_finished (action);
136 reset_tap_dance (&action->state);
137 } 126 }
138 }
139} 127}
140 128
141bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { 129bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
142 uint16_t idx = keycode - QK_TAP_DANCE; 130 uint16_t idx = keycode - QK_TAP_DANCE;
143 qk_tap_dance_action_t *action; 131 qk_tap_dance_action_t *action;
144 132
145 switch(keycode) { 133 switch (keycode) {
146 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: 134 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
147 if ((int16_t)idx > highest_td) 135 if ((int16_t)idx > highest_td) highest_td = idx;
148 highest_td = idx; 136 action = &tap_dance_actions[idx];
149 action = &tap_dance_actions[idx]; 137
150 138 action->state.pressed = record->event.pressed;
151 action->state.pressed = record->event.pressed; 139 if (record->event.pressed) {
152 if (record->event.pressed) { 140 action->state.keycode = keycode;
153 action->state.keycode = keycode; 141 action->state.count++;
154 action->state.count++; 142 action->state.timer = timer_read();
155 action->state.timer = timer_read();
156#ifndef NO_ACTION_ONESHOT 143#ifndef NO_ACTION_ONESHOT
157 action->state.oneshot_mods = get_oneshot_mods(); 144 action->state.oneshot_mods = get_oneshot_mods();
158#else 145#else
159 action->state.oneshot_mods = 0; 146 action->state.oneshot_mods = 0;
160#endif 147#endif
161 action->state.weak_mods = get_mods(); 148 action->state.weak_mods = get_mods();
162 action->state.weak_mods |= get_weak_mods(); 149 action->state.weak_mods |= get_weak_mods();
163 process_tap_dance_action_on_each_tap (action); 150 process_tap_dance_action_on_each_tap(action);
164 151
165 last_td = keycode; 152 last_td = keycode;
166 } else { 153 } else {
167 if (action->state.count && action->state.finished) { 154 if (action->state.count && action->state.finished) {
168 reset_tap_dance (&action->state); 155 reset_tap_dance(&action->state);
169 } 156 }
157 }
158
159 break;
170 } 160 }
171 161
172 break; 162 return true;
173 }
174
175 return true;
176} 163}
177 164
178 165void matrix_scan_tap_dance() {
179 166 if (highest_td == -1) return;
180void matrix_scan_tap_dance () { 167 uint16_t tap_user_defined;
181 if (highest_td == -1) 168
182 return; 169 for (uint8_t i = 0; i <= highest_td; i++) {
183 uint16_t tap_user_defined; 170 qk_tap_dance_action_t *action = &tap_dance_actions[i];
184 171 if (action->custom_tapping_term > 0) {
185 for (uint8_t i = 0; i <= highest_td; i++) { 172 tap_user_defined = action->custom_tapping_term;
186 qk_tap_dance_action_t *action = &tap_dance_actions[i]; 173 } else {
187 if(action->custom_tapping_term > 0 ) { 174 tap_user_defined = TAPPING_TERM;
188 tap_user_defined = action->custom_tapping_term; 175 }
189 } 176 if (action->state.count && timer_elapsed(action->state.timer) > tap_user_defined) {
190 else{ 177 process_tap_dance_action_on_dance_finished(action);
191 tap_user_defined = TAPPING_TERM; 178 reset_tap_dance(&action->state);
192 } 179 }
193 if (action->state.count && timer_elapsed (action->state.timer) > tap_user_defined) {
194 process_tap_dance_action_on_dance_finished (action);
195 reset_tap_dance (&action->state);
196 } 180 }
197 }
198} 181}
199 182
200void reset_tap_dance (qk_tap_dance_state_t *state) { 183void reset_tap_dance(qk_tap_dance_state_t *state) {
201 qk_tap_dance_action_t *action; 184 qk_tap_dance_action_t *action;
202 185
203 if (state->pressed) 186 if (state->pressed) return;
204 return;
205 187
206 action = &tap_dance_actions[state->keycode - QK_TAP_DANCE]; 188 action = &tap_dance_actions[state->keycode - QK_TAP_DANCE];
207 189
208 process_tap_dance_action_on_reset (action); 190 process_tap_dance_action_on_reset(action);
209 191
210 state->count = 0; 192 state->count = 0;
211 state->interrupted = false; 193 state->interrupted = false;
212 state->finished = false; 194 state->finished = false;
213 state->interrupting_keycode = 0; 195 state->interrupting_keycode = 0;
214 last_td = 0; 196 last_td = 0;
215} 197}