4ae0ca5a11c475ee49bbce13d29edbf9bd6fc636

Author
Nick Brassel <nick@tzarc.org>
Committer
GitHub <noreply@github.com>
Date

Message

Tap dance introspection (#24049)

Diff

  1diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c
  2index 71e3b429ead5090a176c2eadfd08ada8deb47dc8..4e95125335d24346022ad79ac06f73e7ad4368b6 100644
  3--- a/quantum/keymap_introspection.c
  4+++ b/quantum/keymap_introspection.c
  5@@ -109,3 +109,26 @@ __attribute__((weak)) combo_t* combo_get(uint16_t combo_idx) {
  6 }
  7 
  8 #endif // defined(COMBO_ENABLE)
  9+
 10+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 11+// Tap Dance
 12+
 13+#if defined(TAP_DANCE_ENABLE)
 14+
 15+uint16_t tap_dance_count_raw(void) {
 16+    return sizeof(tap_dance_actions) / sizeof(tap_dance_action_t);
 17+}
 18+
 19+uint16_t tap_dance_count(void) {
 20+    return tap_dance_count_raw();
 21+}
 22+
 23+tap_dance_action_t* tap_dance_get_raw(uint16_t tap_dance_idx) {
 24+    return &tap_dance_actions[tap_dance_idx];
 25+}
 26+
 27+tap_dance_action_t* tap_dance_get(uint16_t tap_dance_idx) {
 28+    return tap_dance_get_raw(tap_dance_idx);
 29+}
 30+
 31+#endif // defined(TAP_DANCE_ENABLE)
 32diff --git a/quantum/keymap_introspection.h b/quantum/keymap_introspection.h
 33index f7516bf42af7f3f7b321412213d1c75b9a6a681d..bc4dd93b4c85861bc8afd4726bcc97836e367c6f 100644
 34--- a/quantum/keymap_introspection.h
 35+++ b/quantum/keymap_introspection.h
 36@@ -61,9 +61,30 @@ uint16_t combo_count_raw(void);
 37 // Get the number of combos defined in the user's keymap, potentially stored dynamically
 38 uint16_t combo_count(void);
 39 
 40-// Get the keycode for the encoder mapping location, stored in firmware rather than any other persistent storage
 41+// Get the combo definition, stored in firmware rather than any other persistent storage
 42 combo_t* combo_get_raw(uint16_t combo_idx);
 43-// Get the keycode for the encoder mapping location, potentially stored dynamically
 44+// Get the combo definition, potentially stored dynamically
 45 combo_t* combo_get(uint16_t combo_idx);
 46 
 47 #endif // defined(COMBO_ENABLE)
 48+
 49+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 50+// Tap Dance
 51+
 52+#if defined(TAP_DANCE_ENABLE)
 53+
 54+// Forward declaration of tap_dance_action_t so we don't need to deal with header reordering
 55+struct tap_dance_action_t;
 56+typedef struct tap_dance_action_t tap_dance_action_t;
 57+
 58+// Get the number of tap dances defined in the user's keymap, stored in firmware rather than any other persistent storage
 59+uint16_t tap_dance_count_raw(void);
 60+// Get the number of tap dances defined in the user's keymap, potentially stored dynamically
 61+uint16_t tap_dance_count(void);
 62+
 63+// Get the tap dance definitions, stored in firmware rather than any other persistent storage
 64+tap_dance_action_t* tap_dance_get_raw(uint16_t tap_dance_idx);
 65+// Get the tap dance definitions, potentially stored dynamically
 66+tap_dance_action_t* tap_dance_get(uint16_t tap_dance_idx);
 67+
 68+#endif // defined(TAP_DANCE_ENABLE)
 69diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c
 70index ce3b8fc81f7079a0851dd8bb8c3961e10eae6a5b..11df62763dd1035355f6bf0fc34792ecf1466fbd 100644
 71--- a/quantum/process_keycode/process_tap_dance.c
 72+++ b/quantum/process_keycode/process_tap_dance.c
 73@@ -21,6 +21,7 @@
 74 #include "action_util.h"
 75 #include "timer.h"
 76 #include "wait.h"
 77+#include "keymap_introspection.h"
 78 
 79 static uint16_t active_td;
 80 static uint16_t last_tap_time;
 81@@ -133,7 +134,7 @@ bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
 82 
 83     if (!active_td || keycode == active_td) return false;
 84 
 85-    action                             = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(active_td)];
 86+    action                             = tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td));
 87     action->state.interrupted          = true;
 88     action->state.interrupting_keycode = keycode;
 89     process_tap_dance_action_on_dance_finished(action);
 90@@ -150,11 +151,16 @@ bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
 91 }
 92 
 93 bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
 94+    int                 td_index;
 95     tap_dance_action_t *action;
 96 
 97     switch (keycode) {
 98         case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
 99-            action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(keycode)];
