1
0
Fork 0

[Bug][Core] Fix for Chordal Hold: stuck mods when mod-taps are pressed in a stuttered sequence. (#24878)

This commit is contained in:
Pascal Getreuer 2025-01-29 11:17:54 -08:00 committed by GitHub
parent 08dcc8856f
commit 9d799aff97
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 88 additions and 2 deletions

View file

@ -736,7 +736,7 @@ static void waiting_buffer_chordal_hold_taps_until(keypos_t key) {
while (waiting_buffer_tail != waiting_buffer_head) { while (waiting_buffer_tail != waiting_buffer_head) {
keyrecord_t *record = &waiting_buffer[waiting_buffer_tail]; keyrecord_t *record = &waiting_buffer[waiting_buffer_tail];
ac_dprintf("waiting_buffer_chordal_hold_taps_until: processing [%u]\n", waiting_buffer_tail); ac_dprintf("waiting_buffer_chordal_hold_taps_until: processing [%u]\n", waiting_buffer_tail);
if (is_tap_record(record)) { if (record->event.pressed && is_tap_record(record)) {
record->tap.count = 1; record->tap.count = 1;
registered_taps_add(record->event.key); registered_taps_add(record->event.key);
} }

View file

@ -805,3 +805,46 @@ TEST_F(ChordalHoldHoldOnOtherKeyPress, roll_layer_tap_key_with_regular_key) {
run_one_scan_loop(); run_one_scan_loop();
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
} }
TEST_F(ChordalHoldHoldOnOtherKeyPress, two_mod_tap_keys_stuttered_press) {
TestDriver driver;
InSequence s;
auto mod_tap_key1 = KeymapKey(0, 1, 0, LSFT_T(KC_A));
auto mod_tap_key2 = KeymapKey(0, 2, 0, LCTL_T(KC_B));
set_keymap({mod_tap_key1, mod_tap_key2});
// Hold first mod-tap key until the tapping term.
EXPECT_REPORT(driver, (KC_LSFT));
mod_tap_key1.press();
idle_for(TAPPING_TERM + 1);
VERIFY_AND_CLEAR(driver);
// Press the second mod-tap key, then quickly release and press the first.
EXPECT_NO_REPORT(driver);
mod_tap_key2.press();
run_one_scan_loop();
mod_tap_key1.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
EXPECT_REPORT(driver, (KC_LSFT, KC_B));
EXPECT_REPORT(driver, (KC_B));
EXPECT_REPORT(driver, (KC_B, KC_A));
mod_tap_key1.press();
run_one_scan_loop();
EXPECT_EQ(get_mods(), 0); // Verify that Shift was released.
VERIFY_AND_CLEAR(driver);
// Release both keys.
EXPECT_REPORT(driver, (KC_A));
mod_tap_key2.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
EXPECT_EMPTY_REPORT(driver);
mod_tap_key1.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
}

View file

@ -877,6 +877,7 @@ TEST_F(ChordalHoldPermissiveHold, roll_layer_tap_key_with_regular_key) {
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
// Press regular key. // Press regular key.
EXPECT_NO_REPORT(driver);
regular_key.press(); regular_key.press();
run_one_scan_loop(); run_one_scan_loop();
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
@ -885,7 +886,6 @@ TEST_F(ChordalHoldPermissiveHold, roll_layer_tap_key_with_regular_key) {
EXPECT_REPORT(driver, (KC_P)); EXPECT_REPORT(driver, (KC_P));
EXPECT_REPORT(driver, (KC_P, KC_A)); EXPECT_REPORT(driver, (KC_P, KC_A));
EXPECT_REPORT(driver, (KC_A)); EXPECT_REPORT(driver, (KC_A));
EXPECT_NO_REPORT(driver);
layer_tap_hold_key.release(); layer_tap_hold_key.release();
run_one_scan_loop(); run_one_scan_loop();
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
@ -896,3 +896,46 @@ TEST_F(ChordalHoldPermissiveHold, roll_layer_tap_key_with_regular_key) {
run_one_scan_loop(); run_one_scan_loop();
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
} }
TEST_F(ChordalHoldPermissiveHold, two_mod_tap_keys_stuttered_press) {
TestDriver driver;
InSequence s;
auto mod_tap_key1 = KeymapKey(0, 1, 0, LSFT_T(KC_A));
auto mod_tap_key2 = KeymapKey(0, 2, 0, LCTL_T(KC_B));
set_keymap({mod_tap_key1, mod_tap_key2});
// Hold first mod-tap key until the tapping term.
EXPECT_REPORT(driver, (KC_LSFT));
mod_tap_key1.press();
idle_for(TAPPING_TERM + 1);
VERIFY_AND_CLEAR(driver);
// Press the second mod-tap key, then quickly release and press the first.
EXPECT_NO_REPORT(driver);
mod_tap_key2.press();
run_one_scan_loop();
mod_tap_key1.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
EXPECT_REPORT(driver, (KC_LSFT, KC_B));
EXPECT_REPORT(driver, (KC_B));
EXPECT_REPORT(driver, (KC_B, KC_A));
mod_tap_key1.press();
run_one_scan_loop();
EXPECT_EQ(get_mods(), 0); // Verify that Shift was released.
VERIFY_AND_CLEAR(driver);
// Release both keys.
EXPECT_REPORT(driver, (KC_A));
mod_tap_key2.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
EXPECT_EMPTY_REPORT(driver);
mod_tap_key1.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
}