test_tap_hold.cpp (19219B)
1 // Copyright 2025 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "keyboard_report_util.hpp" 16 #include "keycode.h" 17 #include "test_common.hpp" 18 #include "action_tapping.h" 19 #include "test_fixture.hpp" 20 #include "test_keymap_key.hpp" 21 22 using testing::_; 23 using testing::InSequence; 24 25 extern "C" bool get_speculative_hold(uint16_t keycode, keyrecord_t *record) { 26 return true; 27 } 28 29 class SpeculativeHoldRetroTappingTest : public TestFixture {}; 30 31 TEST_F(SpeculativeHoldRetroTappingTest, roll_regular_to_lgui_mod) { 32 TestDriver driver; 33 InSequence s; 34 auto mod_tap_key = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 35 auto regular_key = KeymapKey(0, 2, 0, KC_B); 36 37 set_keymap({mod_tap_key, regular_key}); 38 39 EXPECT_REPORT(driver, (KC_B)); 40 regular_key.press(); 41 run_one_scan_loop(); 42 VERIFY_AND_CLEAR(driver); 43 44 EXPECT_REPORT(driver, (KC_B, KC_LGUI)); 45 mod_tap_key.press(); 46 idle_for(TAPPING_TERM + 1); 47 VERIFY_AND_CLEAR(driver); 48 49 EXPECT_REPORT(driver, (KC_LGUI)); 50 regular_key.release(); 51 run_one_scan_loop(); 52 VERIFY_AND_CLEAR(driver); 53 54 // Neutralizer invoked by Speculative Hold. 55 EXPECT_REPORT(driver, (KC_LGUI, DUMMY_MOD_NEUTRALIZER_KEYCODE)); 56 EXPECT_REPORT(driver, (KC_LGUI)); 57 EXPECT_EMPTY_REPORT(driver); 58 EXPECT_REPORT(driver, (KC_P)); 59 EXPECT_EMPTY_REPORT(driver); 60 mod_tap_key.release(); 61 run_one_scan_loop(); 62 VERIFY_AND_CLEAR(driver); 63 } 64 65 TEST_F(SpeculativeHoldRetroTappingTest, regular_to_mod_under_tap_term) { 66 TestDriver driver; 67 InSequence s; 68 auto mod_tap_key = KeymapKey(0, 1, 0, LSFT_T(KC_A)); 69 auto regular_key = KeymapKey(0, 2, 0, KC_B); 70 71 set_keymap({mod_tap_key, regular_key}); 72 73 EXPECT_REPORT(driver, (KC_B)); 74 regular_key.press(); 75 run_one_scan_loop(); 76 VERIFY_AND_CLEAR(driver); 77 78 EXPECT_REPORT(driver, (KC_B, KC_LSFT)); 79 mod_tap_key.press(); 80 run_one_scan_loop(); 81 VERIFY_AND_CLEAR(driver); 82 83 EXPECT_REPORT(driver, (KC_LSFT)); 84 regular_key.release(); 85 run_one_scan_loop(); 86 VERIFY_AND_CLEAR(driver); 87 88 EXPECT_EMPTY_REPORT(driver); 89 EXPECT_REPORT(driver, (KC_A)); 90 EXPECT_EMPTY_REPORT(driver); 91 mod_tap_key.release(); 92 run_one_scan_loop(); 93 VERIFY_AND_CLEAR(driver); 94 } 95 96 TEST_F(SpeculativeHoldRetroTappingTest, mod_under_tap_term_to_regular) { 97 TestDriver driver; 98 InSequence s; 99 auto mod_tap_key = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 100 auto regular_key = KeymapKey(0, 2, 0, KC_B); 101 102 set_keymap({mod_tap_key, regular_key}); 103 104 EXPECT_REPORT(driver, (KC_LGUI)); 105 mod_tap_key.press(); 106 run_one_scan_loop(); 107 VERIFY_AND_CLEAR(driver); 108 109 EXPECT_NO_REPORT(driver); 110 regular_key.press(); 111 run_one_scan_loop(); 112 VERIFY_AND_CLEAR(driver); 113 114 // Neutralizer invoked by Speculative Hold. 115 EXPECT_REPORT(driver, (KC_LGUI, DUMMY_MOD_NEUTRALIZER_KEYCODE)); 116 EXPECT_REPORT(driver, (KC_LGUI)); 117 EXPECT_EMPTY_REPORT(driver); 118 EXPECT_REPORT(driver, (KC_P)); 119 EXPECT_REPORT(driver, (KC_B, KC_P)); 120 EXPECT_REPORT(driver, (KC_B)); 121 mod_tap_key.release(); 122 run_one_scan_loop(); 123 VERIFY_AND_CLEAR(driver); 124 125 EXPECT_EMPTY_REPORT(driver); 126 regular_key.release(); 127 run_one_scan_loop(); 128 VERIFY_AND_CLEAR(driver); 129 } 130 131 TEST_F(SpeculativeHoldRetroTappingTest, mod_over_tap_term_to_regular) { 132 TestDriver driver; 133 InSequence s; 134 auto mod_tap_key = KeymapKey(0, 1, 0, LSFT_T(KC_A)); 135 auto regular_key = KeymapKey(0, 2, 0, KC_B); 136 137 set_keymap({mod_tap_key, regular_key}); 138 139 EXPECT_REPORT(driver, (KC_LSFT)); 140 mod_tap_key.press(); 141 idle_for(TAPPING_TERM); 142 run_one_scan_loop(); 143 VERIFY_AND_CLEAR(driver); 144 145 EXPECT_REPORT(driver, (KC_LSFT, KC_B)); 146 regular_key.press(); 147 run_one_scan_loop(); 148 VERIFY_AND_CLEAR(driver); 149 150 EXPECT_REPORT(driver, (KC_B)); 151 mod_tap_key.release(); 152 run_one_scan_loop(); 153 VERIFY_AND_CLEAR(driver); 154 155 EXPECT_EMPTY_REPORT(driver); 156 regular_key.release(); 157 run_one_scan_loop(); 158 VERIFY_AND_CLEAR(driver); 159 } 160 161 TEST_F(SpeculativeHoldRetroTappingTest, mod_under_tap_term_to_mod_under_tap_term) { 162 TestDriver driver; 163 InSequence s; 164 auto mod_tap_lgui = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 165 auto mod_tap_lsft = KeymapKey(0, 2, 0, LSFT_T(KC_A)); 166 167 set_keymap({mod_tap_lgui, mod_tap_lsft}); 168 169 EXPECT_REPORT(driver, (KC_LSFT)); 170 mod_tap_lsft.press(); 171 run_one_scan_loop(); 172 VERIFY_AND_CLEAR(driver); 173 174 EXPECT_REPORT(driver, (KC_LSFT, KC_LGUI)); 175 mod_tap_lgui.press(); 176 run_one_scan_loop(); 177 VERIFY_AND_CLEAR(driver); 178 179 EXPECT_EMPTY_REPORT(driver); 180 EXPECT_REPORT(driver, (KC_A)); 181 EXPECT_EMPTY_REPORT(driver); 182 mod_tap_lsft.release(); 183 run_one_scan_loop(); 184 VERIFY_AND_CLEAR(driver); 185 186 EXPECT_REPORT(driver, (KC_P)); 187 EXPECT_EMPTY_REPORT(driver); 188 mod_tap_lgui.release(); 189 run_one_scan_loop(); 190 VERIFY_AND_CLEAR(driver); 191 } 192 193 TEST_F(SpeculativeHoldRetroTappingTest, mod_over_tap_term_to_mod_under_tap_term) { 194 TestDriver driver; 195 InSequence s; 196 auto mod_tap_lgui = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 197 auto mod_tap_lsft = KeymapKey(0, 2, 0, LSFT_T(KC_A)); 198 199 set_keymap({mod_tap_lgui, mod_tap_lsft}); 200 201 EXPECT_REPORT(driver, (KC_LSFT)); 202 mod_tap_lsft.press(); 203 idle_for(TAPPING_TERM); 204 run_one_scan_loop(); 205 VERIFY_AND_CLEAR(driver); 206 207 EXPECT_REPORT(driver, (KC_LSFT, KC_LGUI)); 208 mod_tap_lgui.press(); 209 run_one_scan_loop(); 210 VERIFY_AND_CLEAR(driver); 211 212 EXPECT_NO_REPORT(driver); 213 mod_tap_lsft.release(); 214 run_one_scan_loop(); 215 VERIFY_AND_CLEAR(driver); 216 217 EXPECT_REPORT(driver, (KC_LSFT)); 218 EXPECT_REPORT(driver, (KC_LSFT, KC_P)); 219 EXPECT_REPORT(driver, (KC_P)); 220 EXPECT_EMPTY_REPORT(driver); 221 mod_tap_lgui.release(); 222 run_one_scan_loop(); 223 VERIFY_AND_CLEAR(driver); 224 } 225 226 TEST_F(SpeculativeHoldRetroTappingTest, mod_under_tap_term_to_mod_over_tap_term) { 227 TestDriver driver; 228 InSequence s; 229 auto mod_tap_lgui = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 230 auto mod_tap_lsft = KeymapKey(0, 2, 0, LSFT_T(KC_A)); 231 232 set_keymap({mod_tap_lgui, mod_tap_lsft}); 233 234 EXPECT_REPORT(driver, (KC_LSFT)); 235 mod_tap_lsft.press(); 236 run_one_scan_loop(); 237 VERIFY_AND_CLEAR(driver); 238 239 EXPECT_REPORT(driver, (KC_LSFT, KC_LGUI)); 240 mod_tap_lgui.press(); 241 idle_for(TAPPING_TERM); 242 run_one_scan_loop(); 243 VERIFY_AND_CLEAR(driver); 244 245 EXPECT_REPORT(driver, (KC_LGUI)); 246 mod_tap_lsft.release(); 247 run_one_scan_loop(); 248 VERIFY_AND_CLEAR(driver); 249 250 // Neutralizer invoked by Retro Tapping. 251 EXPECT_REPORT(driver, (KC_LGUI, DUMMY_MOD_NEUTRALIZER_KEYCODE)); 252 EXPECT_REPORT(driver, (KC_LGUI)); 253 EXPECT_EMPTY_REPORT(driver); 254 EXPECT_REPORT(driver, (KC_LSFT)); 255 EXPECT_REPORT(driver, (KC_P, KC_LSFT)); 256 EXPECT_REPORT(driver, (KC_LSFT)); 257 EXPECT_EMPTY_REPORT(driver); 258 mod_tap_lgui.release(); 259 run_one_scan_loop(); 260 VERIFY_AND_CLEAR(driver); 261 } 262 263 TEST_F(SpeculativeHoldRetroTappingTest, mod_under_tap_term_to_mod_over_tap_term_offset) { 264 TestDriver driver; 265 InSequence s; 266 auto mod_tap_lgui = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 267 auto mod_tap_lsft = KeymapKey(0, 2, 0, LSFT_T(KC_A)); 268 269 set_keymap({mod_tap_lgui, mod_tap_lsft}); 270 271 EXPECT_REPORT(driver, (KC_LSFT)); 272 mod_tap_lsft.press(); 273 run_one_scan_loop(); 274 VERIFY_AND_CLEAR(driver); 275 276 EXPECT_REPORT(driver, (KC_LSFT, KC_LGUI)); 277 mod_tap_lgui.press(); 278 run_one_scan_loop(); 279 VERIFY_AND_CLEAR(driver); 280 281 EXPECT_EMPTY_REPORT(driver); 282 EXPECT_REPORT(driver, (KC_A)); 283 EXPECT_EMPTY_REPORT(driver); 284 mod_tap_lsft.release(); 285 run_one_scan_loop(); 286 VERIFY_AND_CLEAR(driver); 287 288 EXPECT_REPORT(driver, (KC_LGUI)); 289 // Neutralizer invoked by Retro Tapping. 290 EXPECT_REPORT(driver, (KC_LGUI, DUMMY_MOD_NEUTRALIZER_KEYCODE)); 291 EXPECT_REPORT(driver, (KC_LGUI)); 292 EXPECT_EMPTY_REPORT(driver); 293 EXPECT_REPORT(driver, (KC_P)); 294 EXPECT_EMPTY_REPORT(driver); 295 idle_for(TAPPING_TERM); 296 mod_tap_lgui.release(); 297 run_one_scan_loop(); 298 VERIFY_AND_CLEAR(driver); 299 } 300 301 TEST_F(SpeculativeHoldRetroTappingTest, mod_over_tap_term_to_mod_over_tap_term) { 302 TestDriver driver; 303 InSequence s; 304 auto mod_tap_lgui = KeymapKey(0, 1, 0, LGUI_T(KC_P)); 305 auto mod_tap_lsft = KeymapKey(0, 2, 0, LSFT_T(KC_A)); 306 307 set_keymap({mod_tap_lgui, mod_tap_lsft}); 308 309 EXPECT_REPORT(driver, (KC_LSFT)); 310 mod_tap_lsft.press(); 311 idle_for(TAPPING_TERM); 312 run_one_scan_loop(); 313 VERIFY_AND_CLEAR(driver); 314 315 EXPECT_REPORT(driver, (KC_LSFT, KC_LGUI)); 316 mod_tap_lgui.press(); 317 idle_for(TAPPING_TERM); 318 run_one_scan_loop(); 319 VERIFY_AND_CLEAR(driver); 320 321 EXPECT_REPORT(driver, (KC_LGUI)); 322 mod_tap_lsft.release(); 323 run_one_scan_loop(); 324 VERIFY_AND_CLEAR(driver); 325 326 // Neutralizer invoked by Retro Tapping. 327 EXPECT_REPORT(driver, (KC_LGUI, DUMMY_MOD_NEUTRALIZER_KEYCODE)); 328 EXPECT_REPORT(driver, (KC_LGUI)); 329 EXPECT_EMPTY_REPORT(driver); 330 EXPECT_REPORT(driver, (KC_LSFT)); 331 EXPECT_REPORT(driver, (KC_P, KC_LSFT)); 332 EXPECT_REPORT(driver, (KC_LSFT)); 333 EXPECT_EMPTY_REPORT(driver); 334 mod_tap_lgui.release(); 335 run_one_scan_loop(); 336 VERIFY_AND_CLEAR(driver); 337 } 338 339 TEST_F(SpeculativeHoldRetroTappingTest, mod_to_mod_to_mod) { 340 TestDriver driver; 341 InSequence s; 342 auto mod_tap_lalt = KeymapKey(0, 1, 0, LALT_T(KC_R)); 343 auto mod_tap_lsft = KeymapKey(0, 2, 0, SFT_T(KC_A)); 344 auto mod_tap_lctl = KeymapKey(0, 3, 0, LCTL_T(KC_C)); 345 346 set_keymap({mod_tap_lalt, mod_tap_lsft, mod_tap_lctl}); 347 348 EXPECT_REPORT(driver, (KC_LALT)); 349 mod_tap_lalt.press(); 350 idle_for(TAPPING_TERM); 351 run_one_scan_loop(); 352 VERIFY_AND_CLEAR(driver); 353 354 EXPECT_REPORT(driver, (KC_LSFT, KC_LALT)); 355 mod_tap_lsft.press(); 356 idle_for(TAPPING_TERM); 357 run_one_scan_loop(); 358 VERIFY_AND_CLEAR(driver); 359 360 EXPECT_REPORT(driver, (KC_LSFT)); 361 mod_tap_lalt.release(); 362 run_one_scan_loop(); 363 VERIFY_AND_CLEAR(driver); 364 365 EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT)); 366 mod_tap_lctl.press(); 367 idle_for(TAPPING_TERM); 368 run_one_scan_loop(); 369 VERIFY_AND_CLEAR(driver); 370 371 EXPECT_REPORT(driver, (KC_LCTL)); 372 mod_tap_lsft.release(); 373 run_one_scan_loop(); 374 VERIFY_AND_CLEAR(driver); 375 376 EXPECT_EMPTY_REPORT(driver); 377 EXPECT_REPORT(driver, (KC_LSFT)); 378 EXPECT_REPORT(driver, (KC_C, KC_LSFT)); 379 EXPECT_REPORT(driver, (KC_LSFT)); 380 EXPECT_EMPTY_REPORT(driver); 381 mod_tap_lctl.release(); 382 run_one_scan_loop(); 383 VERIFY_AND_CLEAR(driver); 384 } 385 386 // Test with layer tap and speculative mod tap keys on the same layer, rolling 387 // from LT to MT key: 388 // "LT down, MT down, (wait out tapping term), LT up, MT up." 389 TEST_F(SpeculativeHoldRetroTappingTest, lt_mt_same_layer_roll) { 390 TestDriver driver; 391 InSequence s; 392 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 393 auto mod_tap_key = KeymapKey(0, 1, 0, LCTL_T(KC_B)); 394 auto regular_key = KeymapKey(1, 1, 0, KC_C); 395 396 set_keymap({layer_tap_key, mod_tap_key, regular_key}); 397 398 // Press layer tap key. 399 EXPECT_NO_REPORT(driver); 400 layer_tap_key.press(); 401 run_one_scan_loop(); 402 VERIFY_AND_CLEAR(driver); 403 404 // Press mod-tap key, after flow tap term but within tapping term. The 405 // speculative mod activates. 406 EXPECT_REPORT(driver, (KC_LCTL)); 407 mod_tap_key.press(); 408 run_one_scan_loop(); 409 VERIFY_AND_CLEAR(driver); 410 411 // Wait for the layer tap key to settle. 412 EXPECT_EMPTY_REPORT(driver); 413 EXPECT_REPORT(driver, (KC_C)); 414 idle_for(TAPPING_TERM); 415 VERIFY_AND_CLEAR(driver); 416 417 // Release keys. 418 EXPECT_EMPTY_REPORT(driver); 419 layer_tap_key.release(); 420 run_one_scan_loop(); 421 mod_tap_key.release(); 422 run_one_scan_loop(); 423 VERIFY_AND_CLEAR(driver); 424 // All mods are released. 425 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 426 } 427 428 // Test with layer tap and speculative mod tap keys on the same layer, trying a 429 // nested press: 430 // "LT down, MT down, (wait out tapping term), MT up, LT up." 431 TEST_F(SpeculativeHoldRetroTappingTest, lt_mt_same_layer_nested_press) { 432 TestDriver driver; 433 InSequence s; 434 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 435 auto mod_tap_key = KeymapKey(0, 1, 0, LCTL_T(KC_B)); 436 auto regular_key = KeymapKey(1, 1, 0, KC_C); 437 438 set_keymap({layer_tap_key, mod_tap_key, regular_key}); 439 440 EXPECT_NO_REPORT(driver); 441 layer_tap_key.press(); 442 run_one_scan_loop(); 443 VERIFY_AND_CLEAR(driver); 444 445 EXPECT_REPORT(driver, (KC_LCTL)); 446 mod_tap_key.press(); 447 run_one_scan_loop(); 448 VERIFY_AND_CLEAR(driver); 449 450 EXPECT_EMPTY_REPORT(driver); 451 EXPECT_REPORT(driver, (KC_C)); 452 idle_for(TAPPING_TERM); 453 VERIFY_AND_CLEAR(driver); 454 455 // Release keys: MT first, LT second. 456 EXPECT_EMPTY_REPORT(driver); 457 mod_tap_key.release(); 458 run_one_scan_loop(); 459 layer_tap_key.release(); 460 run_one_scan_loop(); 461 VERIFY_AND_CLEAR(driver); 462 // All mods are released. 463 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 464 } 465 466 // Test with layer tap and speculative mod tap keys on the same layer, trying a 467 // nested press with the MT first: 468 // "MT down, LT down, (wait out tapping term), LT up, MT up." 469 TEST_F(SpeculativeHoldRetroTappingTest, mt_lt_same_layer_nested_press) { 470 TestDriver driver; 471 InSequence s; 472 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 473 auto mod_tap_key = KeymapKey(0, 1, 0, LCTL_T(KC_B)); 474 auto regular_key = KeymapKey(1, 1, 0, KC_C); 475 476 set_keymap({layer_tap_key, mod_tap_key, regular_key}); 477 478 EXPECT_REPORT(driver, (KC_LCTL)); 479 mod_tap_key.press(); 480 run_one_scan_loop(); 481 482 EXPECT_NO_REPORT(driver); 483 layer_tap_key.press(); 484 idle_for(TAPPING_TERM + 1); 485 VERIFY_AND_CLEAR(driver); 486 487 EXPECT_REPORT(driver, (KC_LCTL, KC_A)); 488 EXPECT_REPORT(driver, (KC_LCTL)); 489 EXPECT_EMPTY_REPORT(driver); 490 layer_tap_key.release(); 491 run_one_scan_loop(); 492 mod_tap_key.release(); 493 run_one_scan_loop(); 494 VERIFY_AND_CLEAR(driver); 495 // All mods are released. 496 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 497 } 498 499 // Test with a speculative mod tap key reached by a layer tap key, rolling from 500 // LT to MT key: 501 // "LT down, MT down, (wait out tapping term), LT up, MT up." 502 TEST_F(SpeculativeHoldRetroTappingTest, lt_mt_different_layer_roll) { 503 TestDriver driver; 504 InSequence s; 505 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 506 auto regular_key = KeymapKey(0, 1, 0, KC_B); 507 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 508 auto mod_tap_key = KeymapKey(1, 1, 0, LCTL_T(KC_C)); 509 510 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 511 512 // Press layer tap key. 513 EXPECT_NO_REPORT(driver); 514 layer_tap_key.press(); 515 run_one_scan_loop(); 516 // Press mod tap key. 517 mod_tap_key.press(); 518 idle_for(TAPPING_TERM); 519 VERIFY_AND_CLEAR(driver); 520 521 // Release keys. 522 EXPECT_REPORT(driver, (KC_LCTL)); 523 layer_tap_key.release(); 524 idle_for(TAPPING_TERM); 525 VERIFY_AND_CLEAR(driver); 526 527 EXPECT_EMPTY_REPORT(driver); 528 mod_tap_key.release(); 529 run_one_scan_loop(); 530 VERIFY_AND_CLEAR(driver); 531 // All mods are released. 532 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 533 } 534 535 // Test with a speculative mod tap key reached by a layer tap key, slowly 536 // rolling from LT to MT key: 537 // "LT down, (wait), MT down, (wait), LT up, MT up." 538 TEST_F(SpeculativeHoldRetroTappingTest, lt_mt_different_layer_slow_roll) { 539 TestDriver driver; 540 InSequence s; 541 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 542 auto regular_key = KeymapKey(0, 1, 0, KC_B); 543 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 544 auto mod_tap_key = KeymapKey(1, 1, 0, LCTL_T(KC_C)); 545 546 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 547 548 EXPECT_REPORT(driver, (KC_LCTL)); 549 layer_tap_key.press(); 550 idle_for(TAPPING_TERM + 1); 551 mod_tap_key.press(); 552 run_one_scan_loop(); 553 VERIFY_AND_CLEAR(driver); 554 555 EXPECT_EMPTY_REPORT(driver); 556 EXPECT_REPORT(driver, (KC_B)); 557 EXPECT_EMPTY_REPORT(driver); 558 layer_tap_key.release(); 559 run_one_scan_loop(); 560 mod_tap_key.release(); 561 run_one_scan_loop(); 562 VERIFY_AND_CLEAR(driver); 563 // All mods are released. 564 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 565 } 566 567 // Test with a speculative mod tap key reached by a layer tap key, trying a 568 // nested press: 569 // "LT down, MT down, (wait out tapping term), MT up, LT up." 570 TEST_F(SpeculativeHoldRetroTappingTest, lt_mt_different_layer_nested_press) { 571 TestDriver driver; 572 InSequence s; 573 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 574 auto regular_key = KeymapKey(0, 1, 0, KC_B); 575 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 576 auto mod_tap_key = KeymapKey(1, 1, 0, LCTL_T(KC_C)); 577 578 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 579 580 EXPECT_NO_REPORT(driver); 581 layer_tap_key.press(); 582 run_one_scan_loop(); 583 mod_tap_key.press(); 584 idle_for(TAPPING_TERM); 585 VERIFY_AND_CLEAR(driver); 586 587 // Release keys. 588 EXPECT_REPORT(driver, (KC_LCTL)); 589 EXPECT_EMPTY_REPORT(driver); 590 mod_tap_key.release(); 591 run_one_scan_loop(); 592 layer_tap_key.release(); 593 run_one_scan_loop(); 594 VERIFY_AND_CLEAR(driver); 595 // All mods are released. 596 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 597 } 598 599 // Test with a speculative mod tap key reached by a layer tap key, slowly making 600 // a nested press from LT to MT key: 601 // "LT down, (wait), MT down, MT up, LT up." 602 TEST_F(SpeculativeHoldRetroTappingTest, lt_mt_different_layer_slow_nested_press) { 603 TestDriver driver; 604 InSequence s; 605 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 606 auto regular_key = KeymapKey(0, 1, 0, KC_B); 607 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 608 auto mod_tap_key = KeymapKey(1, 1, 0, LCTL_T(KC_C)); 609 610 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 611 612 EXPECT_REPORT(driver, (KC_LCTL)); 613 layer_tap_key.press(); 614 idle_for(TAPPING_TERM + 1); 615 mod_tap_key.press(); 616 run_one_scan_loop(); 617 VERIFY_AND_CLEAR(driver); 618 619 EXPECT_EMPTY_REPORT(driver); 620 EXPECT_REPORT(driver, (KC_C)); 621 EXPECT_EMPTY_REPORT(driver); 622 mod_tap_key.release(); 623 run_one_scan_loop(); 624 layer_tap_key.release(); 625 run_one_scan_loop(); 626 VERIFY_AND_CLEAR(driver); 627 // All mods are released. 628 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 629 }