Browse Source

Ignore the Layer Lock key in Repeat Key and Caps Word. (#25171)

Pascal Getreuer 1 year ago
parent
commit
ea85ace4a9

+ 6 - 1
quantum/process_keycode/process_caps_word.c

@@ -160,8 +160,13 @@ bool process_caps_word(uint16_t keycode, keyrecord_t* record) {
             case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
             case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:
             case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
             case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX:
             case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
             case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:
+#ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys.
             case QK_TRI_LAYER_LOWER ... QK_TRI_LAYER_UPPER:
             case QK_TRI_LAYER_LOWER ... QK_TRI_LAYER_UPPER:
-            // Ignore AltGr.
+#endif                   // TRI_LAYER_ENABLE
+#ifdef LAYER_LOCK_ENABLE // Ignore Layer Lock key.
+            case QK_LAYER_LOCK:
+#endif // LAYER_LOCK_ENABLE
+       // Ignore AltGr.
             case KC_RALT:
             case KC_RALT:
             case OSM(MOD_RALT):
             case OSM(MOD_RALT):
                 return true;
                 return true;

+ 4 - 1
quantum/process_keycode/process_repeat_key.c

@@ -41,7 +41,10 @@ static bool remember_last_key(uint16_t keycode, keyrecord_t* record, uint8_t* re
 #ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys.
 #ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys.
         case QK_TRI_LAYER_LOWER:
         case QK_TRI_LAYER_LOWER:
         case QK_TRI_LAYER_UPPER:
         case QK_TRI_LAYER_UPPER:
-#endif // TRI_LAYER_ENABLE
+#endif                   // TRI_LAYER_ENABLE
+#ifdef LAYER_LOCK_ENABLE // Ignore Layer Lock key.
+        case QK_LAYER_LOCK:
+#endif // LAYER_LOCK_ENABLE
             return false;
             return false;
 
 
             // Ignore hold events on tap-hold keys.
             // Ignore hold events on tap-hold keys.

+ 2 - 0
tests/caps_word/test.mk

@@ -15,5 +15,7 @@
 
 
 CAPS_WORD_ENABLE = yes
 CAPS_WORD_ENABLE = yes
 COMMAND_ENABLE = no
 COMMAND_ENABLE = no
+LAYER_LOCK_ENABLE = yes
 SPACE_CADET_ENABLE = yes
 SPACE_CADET_ENABLE = yes
+TRI_LAYER_ENABLE = yes
 
 

+ 45 - 7
tests/caps_word/test_caps_word.cpp

@@ -156,21 +156,22 @@ TEST_F(CapsWord, IdleTimeout) {
     // Turn on Caps Word and tap "A".
     // Turn on Caps Word and tap "A".
     caps_word_on();
     caps_word_on();
     tap_key(key_a);
     tap_key(key_a);
-
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 
 
+    EXPECT_EMPTY_REPORT(driver);
     idle_for(CAPS_WORD_IDLE_TIMEOUT);
     idle_for(CAPS_WORD_IDLE_TIMEOUT);
     run_one_scan_loop();
     run_one_scan_loop();
+    VERIFY_AND_CLEAR(driver);
 
 
     // Caps Word should be off and mods should be clear.
     // Caps Word should be off and mods should be clear.
     EXPECT_EQ(is_caps_word_on(), false);
     EXPECT_EQ(is_caps_word_on(), false);
     EXPECT_EQ(get_mods() | get_weak_mods(), 0);
     EXPECT_EQ(get_mods() | get_weak_mods(), 0);
 
 
-    EXPECT_EMPTY_REPORT(driver).Times(AnyNumber());
     // Expect unshifted "A".
     // Expect unshifted "A".
     EXPECT_REPORT(driver, (KC_A));
     EXPECT_REPORT(driver, (KC_A));
+    EXPECT_EMPTY_REPORT(driver);
     tap_key(key_a);
     tap_key(key_a);
-
+    run_one_scan_loop();
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 }
 }
 
 
@@ -244,6 +245,7 @@ TEST_F(CapsWord, ShiftsAltGrSymbols) {
     // clang-format off
     // clang-format off
     EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
     EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
                 KeyboardReport(),
                 KeyboardReport(),
+                KeyboardReport(KC_LSFT),
                 KeyboardReport(KC_RALT),
                 KeyboardReport(KC_RALT),
                 KeyboardReport(KC_LSFT, KC_RALT))))
                 KeyboardReport(KC_LSFT, KC_RALT))))
         .Times(AnyNumber());
         .Times(AnyNumber());
