test_tap_hold.cpp (16923B)
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 <functional> 16 17 #include "keyboard_report_util.hpp" 18 #include "keycode.h" 19 #include "test_common.hpp" 20 #include "action_tapping.h" 21 #include "test_fixture.hpp" 22 #include "test_keymap_key.hpp" 23 24 using testing::_; 25 using testing::AnyNumber; 26 using testing::InSequence; 27 28 namespace { 29 30 bool process_record_user_default(uint16_t keycode, keyrecord_t *record) { 31 return true; 32 } 33 34 // Indirection so that process_record_user() can be 35 // replaced with other functions in the test cases below. 36 std::function<bool(uint16_t, keyrecord_t *)> process_record_user_fun = process_record_user_default; 37 38 extern "C" bool process_record_user(uint16_t keycode, keyrecord_t *record) { 39 return process_record_user_fun(keycode, record); 40 } 41 42 class SpeculativeHoldDefault : public TestFixture { 43 public: 44 void SetUp() override { 45 process_record_user_fun = process_record_user_default; 46 } 47 }; 48 49 TEST_F(SpeculativeHoldDefault, get_speculative_hold) { 50 keyrecord_t record = {}; 51 52 // With the default definition of get_speculative_hold(), Speculative Hold 53 // is enabled for Ctrl and Shift. 54 EXPECT_TRUE(get_speculative_hold(MT(MOD_LCTL, KC_NO), &record)); 55 EXPECT_TRUE(get_speculative_hold(MT(MOD_LSFT, KC_NO), &record)); 56 EXPECT_TRUE(get_speculative_hold(MT(MOD_LCTL | MOD_LSFT, KC_NO), &record)); 57 EXPECT_TRUE(get_speculative_hold(MT(MOD_RCTL, KC_NO), &record)); 58 EXPECT_TRUE(get_speculative_hold(MT(MOD_RSFT, KC_NO), &record)); 59 EXPECT_TRUE(get_speculative_hold(MT(MOD_RCTL | MOD_RSFT, KC_NO), &record)); 60 61 EXPECT_FALSE(get_speculative_hold(MT(MOD_LALT, KC_NO), &record)); 62 EXPECT_FALSE(get_speculative_hold(MT(MOD_LGUI, KC_NO), &record)); 63 EXPECT_FALSE(get_speculative_hold(MT(MOD_RALT, KC_NO), &record)); 64 EXPECT_FALSE(get_speculative_hold(MT(MOD_RGUI, KC_NO), &record)); 65 EXPECT_FALSE(get_speculative_hold(MT(MOD_MEH, KC_NO), &record)); 66 EXPECT_FALSE(get_speculative_hold(MT(MOD_HYPR, KC_NO), &record)); 67 } 68 69 TEST_F(SpeculativeHoldDefault, tap_mod_tap) { 70 TestDriver driver; 71 InSequence s; 72 static int process_record_user_calls = 0; 73 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 74 75 set_keymap({mod_tap_key}); 76 77 process_record_user_fun = [](uint16_t keycode, keyrecord_t *record) { 78 ++process_record_user_calls; 79 return true; 80 }; 81 82 // Press mod-tap-hold key. Mod is held speculatively. 83 EXPECT_REPORT(driver, (KC_LSFT)); 84 mod_tap_key.press(); 85 idle_for(10); 86 VERIFY_AND_CLEAR(driver); 87 EXPECT_EQ(get_speculative_mods(), MOD_BIT_LSHIFT); 88 // Speculative mod holds and releases are made directly, bypassing regular 89 // event processing. No calls have been made yet to process_record_user(). 90 EXPECT_EQ(process_record_user_calls, 0); 91 92 // Release mod-tap-hold key. 93 EXPECT_EMPTY_REPORT(driver); // Speculative mod canceled. 94 EXPECT_REPORT(driver, (KC_P)); 95 EXPECT_EMPTY_REPORT(driver); 96 mod_tap_key.release(); 97 run_one_scan_loop(); 98 VERIFY_AND_CLEAR(driver); 99 // All mods are released. 100 EXPECT_EQ(get_speculative_mods(), 0); 101 EXPECT_EQ(get_mods(), 0); 102 // Two calls have now been made, for pressing and releasing KC_P. 103 EXPECT_EQ(process_record_user_calls, 2); 104 105 // Idle for tapping term of mod tap hold key. 106 idle_for(TAPPING_TERM - 10); 107 VERIFY_AND_CLEAR(driver); 108 } 109 110 TEST_F(SpeculativeHoldDefault, key_overrides) { 111 TestDriver driver; 112 InSequence s; 113 auto mod_tap_key = KeymapKey(0, 1, 0, LSFT_T(KC_A)); 114 auto esc_key = KeymapKey(0, 3, 0, KC_ESC); 115 116 set_keymap({mod_tap_key, esc_key}); 117 118 // Press mod-tap Shift key. 119 EXPECT_REPORT(driver, (KC_LSFT)); 120 mod_tap_key.press(); 121 run_one_scan_loop(); 122 VERIFY_AND_CLEAR(driver); 123 124 // Press Esc key. 125 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 126 EXPECT_REPORT(driver, (KC_HOME)); 127 esc_key.press(); 128 idle_for(TAPPING_TERM + 1); 129 VERIFY_AND_CLEAR(driver); 130 131 // Release Esc key. 132 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 133 EXPECT_REPORT(driver, (KC_LSFT)); 134 esc_key.release(); 135 run_one_scan_loop(); 136 VERIFY_AND_CLEAR(driver); 137 138 // Release mod-tap Shift key. 139 EXPECT_EMPTY_REPORT(driver); 140 mod_tap_key.release(); 141 run_one_scan_loop(); 142 VERIFY_AND_CLEAR(driver); 143 } 144 145 TEST_F(SpeculativeHoldDefault, tap_regular_key_while_mod_tap_key_is_held) { 146 TestDriver driver; 147 InSequence s; 148 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 149 auto regular_key = KeymapKey(0, 2, 0, KC_A); 150 151 set_keymap({mod_tap_key, regular_key}); 152 153 // Press mod-tap-hold key. 154 EXPECT_REPORT(driver, (KC_LSFT)); 155 mod_tap_key.press(); 156 run_one_scan_loop(); 157 VERIFY_AND_CLEAR(driver); 158 159 // Tap regular key. 160 EXPECT_NO_REPORT(driver); 161 regular_key.press(); 162 run_one_scan_loop(); 163 regular_key.release(); 164 run_one_scan_loop(); 165 VERIFY_AND_CLEAR(driver); 166 167 // Release mod-tap-hold key. 168 EXPECT_EMPTY_REPORT(driver); 169 EXPECT_REPORT(driver, (KC_P)); 170 EXPECT_REPORT(driver, (KC_P, KC_A)); 171 EXPECT_REPORT(driver, (KC_P)); 172 EXPECT_EMPTY_REPORT(driver); 173 mod_tap_key.release(); 174 run_one_scan_loop(); 175 VERIFY_AND_CLEAR(driver); 176 177 // Idle for tapping term of mod tap hold key. 178 idle_for(TAPPING_TERM - 3); 179 VERIFY_AND_CLEAR(driver); 180 } 181 182 TEST_F(SpeculativeHoldDefault, tap_mod_tap_key_two_times) { 183 TestDriver driver; 184 InSequence s; 185 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 186 187 set_keymap({mod_tap_key}); 188 189 // Press mod-tap-hold key. 190 EXPECT_REPORT(driver, (KC_LSFT)); 191 mod_tap_key.press(); 192 run_one_scan_loop(); 193 VERIFY_AND_CLEAR(driver); 194 195 // Release mod-tap-hold key. 196 EXPECT_EMPTY_REPORT(driver); 197 EXPECT_REPORT(driver, (KC_P)); 198 EXPECT_EMPTY_REPORT(driver); 199 mod_tap_key.release(); 200 run_one_scan_loop(); 201 VERIFY_AND_CLEAR(driver); 202 203 // Press mod-tap-hold key again. 204 EXPECT_REPORT(driver, (KC_P)); 205 mod_tap_key.press(); 206 idle_for(TAPPING_TERM); 207 VERIFY_AND_CLEAR(driver); 208 209 // Release mod-tap-hold key. 210 EXPECT_EMPTY_REPORT(driver); 211 mod_tap_key.release(); 212 run_one_scan_loop(); 213 VERIFY_AND_CLEAR(driver); 214 } 215 216 TEST_F(SpeculativeHoldDefault, tap_mod_tap_key_twice_and_hold_on_second_time) { 217 TestDriver driver; 218 InSequence s; 219 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 220 221 set_keymap({mod_tap_key}); 222 223 // Press mod-tap-hold key. 224 EXPECT_REPORT(driver, (KC_LSFT)); 225 mod_tap_key.press(); 226 run_one_scan_loop(); 227 VERIFY_AND_CLEAR(driver); 228 229 // Release mod-tap-hold key. 230 EXPECT_EMPTY_REPORT(driver); 231 EXPECT_REPORT(driver, (KC_P)); 232 EXPECT_EMPTY_REPORT(driver); 233 mod_tap_key.release(); 234 run_one_scan_loop(); 235 VERIFY_AND_CLEAR(driver); 236 237 // Press mod-tap-hold key again. 238 EXPECT_REPORT(driver, (KC_P)); 239 mod_tap_key.press(); 240 idle_for(TAPPING_TERM); 241 VERIFY_AND_CLEAR(driver); 242 243 // Release mod-tap-hold key. 244 EXPECT_EMPTY_REPORT(driver); 245 mod_tap_key.release(); 246 run_one_scan_loop(); 247 VERIFY_AND_CLEAR(driver); 248 } 249 250 TEST_F(SpeculativeHoldDefault, tap_and_hold_mod_tap_key) { 251 TestDriver driver; 252 InSequence s; 253 static int process_record_user_calls = 0; 254 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_P)); 255 256 set_keymap({mod_tap_key}); 257 258 process_record_user_fun = [](uint16_t keycode, keyrecord_t *record) { 259 ++process_record_user_calls; 260 return true; 261 }; 262 263 // Press mod-tap-hold key. 264 EXPECT_REPORT(driver, (KC_LSFT)); 265 mod_tap_key.press(); 266 idle_for(TAPPING_TERM - 1); 267 EXPECT_EQ(get_speculative_mods(), MOD_BIT_LSHIFT); 268 EXPECT_EQ(get_mods(), 0); 269 // Speculative mod holds and releases are made directly, bypassing regular 270 // event processing. No calls have been made yet to process_record_user(). 271 EXPECT_EQ(process_record_user_calls, 0); 272 idle_for(2); 273 // Now that the key has settled, one call has been made for the hold event. 274 EXPECT_EQ(process_record_user_calls, 1); 275 EXPECT_EQ(get_speculative_mods(), 0); 276 EXPECT_EQ(get_mods(), MOD_BIT_LSHIFT); 277 VERIFY_AND_CLEAR(driver); 278 279 // Release mod-tap-hold key. 280 EXPECT_EMPTY_REPORT(driver); 281 mod_tap_key.release(); 282 run_one_scan_loop(); 283 EXPECT_EQ(process_record_user_calls, 2); 284 VERIFY_AND_CLEAR(driver); 285 } 286 287 // Test with layer tap and speculative mod tap keys on the same layer, 288 // rolling from LT to MT key: 289 // "LT down, MT down, (wait out tapping term), LT up, MT up." 290 TEST_F(SpeculativeHoldDefault, lt_mt_same_layer_roll) { 291 TestDriver driver; 292 InSequence s; 293 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 294 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_B)); 295 auto regular_key = KeymapKey(1, 1, 0, KC_C); 296 297 set_keymap({layer_tap_key, mod_tap_key, regular_key}); 298 299 // Press layer tap key. 300 EXPECT_NO_REPORT(driver); 301 layer_tap_key.press(); 302 run_one_scan_loop(); 303 VERIFY_AND_CLEAR(driver); 304 305 // Press mod-tap key, after flow tap term but within tapping term. The 306 // speculative mod activates. 307 EXPECT_REPORT(driver, (KC_LSFT)); 308 mod_tap_key.press(); 309 run_one_scan_loop(); 310 VERIFY_AND_CLEAR(driver); 311 312 // Wait for the layer tap key to settle. 313 EXPECT_EMPTY_REPORT(driver); 314 EXPECT_REPORT(driver, (KC_C)); 315 idle_for(TAPPING_TERM); 316 VERIFY_AND_CLEAR(driver); 317 318 // Release keys. 319 EXPECT_EMPTY_REPORT(driver); 320 layer_tap_key.release(); 321 run_one_scan_loop(); 322 mod_tap_key.release(); 323 run_one_scan_loop(); 324 VERIFY_AND_CLEAR(driver); 325 // All mods are released. 326 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 327 } 328 329 // Test with layer tap and speculative mod tap keys on the same layer, trying a 330 // nested press: 331 // "LT down, MT down, (wait out tapping term), MT up, LT up." 332 TEST_F(SpeculativeHoldDefault, lt_mt_same_layer_nested_press) { 333 TestDriver driver; 334 InSequence s; 335 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 336 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_B)); 337 auto regular_key = KeymapKey(1, 1, 0, KC_C); 338 339 set_keymap({layer_tap_key, mod_tap_key, regular_key}); 340 341 EXPECT_NO_REPORT(driver); 342 layer_tap_key.press(); 343 run_one_scan_loop(); 344 VERIFY_AND_CLEAR(driver); 345 346 EXPECT_REPORT(driver, (KC_LSFT)); 347 mod_tap_key.press(); 348 run_one_scan_loop(); 349 VERIFY_AND_CLEAR(driver); 350 351 EXPECT_EMPTY_REPORT(driver); 352 EXPECT_REPORT(driver, (KC_C)); 353 run_one_scan_loop(); 354 idle_for(TAPPING_TERM); 355 VERIFY_AND_CLEAR(driver); 356 357 // Release keys: MT first, LT second. 358 EXPECT_EMPTY_REPORT(driver); 359 mod_tap_key.release(); 360 run_one_scan_loop(); 361 layer_tap_key.release(); 362 run_one_scan_loop(); 363 VERIFY_AND_CLEAR(driver); 364 // All mods are released. 365 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 366 } 367 368 // Test with layer tap and speculative mod tap keys on the same layer, trying a 369 // nested press with the MT first: 370 // "MT down, LT down, (wait out tapping term), LT up, MT up." 371 TEST_F(SpeculativeHoldDefault, mt_lt_same_layer_nested_press) { 372 TestDriver driver; 373 InSequence s; 374 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 375 auto mod_tap_key = KeymapKey(0, 1, 0, SFT_T(KC_B)); 376 auto regular_key = KeymapKey(1, 1, 0, KC_C); 377 378 set_keymap({layer_tap_key, mod_tap_key, regular_key}); 379 380 EXPECT_REPORT(driver, (KC_LSFT)); 381 mod_tap_key.press(); 382 run_one_scan_loop(); 383 384 EXPECT_NO_REPORT(driver); 385 layer_tap_key.press(); 386 idle_for(TAPPING_TERM + 1); 387 VERIFY_AND_CLEAR(driver); 388 389 EXPECT_EMPTY_REPORT(driver); 390 layer_tap_key.release(); 391 run_one_scan_loop(); 392 mod_tap_key.release(); 393 run_one_scan_loop(); 394 VERIFY_AND_CLEAR(driver); 395 // All mods are released. 396 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 397 } 398 399 // Test with a speculative mod tap key reached by a layer tap key, rolling from 400 // LT to MT key: 401 // "LT down, MT down, (wait out tapping term), LT up, MT up." 402 TEST_F(SpeculativeHoldDefault, lt_mt_different_layer_roll) { 403 TestDriver driver; 404 InSequence s; 405 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 406 auto regular_key = KeymapKey(0, 1, 0, KC_B); 407 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 408 auto mod_tap_key = KeymapKey(1, 1, 0, SFT_T(KC_C)); 409 410 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 411 412 // Press layer tap key. 413 EXPECT_NO_REPORT(driver); 414 layer_tap_key.press(); 415 run_one_scan_loop(); 416 // Press mod tap key. 417 mod_tap_key.press(); 418 idle_for(TAPPING_TERM); 419 VERIFY_AND_CLEAR(driver); 420 421 // Release keys. 422 EXPECT_REPORT(driver, (KC_LSFT)); 423 layer_tap_key.release(); 424 idle_for(TAPPING_TERM); 425 VERIFY_AND_CLEAR(driver); 426 427 EXPECT_EMPTY_REPORT(driver); 428 mod_tap_key.release(); 429 run_one_scan_loop(); 430 VERIFY_AND_CLEAR(driver); 431 // All mods are released. 432 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 433 } 434 435 // Test with a speculative mod tap key reached by a layer tap key, slowly 436 // rolling from LT to MT key: 437 // "LT down, (wait), MT down, (wait), LT up, MT up." 438 TEST_F(SpeculativeHoldDefault, lt_mt_different_layer_slow_roll) { 439 TestDriver driver; 440 InSequence s; 441 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 442 auto regular_key = KeymapKey(0, 1, 0, KC_B); 443 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 444 auto mod_tap_key = KeymapKey(1, 1, 0, SFT_T(KC_C)); 445 446 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 447 448 EXPECT_NO_REPORT(driver); 449 layer_tap_key.press(); 450 idle_for(TAPPING_TERM + 1); 451 452 EXPECT_REPORT(driver, (KC_LSFT)); 453 mod_tap_key.press(); 454 run_one_scan_loop(); 455 VERIFY_AND_CLEAR(driver); 456 457 EXPECT_EMPTY_REPORT(driver); 458 EXPECT_REPORT(driver, (KC_B)); 459 EXPECT_EMPTY_REPORT(driver); 460 layer_tap_key.release(); 461 run_one_scan_loop(); 462 mod_tap_key.release(); 463 run_one_scan_loop(); 464 VERIFY_AND_CLEAR(driver); 465 // All mods are released. 466 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 467 } 468 469 // Test with a speculative mod tap key reached by a layer tap key, trying a 470 // nested press: 471 // "LT down, MT down, (wait out tapping term), MT up, LT up." 472 TEST_F(SpeculativeHoldDefault, lt_mt_different_layer_nested_press) { 473 TestDriver driver; 474 InSequence s; 475 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 476 auto regular_key = KeymapKey(0, 1, 0, KC_B); 477 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 478 auto mod_tap_key = KeymapKey(1, 1, 0, SFT_T(KC_C)); 479 480 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 481 482 EXPECT_NO_REPORT(driver); 483 layer_tap_key.press(); 484 run_one_scan_loop(); 485 mod_tap_key.press(); 486 idle_for(TAPPING_TERM); 487 VERIFY_AND_CLEAR(driver); 488 489 // Release keys. 490 EXPECT_REPORT(driver, (KC_LSFT)); 491 EXPECT_EMPTY_REPORT(driver); 492 mod_tap_key.release(); 493 run_one_scan_loop(); 494 layer_tap_key.release(); 495 run_one_scan_loop(); 496 VERIFY_AND_CLEAR(driver); 497 // All mods are released. 498 EXPECT_EQ(get_mods() | get_speculative_mods(), 0); 499 } 500 501 // Test with a speculative mod tap key reached by a layer tap key, trying a 502 // slow nested press: 503 // "LT down, (wait), MT down, MT up, LT up." 504 TEST_F(SpeculativeHoldDefault, lt_mt_different_layer_slow_nested_press) { 505 TestDriver driver; 506 InSequence s; 507 auto layer_tap_key = KeymapKey(0, 0, 0, LT(1, KC_A)); 508 auto regular_key = KeymapKey(0, 1, 0, KC_B); 509 auto placeholder_key = KeymapKey(1, 0, 0, KC_NO); 510 auto mod_tap_key = KeymapKey(1, 1, 0, SFT_T(KC_C)); 511 512 set_keymap({layer_tap_key, regular_key, placeholder_key, mod_tap_key}); 513 514 EXPECT_NO_REPORT(driver); 515 layer_tap_key.press(); 516 idle_for(TAPPING_TERM + 1); 517 518 EXPECT_REPORT(driver, (KC_LSFT)); 519 mod_tap_key.press(); 520 run_one_scan_loop(); 521 VERIFY_AND_CLEAR(driver); 522 523 EXPECT_EMPTY_REPORT(driver); 524 EXPECT_REPORT(driver, (KC_C)); 525 EXPECT_EMPTY_REPORT(driver); 526 mod_tap_key.release(); 527 run_one_scan_loop(); 528 layer_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 } // namespace