aboutsummaryrefslogtreecommitdiff
path: root/quantum/process_keycode
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/process_keycode')
-rw-r--r--quantum/process_keycode/process_tap_dance.c111
-rw-r--r--quantum/process_keycode/process_tap_dance.h43
2 files changed, 71 insertions, 83 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}
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
index 7b820584a..e2c74efe9 100644
--- a/quantum/process_keycode/process_tap_dance.h
+++ b/quantum/process_keycode/process_tap_dance.h
@@ -11,46 +11,40 @@ typedef struct
11 uint8_t count; 11 uint8_t count;
12 uint16_t keycode; 12 uint16_t keycode;
13 uint16_t timer; 13 uint16_t timer;
14 bool active:1;
15 bool pressed:1;
14} qk_tap_dance_state_t; 16} qk_tap_dance_state_t;
15 17
16#define TD(n) (QK_TAP_DANCE + n) 18#define TD(n) (QK_TAP_DANCE + n)
17 19
18typedef enum 20typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state, void *user_data);
19{
20 QK_TAP_DANCE_TYPE_PAIR,
21 QK_TAP_DANCE_TYPE_FN,
22} qk_tap_dance_type_t;
23
24typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state);
25 21
26typedef struct 22typedef struct
27{ 23{
28 qk_tap_dance_type_t type; 24 struct {
29 union { 25 qk_tap_dance_user_fn_t on_each_tap;
30 struct { 26 qk_tap_dance_user_fn_t on_dance_finished;
31 uint16_t kc1; 27 qk_tap_dance_user_fn_t on_reset;
32 uint16_t kc2; 28 } fn;
33 } pair; 29 void *user_data;
34 struct {
35 qk_tap_dance_user_fn_t on_each_tap;
36 qk_tap_dance_user_fn_t on_dance_finished;
37 qk_tap_dance_user_fn_t on_reset;
38 } fn;
39 };
40} qk_tap_dance_action_t; 30} qk_tap_dance_action_t;
41 31
32typedef struct
33{
34 uint16_t kc1;
35 uint16_t kc2;
36} qk_tap_dance_pair_t;
37
42#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ 38#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \
43 .type = QK_TAP_DANCE_TYPE_PAIR, \ 39 .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \
44 .pair = { kc1, kc2 } \ 40 .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }) \
45 } 41 }
46 42
47#define ACTION_TAP_DANCE_FN(user_fn) { \ 43#define ACTION_TAP_DANCE_FN(user_fn) { \
48 .type = QK_TAP_DANCE_TYPE_FN, \
49 .fn = { NULL, user_fn, NULL } \ 44 .fn = { NULL, user_fn, NULL } \
50 } 45 }
51 46
52#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \ 47#define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset) { \
53 .type = QK_TAP_DANCE_TYPE_FN, \
54 .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \ 48 .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_reset } \
55 } 49 }
56 50
@@ -62,6 +56,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record);
62void matrix_scan_tap_dance (void); 56void matrix_scan_tap_dance (void);
63void reset_tap_dance (qk_tap_dance_state_t *state); 57void reset_tap_dance (qk_tap_dance_state_t *state);
64 58
59void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data);
60void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data);
61
65#else 62#else
66 63
67#define TD(n) KC_NO 64#define TD(n) KC_NO