summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--quantum/action.c4
-rw-r--r--tests/basic/test_one_shot_keys.cpp336
2 files changed, 339 insertions, 1 deletions
diff --git a/quantum/action.c b/quantum/action.c
index a39631ba3e..395340d9d7 100644
--- a/quantum/action.c
+++ b/quantum/action.c
@@ -817,6 +817,10 @@ void process_action(keyrecord_t *record, action_t action) {
817 case ACT_LAYER_TAP_EXT: 817 case ACT_LAYER_TAP_EXT:
818# endif 818# endif
819 led_set(host_keyboard_leds()); 819 led_set(host_keyboard_leds());
820# ifndef NO_ACTION_ONESHOT
821 // don't release the key
822 do_release_oneshot = false;
823# endif
820 break; 824 break;
821 default: 825 default:
822 break; 826 break;
diff --git a/tests/basic/test_one_shot_keys.cpp b/tests/basic/test_one_shot_keys.cpp
index 64a8673a5c..92db52f811 100644
--- a/tests/basic/test_one_shot_keys.cpp
+++ b/tests/basic/test_one_shot_keys.cpp
@@ -168,7 +168,7 @@ TEST_F(OneShot, OSMChainingTwoOSMs) {
168 tap_key(osm_key1); 168 tap_key(osm_key1);
169 VERIFY_AND_CLEAR(driver); 169 VERIFY_AND_CLEAR(driver);
170 170
171 /* Press and relesea OSM2 */ 171 /* Press and release OSM2 */
172 EXPECT_NO_REPORT(driver); 172 EXPECT_NO_REPORT(driver);
173 tap_key(osm_key2); 173 tap_key(osm_key2);
174 VERIFY_AND_CLEAR(driver); 174 VERIFY_AND_CLEAR(driver);
@@ -353,3 +353,337 @@ TEST_F(OneShot, OSLWithOsmAndAdditionalKeypress) {
353 run_one_scan_loop(); 353 run_one_scan_loop();
354 VERIFY_AND_CLEAR(driver); 354 VERIFY_AND_CLEAR(driver);
355} 355}
356
357TEST_F(OneShot, OSLWithMoAndAdditionalKeypress) {
358 TestDriver driver;
359 InSequence s;
360 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
361 KeymapKey mo_key = KeymapKey{1, 1, 0, MO(2)};
362 KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
363
364 set_keymap({osl_key, mo_key, regular_key});
365
366 /* Press OSL key */
367 EXPECT_NO_REPORT(driver);
368 osl_key.press();
369 run_one_scan_loop();
370 VERIFY_AND_CLEAR(driver);
371
372 /* Release OSL key */
373 EXPECT_NO_REPORT(driver);
374 osl_key.release();
375 run_one_scan_loop();
376 EXPECT_TRUE(layer_state_is(1));
377 VERIFY_AND_CLEAR(driver);
378
379 /* Press MO */
380 EXPECT_NO_REPORT(driver);
381 mo_key.press();
382 run_one_scan_loop();
383 EXPECT_TRUE(layer_state_is(2));
384 VERIFY_AND_CLEAR(driver);
385
386 /* Press regular key */
387 EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
388 regular_key.press();
389 run_one_scan_loop();
390 EXPECT_TRUE(layer_state_is(2));
391 VERIFY_AND_CLEAR(driver);
392
393 /* Release regular key */
394 EXPECT_EMPTY_REPORT(driver);
395 regular_key.release();
396 run_one_scan_loop();
397 VERIFY_AND_CLEAR(driver);
398
399 /* Release MO */
400 EXPECT_NO_REPORT(driver);
401 mo_key.release();
402 run_one_scan_loop();
403 EXPECT_TRUE(layer_state_is(0));
404 VERIFY_AND_CLEAR(driver);
405}
406
407class OneShotLayerParametrizedTestFixture : public ::testing::WithParamInterface<uint16_t>, public OneShot {};
408
409TEST_P(OneShotLayerParametrizedTestFixture, OSLWithActionAndAdditionalKeypress) {
410 TestDriver driver;
411 InSequence s;
412 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
413 KeymapKey action_key = KeymapKey{1, 1, 0, GetParam()};
414 KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
415
416 set_keymap({osl_key, action_key, regular_key});
417
418 /* Tap OSL key */
419 EXPECT_NO_REPORT(driver);
420 tap_key(osl_key);
421 run_one_scan_loop();
422 VERIFY_AND_CLEAR(driver);
423
424 /* Tag Action key */
425 EXPECT_NO_REPORT(driver);
426 tap_key(action_key);
427 run_one_scan_loop();
428 EXPECT_TRUE(layer_state_is(2));
429 VERIFY_AND_CLEAR(driver);
430
431 /* Press regular key */
432 EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
433 regular_key.press();
434 run_one_scan_loop();
435 EXPECT_TRUE(layer_state_is(2));
436 VERIFY_AND_CLEAR(driver);
437
438 /* Release regular key */
439 EXPECT_EMPTY_REPORT(driver);
440 regular_key.release();
441 run_one_scan_loop();
442 VERIFY_AND_CLEAR(driver);
443}
444
445INSTANTIATE_TEST_CASE_P(OneShotLayerTests, OneShotLayerParametrizedTestFixture, ::testing::Values(TG(2), TO(2)));
446
447TEST_F(OneShot, OSLWithDFAndAdditionalKeypress) {
448 TestDriver driver;
449 InSequence s;
450 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
451 KeymapKey df_key = KeymapKey{1, 1, 0, DF(2)};
452 KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
453
454 set_keymap({osl_key, df_key, regular_key});
455
456 layer_state_t default_layer_state_bak = default_layer_state;
457
458 /* Tap OSL key */
459 EXPECT_NO_REPORT(driver);
460 tap_key(osl_key);
461 run_one_scan_loop();
462 EXPECT_TRUE(layer_state_is(1));
463 VERIFY_AND_CLEAR(driver);
464
465 /* Press DF key */
466 EXPECT_NO_REPORT(driver);
467 df_key.press();
468 run_one_scan_loop();
469 EXPECT_EQ(default_layer_state, 0b001);
470
471 VERIFY_AND_CLEAR(driver);
472
473 /* Release DF key */
474 EXPECT_NO_REPORT(driver);
475 df_key.release();
476 run_one_scan_loop();
477 EXPECT_EQ(default_layer_state, 0b100);
478 VERIFY_AND_CLEAR(driver);
479
480 /* Press regular key */
481 EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
482 regular_key.press();
483 run_one_scan_loop();
484 VERIFY_AND_CLEAR(driver);
485
486 /* Release regular key */
487 EXPECT_EMPTY_REPORT(driver);
488 regular_key.release();
489 run_one_scan_loop();
490 VERIFY_AND_CLEAR(driver);
491
492 default_layer_state = default_layer_state_bak;
493}
494
495TEST_F(OneShot, OSLChainingTwoOSLsAndAdditionalKeypress) {
496 TestDriver driver;
497 InSequence s;
498 KeymapKey osl1_key = KeymapKey{0, 0, 0, OSL(1)};
499 KeymapKey osl2_key = KeymapKey{1, 1, 0, OSL(2)};
500 KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
501
502 set_keymap({osl1_key, osl2_key, regular_key});
503
504 /* Press and release first OSL key */
505 EXPECT_NO_REPORT(driver);
506 osl1_key.press();
507 run_one_scan_loop();
508 osl1_key.release();
509 run_one_scan_loop();
510 EXPECT_TRUE(layer_state_is(1));
511 VERIFY_AND_CLEAR(driver);
512
513 /* Press and release second OSL */
514 EXPECT_NO_REPORT(driver);
515 osl2_key.press();
516 run_one_scan_loop();
517 osl2_key.release();
518 run_one_scan_loop();
519 EXPECT_TRUE(layer_state_is(2));
520 VERIFY_AND_CLEAR(driver);
521
522 /* Press regular key */
523 EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
524 EXPECT_EMPTY_REPORT(driver);
525 regular_key.press();
526 run_one_scan_loop();
527 VERIFY_AND_CLEAR(driver);
528
529 /* Release regular key */
530 EXPECT_NO_REPORT(driver);
531 regular_key.release();
532 run_one_scan_loop();
533 EXPECT_TRUE(layer_state_is(0));
534 VERIFY_AND_CLEAR(driver);
535}
536
537TEST_F(OneShot, OSLWithShortLT) {
538 TestDriver driver;
539 InSequence s;
540 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
541 KeymapKey lt_key = KeymapKey(1, 1, 0, LT(2, KC_A));
542
543 set_keymap({osl_key, lt_key});
544
545 /* Tap OSL key */
546 EXPECT_NO_REPORT(driver);
547 tap_key(osl_key);
548 run_one_scan_loop();
549 EXPECT_TRUE(layer_state_is(1));
550 VERIFY_AND_CLEAR(driver);
551
552 /* Tap LT key. */
553 EXPECT_REPORT(driver, (lt_key.report_code)).Times(1);
554 EXPECT_EMPTY_REPORT(driver);
555 tap_key(lt_key);
556 run_one_scan_loop();
557 EXPECT_TRUE(layer_state_is(0));
558 VERIFY_AND_CLEAR(driver);
559}
560
561TEST_F(OneShot, OSLWithLongLTAndRegularKey) {
562 TestDriver driver;
563 InSequence s;
564 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
565 KeymapKey lt_key = KeymapKey(1, 1, 0, LT(2, KC_A));
566 KeymapKey regular_key = KeymapKey(2, 1, 1, KC_B);
567
568 set_keymap({osl_key, lt_key, regular_key});
569
570 /* Tap OSL key */
571 EXPECT_NO_REPORT(driver);
572 tap_key(osl_key);
573 run_one_scan_loop();
574 EXPECT_TRUE(layer_state_is(1));
575 VERIFY_AND_CLEAR(driver);
576
577 /* Press LT key. */
578 EXPECT_NO_REPORT(driver);
579 lt_key.press();
580 run_one_scan_loop();
581 VERIFY_AND_CLEAR(driver);
582
583 /* Idle for tapping term of mod tap hold key. */
584 EXPECT_NO_REPORT(driver);
585 idle_for(TAPPING_TERM + 1);
586 VERIFY_AND_CLEAR(driver);
587 EXPECT_TRUE(layer_state_is(2));
588
589 /* Press regular key. */
590 EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
591 regular_key.press();
592 run_one_scan_loop();
593 VERIFY_AND_CLEAR(driver);
594
595 /* Release regular key. */
596 EXPECT_EMPTY_REPORT(driver);
597 regular_key.release();
598 run_one_scan_loop();
599 VERIFY_AND_CLEAR(driver);
600}
601
602TEST_F(OneShot, OSLWithShortModTapKeyAndRegularKey) {
603 TestDriver driver;
604 InSequence s;
605 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
606 KeymapKey mod_tap_hold_key = KeymapKey(1, 1, 0, SFT_T(KC_P));
607 KeymapKey regular_key = KeymapKey(0, 2, 0, KC_A);
608
609 set_keymap({osl_key, mod_tap_hold_key, regular_key});
610
611 /* Tap OSL key */
612 EXPECT_NO_REPORT(driver);
613 tap_key(osl_key);
614 run_one_scan_loop();
615 EXPECT_TRUE(layer_state_is(1));
616 VERIFY_AND_CLEAR(driver);
617
618 /* Press mod-tap-hold key. */
619 EXPECT_NO_REPORT(driver);
620 mod_tap_hold_key.press();
621 run_one_scan_loop();
622 VERIFY_AND_CLEAR(driver);
623
624 /* Release mod-tap-hold key. */
625 EXPECT_REPORT(driver, (KC_P));
626 EXPECT_EMPTY_REPORT(driver);
627 mod_tap_hold_key.release();
628 run_one_scan_loop();
629 VERIFY_AND_CLEAR(driver);
630
631 /* Press regular key. */
632 EXPECT_REPORT(driver, (regular_key.report_code));
633 regular_key.press();
634 run_one_scan_loop();
635 VERIFY_AND_CLEAR(driver);
636
637 /* Release regular key. */
638 EXPECT_EMPTY_REPORT(driver);
639 regular_key.release();
640 run_one_scan_loop();
641 VERIFY_AND_CLEAR(driver);
642}
643
644TEST_F(OneShot, OSLWithLongModTapKeyAndRegularKey) {
645 TestDriver driver;
646 InSequence s;
647 KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
648 KeymapKey mod_tap_hold_key = KeymapKey(1, 1, 0, SFT_T(KC_P));
649 KeymapKey regular_key = KeymapKey(1, 2, 0, KC_A);
650
651 set_keymap({osl_key, mod_tap_hold_key, regular_key});
652
653 /* Tap OSL key */
654 EXPECT_NO_REPORT(driver);
655 tap_key(osl_key);
656 run_one_scan_loop();
657 EXPECT_TRUE(layer_state_is(1));
658 VERIFY_AND_CLEAR(driver);
659
660 /* Press mod-tap-hold key. */
661 EXPECT_NO_REPORT(driver);
662 mod_tap_hold_key.press();
663 run_one_scan_loop();
664 VERIFY_AND_CLEAR(driver);
665
666 /* Idle for tapping term of mod tap hold key. */
667 EXPECT_REPORT(driver, (KC_LSFT));
668 idle_for(TAPPING_TERM + 1);
669 VERIFY_AND_CLEAR(driver);
670
671 /* Release mod-tap-hold key. */
672 EXPECT_EMPTY_REPORT(driver);
673 mod_tap_hold_key.release();
674 run_one_scan_loop();
675 VERIFY_AND_CLEAR(driver);
676
677 /* Press regular key. */
678 EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
679 EXPECT_EMPTY_REPORT(driver);
680 regular_key.press();
681 run_one_scan_loop();
682 VERIFY_AND_CLEAR(driver);
683
684 /* Release regular key. */
685 EXPECT_NO_REPORT(driver);
686 regular_key.release();
687 run_one_scan_loop();
688 VERIFY_AND_CLEAR(driver);
689} \ No newline at end of file