Use uint8 with idx rather than uint16 with keycode in state

This commit is contained in:
Stephen Ostermiller 2025-06-27 18:58:49 -04:00
parent 39ab15a52f
commit 425a4007ce
3 changed files with 11 additions and 10 deletions

View File

@ -46,7 +46,7 @@ Well, that's the bulk of it! You should now be able to work through the examples
Let's go over the three functions mentioned in `ACTION_TAP_DANCE_FN_ADVANCED` in a little more detail. They all receive the same two arguments: a pointer to a structure that holds all dance related state information, and a pointer to a use case specific state variable. The three functions differ in when they are called. The first, `on_each_tap_fn()`, is called every time the tap dance key is *pressed*. Before it is called, the counter is incremented and the timer is reset. The second function, `on_dance_finished_fn()`, is called when the tap dance is interrupted or ends because `TAPPING_TERM` milliseconds have passed since the last tap. When the `finished` field of the dance state structure is set to `true`, the `on_dance_finished_fn()` is skipped. After `on_dance_finished_fn()` was called or would have been called, but no sooner than when the tap dance key is *released*, `on_dance_reset_fn()` is called. It is possible to end a tap dance immediately, skipping `on_dance_finished_fn()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`.
To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()` *after* `process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `tap_dance_task()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case.
To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()` *after* `process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `½()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case.
This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness.

View File

@ -35,20 +35,20 @@ static uint16_t last_tap_time;
tap_dance_state_t *tap_dance_get_state(uint8_t tap_dance_idx) {
uint8_t i;
uint16_t keycode = QK_TAP_DANCE + tap_dance_idx;
if (tap_dance_idx >= tap_dance_count()) {
return NULL;
}
// Search for a state already used for this keycode
for (i = 0; i < TAP_DANCE_MAX_SIMULTANEOUS; i++) {
if (tap_dance_states[i].keycode == keycode) {
if (tap_dance_states[i].in_use && tap_dance_states[i].index == tap_dance_idx) {
return &tap_dance_states[i];
}
}
// Search for the first available state
for (i = 0; i < TAP_DANCE_MAX_SIMULTANEOUS; i++) {
if (tap_dance_states[i].keycode == 0) {
tap_dance_states[i].keycode = keycode;
if (!tap_dance_states[i].in_use) {
tap_dance_states[i].index = tap_dance_idx;
tap_dance_states[i].in_use = true;
return &tap_dance_states[i];
}
}
@ -238,5 +238,5 @@ void tap_dance_task(void) {
void reset_tap_dance(tap_dance_state_t *state) {
active_td = 0;
process_tap_dance_action_on_reset(tap_dance_get(QK_TAP_DANCE_GET_INDEX(state->keycode)), state);
process_tap_dance_action_on_reset(tap_dance_get(state->index), state);
}

View File

@ -28,10 +28,11 @@ typedef struct {
#ifndef NO_ACTION_ONESHOT
uint8_t oneshot_mods;
#endif
bool pressed : 1;
bool finished : 1;
bool interrupted : 1;
uint16_t keycode;
bool pressed : 1;
bool finished : 1;
bool interrupted : 1;
bool in_use : 1;
uint8_t index;
} tap_dance_state_t;
typedef void (*tap_dance_user_fn_t)(tap_dance_state_t *state, void *user_data);