@@ -259,6 +261,9 @@ TEST_F(CapsWord, ShiftsAltGrSymbols) {
     tap_key(key_a);
     tap_key(key_a);
     run_one_scan_loop();
     run_one_scan_loop();
     key_altgr.release();
     key_altgr.release();
+    run_one_scan_loop();
+
+    idle_for(CAPS_WORD_IDLE_TIMEOUT);
 
 
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 }
 }
@@ -274,6 +279,7 @@ TEST_F(CapsWord, ShiftsModTapAltGrSymbols) {
     // clang-format off
     // clang-format off
     EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
     EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
                 KeyboardReport(),
                 KeyboardReport(),
+                KeyboardReport(KC_LSFT),
                 KeyboardReport(KC_RALT),
                 KeyboardReport(KC_RALT),
                 KeyboardReport(KC_LSFT, KC_RALT))))
                 KeyboardReport(KC_LSFT, KC_RALT))))
         .Times(AnyNumber());
         .Times(AnyNumber());
@@ -289,8 +295,11 @@ TEST_F(CapsWord, ShiftsModTapAltGrSymbols) {
     tap_key(key_a);
     tap_key(key_a);
     run_one_scan_loop();
     run_one_scan_loop();
     key_altgr_t.release();
     key_altgr_t.release();
-
+    run_one_scan_loop();
     EXPECT_TRUE(is_caps_word_on());
     EXPECT_TRUE(is_caps_word_on());
+
+    idle_for(CAPS_WORD_IDLE_TIMEOUT);
+
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 }
 }
 
 
@@ -535,7 +544,11 @@ TEST_P(CapsWordDoubleTapShift, Activation) {
     // machine at this point. This due to imperfect test isolation which can't
     // machine at this point. This due to imperfect test isolation which can't
     // reset the caps word double shift timer on test case setup.
     // reset the caps word double shift timer on test case setup.
     idle_for(CAPS_WORD_IDLE_TIMEOUT);
     idle_for(CAPS_WORD_IDLE_TIMEOUT);
+
+    EXPECT_REPORT(driver, (KC_ESC));
+    EXPECT_EMPTY_REPORT(driver);
     tap_key(esc);
     tap_key(esc);
+    VERIFY_AND_CLEAR(driver);
 }
 }
 
 
 // Double tap doesn't count if another key is pressed between the taps.
 // Double tap doesn't count if another key is pressed between the taps.
@@ -589,6 +602,7 @@ TEST_P(CapsWordDoubleTapShift, SlowTaps) {
 
 
     EXPECT_EQ(is_caps_word_on(), false); // Caps Word is still off.
     EXPECT_EQ(is_caps_word_on(), false); // Caps Word is still off.
     clear_oneshot_mods();
     clear_oneshot_mods();
+    send_keyboard_report();
 
 
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 }
 }
@@ -626,7 +640,7 @@ TEST_F(CapsWord, IgnoresOSLHold) {
     run_one_scan_loop();
     run_one_scan_loop();
     tap_key(key_b);
     tap_key(key_b);
     key_osl.release();
     key_osl.release();
-    run_one_scan_loop();
+    idle_for(CAPS_WORD_IDLE_TIMEOUT + 1);
 
 
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 }
 }
@@ -645,15 +659,39 @@ TEST_F(CapsWord, IgnoresOSLTap) {
                 KeyboardReport(),
                 KeyboardReport(),
                 KeyboardReport(KC_LSFT))))
                 KeyboardReport(KC_LSFT))))
         .Times(AnyNumber());
         .Times(AnyNumber());
