race condition between oneshot_mods and tap_dance
since the keycode for a tap dance process gets process only after the TAPPING_TERM timeout, you really only have ONESHOT_TIMEOUT - TAPPING_TERM time to tap or double tap on the key. This fix save the oneshot_mods into the action.state structure and applies the mods with the keycode when it's registered. It also unregisters the mod when the the tap dance process gets reset.
This commit is contained in:
parent
ec05f65421
commit
5a860b71a1
2 changed files with 7 additions and 1 deletions
|
@ -43,12 +43,16 @@ static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_acti
|
||||||
if (action->state.finished)
|
if (action->state.finished)
|
||||||
return;
|
return;
|
||||||
action->state.finished = true;
|
action->state.finished = true;
|
||||||
|
add_mods(action->state.oneshot_mods);
|
||||||
|
send_keyboard_report();
|
||||||
_process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished);
|
_process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action)
|
static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action)
|
||||||
{
|
{
|
||||||
_process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset);
|
_process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset);
|
||||||
|
del_mods(action->state.oneshot_mods);
|
||||||
|
send_keyboard_report();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
|
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
@ -70,6 +74,7 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
|
||||||
action->state.keycode = keycode;
|
action->state.keycode = keycode;
|
||||||
action->state.count++;
|
action->state.count++;
|
||||||
action->state.timer = timer_read();
|
action->state.timer = timer_read();
|
||||||
|
action->state.oneshot_mods = get_oneshot_mods();
|
||||||
process_tap_dance_action_on_each_tap (action);
|
process_tap_dance_action_on_each_tap (action);
|
||||||
|
|
||||||
if (last_td && last_td != keycode) {
|
if (last_td && last_td != keycode) {
|
||||||
|
@ -109,7 +114,7 @@ void matrix_scan_tap_dance () {
|
||||||
if (highest_td == -1)
|
if (highest_td == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i <= highest_td; i++) {
|
for (int i = 0; i <= highest_td; i++) {
|
||||||
qk_tap_dance_action_t *action = &tap_dance_actions[i];
|
qk_tap_dance_action_t *action = &tap_dance_actions[i];
|
||||||
|
|
||||||
if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) {
|
if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8_t count;
|
uint8_t count;
|
||||||
|
uint8_t oneshot_mods;
|
||||||
uint16_t keycode;
|
uint16_t keycode;
|
||||||
uint16_t timer;
|
uint16_t timer;
|
||||||
bool interrupted;
|
bool interrupted;
|
||||||
|
|
Loading…
Reference in a new issue