From 29ac6aece0948c2d2934ed869f575181bf84e611 Mon Sep 17 00:00:00 2001 From: Greg Leeper Date: Mon, 17 Jul 2023 10:45:37 -0400 Subject: [PATCH] ensure reset fn is only called once in on_each_release tap dance function --- quantum/process_keycode/process_tap_dance.c | 3 ++ tests/tap_dance/examples.c | 12 ++++- tests/tap_dance/examples.h | 1 + tests/tap_dance/test_examples.cpp | 50 +++++++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c index 4efe4b0aae2d..b8a8d32f350c 100644 --- a/quantum/process_keycode/process_tap_dance.c +++ b/quantum/process_keycode/process_tap_dance.c @@ -165,6 +165,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { process_tap_dance_action_on_each_release(action); if (action->state.finished) { process_tap_dance_action_on_reset(action); + if (active_td == keycode) { + active_td = 0; + } } } diff --git a/tests/tap_dance/examples.c b/tests/tap_dance/examples.c index 00f0b76c5e88..13086bbb4bba 100644 --- a/tests/tap_dance/examples.c +++ b/tests/tap_dance/examples.c @@ -195,17 +195,27 @@ static void release_unpress(tap_dance_state_t *state, void *user_data) { tap_code16(KC_U); } +static void release_unpress_mark_finished(tap_dance_state_t *state, void *user_data) { + tap_code16(KC_U); + state->finished = true; +} + static void release_finished(tap_dance_state_t *state, void *user_data) { tap_code16(KC_F); } +static void release_reset(tap_dance_state_t *state, void *user_data) { + tap_code16(KC_R); +} + tap_dance_action_t tap_dance_actions[] = { [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS), [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset), [CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN), [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset), - [TD_RELEASE] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(release_press, release_unpress, release_finished, NULL), + [TD_RELEASE] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(release_press, release_unpress, release_finished, release_reset), + [TD_RELEASE_AND_FINISH] = ACTION_TAP_DANCE_FN_ADVANCED_WITH_RELEASE(release_press, release_unpress_mark_finished, release_finished, release_reset), }; // clang-format on diff --git a/tests/tap_dance/examples.h b/tests/tap_dance/examples.h index 868a0c721bbe..6118188dd185 100644 --- a/tests/tap_dance/examples.h +++ b/tests/tap_dance/examples.h @@ -27,6 +27,7 @@ enum { CT_CLN, X_CTL, TD_RELEASE, + TD_RELEASE_AND_FINISH, }; #ifdef __cplusplus diff --git a/tests/tap_dance/test_examples.cpp b/tests/tap_dance/test_examples.cpp index 6786df88be72..7858dab92b9d 100644 --- a/tests/tap_dance/test_examples.cpp +++ b/tests/tap_dance/test_examples.cpp @@ -337,6 +337,8 @@ TEST_F(TapDance, DanceFnAdvancedWithRelease) { EXPECT_REPORT(driver, (KC_F)); EXPECT_EMPTY_REPORT(driver); + EXPECT_REPORT(driver, (KC_R)); + EXPECT_EMPTY_REPORT(driver); idle_for(TAPPING_TERM); run_one_scan_loop(); @@ -363,6 +365,52 @@ TEST_F(TapDance, DanceFnAdvancedWithRelease) { EXPECT_REPORT(driver, (KC_F)); EXPECT_EMPTY_REPORT(driver); + EXPECT_REPORT(driver, (KC_R)); + EXPECT_EMPTY_REPORT(driver); + idle_for(TAPPING_TERM); + run_one_scan_loop(); + + /* Unpress after tapping term has elapsed (key is registered as held) */ + key_rls.press(); + EXPECT_REPORT(driver, (KC_P)); + EXPECT_EMPTY_REPORT(driver); + run_one_scan_loop(); + + EXPECT_REPORT(driver, (KC_F)); + EXPECT_EMPTY_REPORT(driver); + idle_for(TAPPING_TERM); + run_one_scan_loop(); + + key_rls.release(); + EXPECT_REPORT(driver, (KC_U)); + EXPECT_EMPTY_REPORT(driver); + EXPECT_REPORT(driver, (KC_R)); + EXPECT_EMPTY_REPORT(driver); + run_one_scan_loop(); +} + +TEST_F(TapDance, DanceFnAdvancedWithReleaseAndFinish) { + TestDriver driver; + InSequence s; + auto key_rls = KeymapKey(0, 1, 0, TD(TD_RELEASE_AND_FINISH)); + + set_keymap({key_rls}); + + /* Single press and unpress */ + key_rls.press(); + EXPECT_REPORT(driver, (KC_P)); + EXPECT_EMPTY_REPORT(driver); + run_one_scan_loop(); + + key_rls.release(); + EXPECT_REPORT(driver, (KC_U)); + EXPECT_EMPTY_REPORT(driver); + EXPECT_REPORT(driver, (KC_R)); + EXPECT_EMPTY_REPORT(driver); + run_one_scan_loop(); + + // Verify the finished and/or reset functions aren't called + // after the tapping term elapses idle_for(TAPPING_TERM); run_one_scan_loop(); @@ -380,5 +428,7 @@ TEST_F(TapDance, DanceFnAdvancedWithRelease) { key_rls.release(); EXPECT_REPORT(driver, (KC_U)); EXPECT_EMPTY_REPORT(driver); + EXPECT_REPORT(driver, (KC_R)); + EXPECT_EMPTY_REPORT(driver); run_one_scan_loop(); }