+    // clang-format on
 
 
     EXPECT_REPORT(driver, (KC_LSFT, KC_B));
     EXPECT_REPORT(driver, (KC_LSFT, KC_B));
     caps_word_on();
     caps_word_on();
 
 
     tap_key(key_osl);
     tap_key(key_osl);
     tap_key(key_b);
     tap_key(key_b);
-    run_one_scan_loop();
+    idle_for(CAPS_WORD_IDLE_TIMEOUT);
+
+    VERIFY_AND_CLEAR(driver);
+}
+
+TEST_F(CapsWord, IgnoresLayerLockKey) {
+    TestDriver driver;
+    KeymapKey  key_llock(0, 1, 0, QK_LAYER_LOCK);
+    KeymapKey  key_b(0, 0, 0, KC_B);
+    set_keymap({key_llock, key_b});
+
+    // Allow any number of reports with no keys or only modifiers.
+    // clang-format off
+    EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
+                KeyboardReport(),
+                KeyboardReport(KC_LSFT))))
+        .Times(AnyNumber());
+    // clang-format on
+
+    EXPECT_REPORT(driver, (KC_LSFT, KC_B));
+    caps_word_on();
+
+    tap_key(key_llock);
+    tap_key(key_b);
+    idle_for(CAPS_WORD_IDLE_TIMEOUT);
 
 
     VERIFY_AND_CLEAR(driver);
     VERIFY_AND_CLEAR(driver);
 }
 }
-// clang-format on
 } // namespace
 } // namespace

+ 1 - 0
tests/repeat_key/test.mk

@@ -16,3 +16,4 @@
 REPEAT_KEY_ENABLE = yes
 REPEAT_KEY_ENABLE = yes
 
 
 AUTO_SHIFT_ENABLE = yes
 AUTO_SHIFT_ENABLE = yes
+LAYER_LOCK_ENABLE = yes

+ 33 - 0
tests/repeat_key/test_repeat_key.cpp

@@ -751,4 +751,37 @@ TEST_F(RepeatKey, RepeatKeyInvoke) {
     testing::Mock::VerifyAndClearExpectations(&driver);
     testing::Mock::VerifyAndClearExpectations(&driver);
 }
 }
 
 
+// Check that mods and Layer Lock are not remembered.
+TEST_F(RepeatKey, IgnoredKeys) {
+    TestDriver driver;
+    KeymapKey  regular_key(0, 0, 0, KC_A);
+    KeymapKey  key_repeat(0, 1, 0, QK_REP);
+    KeymapKey  key_lsft(0, 2, 0, KC_LSFT);
+    KeymapKey  key_lctl(0, 3, 0, KC_LCTL);
+    KeymapKey  key_llck(0, 4, 0, QK_LAYER_LOCK);
+    set_keymap({regular_key, key_repeat, key_lsft, key_lctl, key_llck});
+
+    // Allow any number of empty reports.
+    EXPECT_EMPTY_REPORT(driver).Times(AnyNumber());
+    {
+        InSequence seq;
+        EXPECT_REPORT(driver, (KC_A));
+        EXPECT_REPORT(driver, (KC_LSFT));
+        EXPECT_REPORT(driver, (KC_LCTL));
+        EXPECT_REPORT(driver, (KC_A));
+        EXPECT_REPORT(driver, (KC_A));
+    }
+
+    tap_key(regular_key); // Taps the KC_A key.
+
+    // Tap Shift, Ctrl, and Layer Lock keys, which should not be remembered.
+    tap_keys(key_lsft, key_lctl, key_llck);
+    EXPECT_KEYCODE_EQ(get_last_keycode(), KC_A);
+
+    // Tapping the Repeat Key should still reproduce KC_A.
+    tap_keys(key_repeat, key_repeat);
+
+    testing::Mock::VerifyAndClearExpectations(&driver);
+}
+
 } // namespace
 } // namespace