100+            td_index = QK_TAP_DANCE_GET_INDEX(keycode);
101+            if (td_index >= tap_dance_count()) {
102+                return false;
103+            }
104+            action = tap_dance_get(td_index);
105 
106             action->state.pressed = record->event.pressed;
107             if (record->event.pressed) {
108@@ -182,7 +188,7 @@ void tap_dance_task(void) {
109 
110     if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return;
111 
112-    action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(active_td)];
113+    action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(active_td));
114     if (!action->state.interrupted) {
115         process_tap_dance_action_on_dance_finished(action);
116     }
117diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h
118index c0137c14a332229e039646bdb1d7384ded7a7ddf..5cccbdf439a2ed21a27b3382b16a4a0f79cf5e3d 100644
119--- a/quantum/process_keycode/process_tap_dance.h
120+++ b/quantum/process_keycode/process_tap_dance.h
121@@ -35,7 +35,7 @@ typedef struct {
122 
123 typedef void (*tap_dance_user_fn_t)(tap_dance_state_t *state, void *user_data);
124 
125-typedef struct {
126+typedef struct tap_dance_action_t {
127     tap_dance_state_t state;
128     struct {
129         tap_dance_user_fn_t on_each_tap;
130@@ -78,8 +78,6 @@ typedef struct {
131 #define TD_INDEX(code) QK_TAP_DANCE_GET_INDEX(code)
132 #define TAP_DANCE_KEYCODE(state) TD(((tap_dance_action_t *)state) - tap_dance_actions)
133 
134-extern tap_dance_action_t tap_dance_actions[];
135-
136 void reset_tap_dance(tap_dance_state_t *state);
137 
138 /* To be used internally */
139diff --git a/tests/tap_dance/examples.c b/tests/tap_dance/examples.c
140index 5377b397d3cb12e57dbc4908fb3b57e05f5914a5..4b6bdb20908f175fc8038f41f22065b9101370ad 100644
141--- a/tests/tap_dance/examples.c
142+++ b/tests/tap_dance/examples.c
143@@ -16,6 +16,7 @@
144 
145 #include "quantum.h"
146 #include "examples.h"
147+#include "keymap_introspection.h"
148 
149 // Example code from the tap dance documentation, adapted for testing
150 
151@@ -83,7 +84,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
152 
153     switch (keycode) {
154         case TD(CT_CLN):
155-            action = &tap_dance_actions[QK_TAP_DANCE_GET_INDEX(keycode)];
156+            action = tap_dance_get(QK_TAP_DANCE_GET_INDEX(keycode));
157             if (!record->event.pressed && action->state.count && !action->state.finished) {
158                 tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data;
159                 tap_code16(tap_hold->tap);
160diff --git a/tests/tap_dance/tap_dance_layers/test.mk b/tests/tap_dance/tap_dance_layers/test.mk
161index b4cdc9b0880e4e6280395131dec6e50f4b7c3511..a677fda64826dcb5bab929275ec0cafbbb8610ed 100644
162--- a/tests/tap_dance/tap_dance_layers/test.mk
163+++ b/tests/tap_dance/tap_dance_layers/test.mk
164@@ -7,4 +7,4 @@
165 
166 TAP_DANCE_ENABLE = yes
167 
168-SRC += tap_dance_defs.c
169+INTROSPECTION_KEYMAP_C = tap_dance_defs.c
170diff --git a/tests/tap_dance/test.mk b/tests/tap_dance/test.mk
171index 041d9b4dc9a2498cc2570dc3a5bc7af3c6892bcb..0e727da9e8f3128b070bdb2a15182848d3d98521 100644
172--- a/tests/tap_dance/test.mk
173+++ b/tests/tap_dance/test.mk
174@@ -18,5 +18,4 @@
175 # --------------------------------------------------------------------------------
176 
177 TAP_DANCE_ENABLE = yes
178-
179-SRC += examples.c
180+INTROSPECTION_KEYMAP_C = examples.c