From 682fb7108cc999466821698ac035ea40d1797811 Mon Sep 17 00:00:00 2001 From: Dean Scarff Date: Sun, 26 Jul 2020 06:32:12 +1000 Subject: [PATCH] Fix flaky unshifting --- quantum/process_keycode/process_auto_shift.c | 36 +++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index c6c9658fddf8..373e087cf1d8 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c @@ -46,7 +46,7 @@ void autoshift_timer_report(void) { send_string((const char *)display); } -/** \brief Resets the autoshift state and releases the shift key */ +/** \brief Resets the autoshift state */ static void autoshift_flush(uint16_t now) { if (autoshift_flags.in_progress && !autoshift_flags.registered) { // Register the key. @@ -54,17 +54,22 @@ static void autoshift_flush(uint16_t now) { # if TAP_CODE_DELAY > 0 wait_ms(TAP_CODE_DELAY); # endif - } else if (autoshift_flags.holding_shift) { - // Release the shift key if it was simulated. - unregister_code(KC_LSFT); } // Roll the autoshift_time forward for detecting tap-and-hold. autoshift_time = now; autoshift_flags.in_progress = false; - autoshift_flags.holding_shift = false; autoshift_flags.registered = false; } +/** \brief Releases the shift key if it was held by auto-shift */ +static void autoshift_flush_shift(void) { + if (autoshift_flags.holding_shift) { + // Release the shift key if it was simulated. + unregister_code(KC_LSFT); + } + autoshift_flags.holding_shift = false; +} + /** \brief Record the press of an autoshiftable key * * \return Whether the record should be further processed. @@ -74,16 +79,14 @@ static bool autoshift_press(uint16_t keycode, keyrecord_t *record) { return true; } + const uint16_t elapsed = TIMER_DIFF_16(record->event.time, autoshift_time); autoshift_flush(record->event.time); # ifndef AUTO_SHIFT_MODIFIERS - if (get_mods()) { + if (get_mods() ^ (autoshift_flags.holding_shift ? MOD_BIT(KC_LSFT) : 0)) { return true; } # endif - - const uint16_t elapsed = TIMER_DIFF_16(record->event.time, autoshift_time); - # ifndef TAPPING_FORCE_HOLD if (elapsed < TAPPING_TERM && keycode == autoshift_lastkey && !autoshift_flags.lastshifted) { // Allow a tap-then-hold to hold the unshifted key. @@ -93,7 +96,6 @@ static bool autoshift_press(uint16_t keycode, keyrecord_t *record) { # endif // Record the keycode so we can simulate it later. - autoshift_time = record->event.time; autoshift_lastkey = keycode; autoshift_flags.in_progress = true; @@ -146,15 +148,16 @@ static void autoshift_check_record(uint16_t keycode, keyrecord_t *record) { // Process the release of the autoshiftable key. if (keycode == autoshift_lastkey && !record->event.pressed) { + autoshift_flush_shift(); // Time since the initial press was recorded. const uint16_t elapsed = TIMER_DIFF_16(record->event.time, autoshift_time); if (!autoshift_flags.registered && elapsed < autoshift_timeout) { - autoshift_flags.lastshifted = false; // Auto-shiftable key is being released before the shift timeout; // simulate the original press then let the usual processing take // care of the release. register_code(keycode); - autoshift_flags.registered = true; + autoshift_flags.lastshifted = false; + autoshift_flags.registered = true; # if TAP_CODE_DELAY > 0 wait_ms(TAP_CODE_DELAY); # endif @@ -167,9 +170,13 @@ static void autoshift_check_record(uint16_t keycode, keyrecord_t *record) { autoshift_flags.holding_shift = false; } else if (!autoshift_flags.registered) { // If the key isn't registered yet, it means the timeout hasn't - // elapsed, so register the unshifted key. + // elapsed, so register the key without additional shifting. autoshift_flush(0); autoshift_lastkey = KC_NO; + } else { + // The key is registered; flush any shift state for the + // non-autoshiftable key. + autoshift_flush_shift(); } } } @@ -190,17 +197,20 @@ void autoshift_matrix_scan(void) { void autoshift_enable(void) { autoshift_flags.enabled = true; + autoshift_flush_shift(); autoshift_flush(0); } void autoshift_disable(void) { autoshift_flags.enabled = false; + autoshift_flush_shift(); autoshift_flush(0); } void autoshift_toggle(void) { if (autoshift_flags.enabled) { autoshift_flags.enabled = false; + autoshift_flush_shift(); autoshift_flush(0); } else { autoshift_flags.enabled = true;