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.c111
1 files changed, 51 insertions, 60 deletions
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
index b9b836df2..d240dc2e6 100644
--- a/quantum/process_keycode/process_tap_dance.c
+++ b/quantum/process_keycode/process_tap_dance.c
@@ -2,81 +2,70 @@
2 2
3static qk_tap_dance_state_t qk_tap_dance_state; 3static qk_tap_dance_state_t qk_tap_dance_state;
4 4
5static void _process_tap_dance_action_pair (qk_tap_dance_state_t *state, 5void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) {
6 uint16_t kc1, uint16_t kc2) { 6 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
7 uint16_t kc;
8 7
9 if (state->count == 0) 8 if (state->count == 1) {
10 return; 9 register_code (pair->kc1);
11 10 } else if (state->count == 2) {
12 kc = (state->count == 1) ? kc1 : kc2; 11 register_code (pair->kc2);
12 }
13}
13 14
14 register_code (kc); 15void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) {
15 unregister_code (kc); 16 qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
16 17
17 if (state->count >= 2) { 18 if (state->count == 1) {
18 reset_tap_dance (state); 19 unregister_code (pair->kc1);
20 } else if (state->count == 2) {
21 unregister_code (pair->kc2);
19 } 22 }
20} 23}
21 24
22static void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, 25static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state,
26 void *user_data,
23 qk_tap_dance_user_fn_t fn) 27 qk_tap_dance_user_fn_t fn)
24{ 28{
25 if (fn) { 29 if (fn) {
26 fn(state); 30 fn(state, user_data);
27 } 31 }
28} 32}
29 33
30void process_tap_dance_action_on_each_tap (uint16_t keycode) 34static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t action)
31{ 35{
32 uint16_t idx = keycode - QK_TAP_DANCE; 36 _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_each_tap);
33 qk_tap_dance_action_t action;
34
35 action = tap_dance_actions[idx];
36
37 switch (action.type) {
38 case QK_TAP_DANCE_TYPE_FN:
39 _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_each_tap);
40 break;
41
42 default:
43 break;
44 }
45} 37}
46 38
47void process_tap_dance_action_on_dance_finished (uint16_t keycode) 39static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t action)
48{ 40{
49 uint16_t idx = keycode - QK_TAP_DANCE; 41 _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_dance_finished);
50 qk_tap_dance_action_t action; 42}
51
52 action = tap_dance_actions[idx];
53
54 switch (action.type) {
55 case QK_TAP_DANCE_TYPE_PAIR:
56 _process_tap_dance_action_pair (&qk_tap_dance_state,
57 action.pair.kc1, action.pair.kc2);
58 break;
59 case QK_TAP_DANCE_TYPE_FN:
60 _process_tap_dance_action_fn (&qk_tap_dance_state, action.fn.on_dance_finished);
61 break;
62 43
63 default: 44static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t action)
64 break; 45{
65 } 46 _process_tap_dance_action_fn (&qk_tap_dance_state, action.user_data, action.fn.on_reset);
66} 47}
67 48
68bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { 49bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
69 bool r = true; 50 bool r = true;
51 uint16_t idx = keycode - QK_TAP_DANCE;
52 qk_tap_dance_action_t action;
70 53
71 switch(keycode) { 54 switch(keycode) {
72 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: 55 case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
73 process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); 56 action = tap_dance_actions[idx];
57
58 process_tap_dance_action_on_each_tap (action);
74 if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) { 59 if (qk_tap_dance_state.keycode && qk_tap_dance_state.keycode != keycode) {
75 process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); 60 process_tap_dance_action_on_dance_finished (action);
61 } else if (qk_tap_dance_state.active && qk_tap_dance_state.pressed) {
62 reset_tap_dance (&qk_tap_dance_state);
76 } else { 63 } else {
77 r = false; 64 r = false;
78 } 65 }
79 66
67 qk_tap_dance_state.active = true;
68 qk_tap_dance_state.pressed = record->event.pressed;
80 if (record->event.pressed) { 69 if (record->event.pressed) {
81 qk_tap_dance_state.keycode = keycode; 70 qk_tap_dance_state.keycode = keycode;
82 qk_tap_dance_state.timer = timer_read (); 71 qk_tap_dance_state.timer = timer_read ();
@@ -87,9 +76,13 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
87 default: 76 default:
88 if (qk_tap_dance_state.keycode) { 77 if (qk_tap_dance_state.keycode) {
89 // if we are here, the tap dance was interrupted by a different key 78 // if we are here, the tap dance was interrupted by a different key
90 process_tap_dance_action_on_each_tap (qk_tap_dance_state.keycode); 79 idx = qk_tap_dance_state.keycode - QK_TAP_DANCE;
91 process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); 80 action = tap_dance_actions[idx];
81
82 process_tap_dance_action_on_each_tap (action);
83 process_tap_dance_action_on_dance_finished (action);
92 reset_tap_dance (&qk_tap_dance_state); 84 reset_tap_dance (&qk_tap_dance_state);
85 qk_tap_dance_state.active = false;
93 } 86 }
94 break; 87 break;
95 } 88 }
@@ -98,9 +91,12 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
98} 91}
99 92
100void matrix_scan_tap_dance () { 93void matrix_scan_tap_dance () {
101 if (qk_tap_dance_state.keycode && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) { 94 if (qk_tap_dance_state.active && timer_elapsed (qk_tap_dance_state.timer) > TAPPING_TERM) {
102 // if we are here, the tap dance was timed out 95 // if we are here, the tap dance was timed out
103 process_tap_dance_action_on_dance_finished (qk_tap_dance_state.keycode); 96 uint16_t idx = qk_tap_dance_state.keycode - QK_TAP_DANCE;
97 qk_tap_dance_action_t action = tap_dance_actions[idx];
98
99 process_tap_dance_action_on_dance_finished (action);
104 reset_tap_dance (&qk_tap_dance_state); 100 reset_tap_dance (&qk_tap_dance_state);
105 } 101 }
106} 102}
@@ -109,18 +105,13 @@ void reset_tap_dance (qk_tap_dance_state_t *state) {
109 uint16_t idx = state->keycode - QK_TAP_DANCE; 105 uint16_t idx = state->keycode - QK_TAP_DANCE;
110 qk_tap_dance_action_t action; 106 qk_tap_dance_action_t action;
111 107
112 action = tap_dance_actions[idx]; 108 if (state->pressed)
113 switch (action.type) { 109 return;
114 case QK_TAP_DANCE_TYPE_FN:
115 if (action.fn.on_reset) {
116 action.fn.on_reset(state);
117 }
118 break;
119 110
120 default: 111 action = tap_dance_actions[idx];
121 break; 112 process_tap_dance_action_on_reset (action);
122 }
123 113
124 state->keycode = 0; 114 state->keycode = 0;
125 state->count = 0; 115 state->count = 0;
116 state->active = false;
126} 117}