Fixes to get tap dance to fire at proper places (#2272)

* tap dance fixes: fire immediately upon completion and also get properly interrupted before macros

* bugfix for tapdance improvement

* fix build
master
scauligi 2018-02-04 10:45:19 -08:00 committed by Jack Humbert
parent 2908c0f927
commit 9fcda95363
3 changed files with 53 additions and 31 deletions

View File

@ -21,6 +21,15 @@ uint8_t get_oneshot_mods(void);
static uint16_t last_td; static uint16_t last_td;
static int8_t highest_td = -1; static int8_t highest_td = -1;
void qk_tap_dance_pair_on_each_tap (qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
if (state->count == 2) {
register_code16 (pair->kc2);
state->finished = true;
}
}
void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data;
@ -41,6 +50,15 @@ void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) {
} }
} }
void qk_tap_dance_dual_role_on_each_tap (qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
if (state->count == 2) {
layer_move (pair->layer);
state->finished = true;
}
}
void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) { void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data) {
qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data; qk_tap_dance_dual_role_t *pair = (qk_tap_dance_dual_role_t *)user_data;
@ -92,14 +110,31 @@ static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *act
send_keyboard_report(); send_keyboard_report();
} }
void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) {
qk_tap_dance_action_t *action;
if (!record->event.pressed)
return;
if (highest_td == -1)
return;
for (int i = 0; i <= highest_td; i++) {
action = &tap_dance_actions[i];
if (action->state.count) {
if (keycode == action->state.keycode && keycode == last_td)
continue;
action->state.interrupted = true;
process_tap_dance_action_on_dance_finished (action);
reset_tap_dance (&action->state);
}
}
}
bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
uint16_t idx = keycode - QK_TAP_DANCE; uint16_t idx = keycode - QK_TAP_DANCE;
qk_tap_dance_action_t *action; qk_tap_dance_action_t *action;
if (last_td && last_td != keycode) {
(&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true;
}
switch(keycode) { switch(keycode) {
case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: case QK_TAP_DANCE ... QK_TAP_DANCE_MAX:
if ((int16_t)idx > highest_td) if ((int16_t)idx > highest_td)
@ -116,34 +151,14 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
action->state.weak_mods |= get_weak_mods(); action->state.weak_mods |= get_weak_mods();
process_tap_dance_action_on_each_tap (action); process_tap_dance_action_on_each_tap (action);
if (last_td && last_td != keycode) {
qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE];
paction->state.interrupted = true;
process_tap_dance_action_on_dance_finished (paction);
reset_tap_dance (&paction->state);
}
last_td = keycode; last_td = keycode;
} else {
if (action->state.count && action->state.finished) {
reset_tap_dance (&action->state);
}
} }
break; break;
default:
if (!record->event.pressed)
return true;
if (highest_td == -1)
return true;
for (int i = 0; i <= highest_td; i++) {
action = &tap_dance_actions[i];
if (action->state.count == 0)
continue;
action->state.interrupted = true;
process_tap_dance_action_on_dance_finished (action);
reset_tap_dance (&action->state);
}
break;
} }
return true; return true;
@ -156,7 +171,7 @@ void matrix_scan_tap_dance () {
return; return;
uint16_t tap_user_defined; uint16_t tap_user_defined;
for (uint8_t i = 0; i <= highest_td; i++) { for (uint8_t 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->custom_tapping_term > 0 ) { if(action->custom_tapping_term > 0 ) {
tap_user_defined = action->custom_tapping_term; tap_user_defined = action->custom_tapping_term;

View File

@ -62,12 +62,12 @@ typedef struct
} qk_tap_dance_dual_role_t; } qk_tap_dance_dual_role_t;
#define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \
.fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ .fn = { qk_tap_dance_pair_on_each_tap, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \
.user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \ .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \
} }
#define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) { \ #define ACTION_TAP_DANCE_DUAL_ROLE(kc, layer) { \
.fn = { NULL, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, \ .fn = { qk_tap_dance_dual_role_on_each_tap, qk_tap_dance_dual_role_finished, qk_tap_dance_dual_role_reset }, \
.user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer }), \ .user_data = (void *)&((qk_tap_dance_dual_role_t) { kc, layer }), \
} }
@ -91,13 +91,16 @@ extern qk_tap_dance_action_t tap_dance_actions[];
/* To be used internally */ /* To be used internally */
void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record);
bool process_tap_dance(uint16_t keycode, keyrecord_t *record); bool process_tap_dance(uint16_t keycode, keyrecord_t *record);
void matrix_scan_tap_dance (void); void matrix_scan_tap_dance (void);
void reset_tap_dance (qk_tap_dance_state_t *state); void reset_tap_dance (qk_tap_dance_state_t *state);
void qk_tap_dance_pair_on_each_tap (qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_dual_role_on_each_tap (qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data); void qk_tap_dance_dual_role_finished (qk_tap_dance_state_t *state, void *user_data);
void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data); void qk_tap_dance_dual_role_reset (qk_tap_dance_state_t *state, void *user_data);

View File

@ -209,6 +209,10 @@ bool process_record_quantum(keyrecord_t *record) {
// return false; // return false;
// } // }
#ifdef TAP_DANCE_ENABLE
preprocess_tap_dance(keycode, record);
#endif
if (!( if (!(
#if defined(KEY_LOCK_ENABLE) #if defined(KEY_LOCK_ENABLE)
// Must run first to be able to mask key_up events. // Must run first to be able to mask key_up events.