[MERGE] Chaining OSL and MO (23065)

This commit is contained in:
Drashna Jael're 2024-07-26 18:47:18 -07:00
parent 42bd566c95
commit b5e1319410
Signed by: drashna
GPG key ID: DBA1FD3A860D1B11
2 changed files with 339 additions and 1 deletions

View file

@ -839,6 +839,10 @@ void process_action(keyrecord_t *record, action_t action) {
case ACT_LAYER_TAP_EXT: case ACT_LAYER_TAP_EXT:
# endif # endif
led_set(host_keyboard_leds()); led_set(host_keyboard_leds());
# ifndef NO_ACTION_ONESHOT
// don't release the key
do_release_oneshot = false;
# endif
break; break;
default: default:
break; break;

View file

@ -168,7 +168,7 @@ TEST_F(OneShot, OSMChainingTwoOSMs) {
tap_key(osm_key1); tap_key(osm_key1);
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
/* Press and relesea OSM2 */ /* Press and release OSM2 */
EXPECT_NO_REPORT(driver); EXPECT_NO_REPORT(driver);
tap_key(osm_key2); tap_key(osm_key2);
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
@ -353,3 +353,337 @@ TEST_F(OneShot, OSLWithOsmAndAdditionalKeypress) {
run_one_scan_loop(); run_one_scan_loop();
VERIFY_AND_CLEAR(driver); VERIFY_AND_CLEAR(driver);
} }
TEST_F(OneShot, OSLWithMoAndAdditionalKeypress) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey mo_key = KeymapKey{1, 1, 0, MO(2)};
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
set_keymap({osl_key, mo_key, regular_key});
/* Press OSL key */
EXPECT_NO_REPORT(driver);
osl_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release OSL key */
EXPECT_NO_REPORT(driver);
osl_key.release();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Press MO */
EXPECT_NO_REPORT(driver);
mo_key.press();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(2));
VERIFY_AND_CLEAR(driver);
/* Press regular key */
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
regular_key.press();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(2));
VERIFY_AND_CLEAR(driver);
/* Release regular key */
EXPECT_EMPTY_REPORT(driver);
regular_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release MO */
EXPECT_NO_REPORT(driver);
mo_key.release();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(0));
VERIFY_AND_CLEAR(driver);
}
class OneShotLayerParametrizedTestFixture : public ::testing::WithParamInterface<uint16_t>, public OneShot {};
TEST_P(OneShotLayerParametrizedTestFixture, OSLWithActionAndAdditionalKeypress) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey action_key = KeymapKey{1, 1, 0, GetParam()};
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
set_keymap({osl_key, action_key, regular_key});
/* Tap OSL key */
EXPECT_NO_REPORT(driver);
tap_key(osl_key);
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Tag Action key */
EXPECT_NO_REPORT(driver);
tap_key(action_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(2));
VERIFY_AND_CLEAR(driver);
/* Press regular key */
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
regular_key.press();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(2));
VERIFY_AND_CLEAR(driver);
/* Release regular key */
EXPECT_EMPTY_REPORT(driver);
regular_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
}
INSTANTIATE_TEST_CASE_P(OneShotLayerTests, OneShotLayerParametrizedTestFixture, ::testing::Values(TG(2), TO(2)));
TEST_F(OneShot, OSLWithDFAndAdditionalKeypress) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey df_key = KeymapKey{1, 1, 0, DF(2)};
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
set_keymap({osl_key, df_key, regular_key});
layer_state_t default_layer_state_bak = default_layer_state;
/* Tap OSL key */
EXPECT_NO_REPORT(driver);
tap_key(osl_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Press DF key */
EXPECT_NO_REPORT(driver);
df_key.press();
run_one_scan_loop();
EXPECT_EQ(default_layer_state, 0b001);
VERIFY_AND_CLEAR(driver);
/* Release DF key */
EXPECT_NO_REPORT(driver);
df_key.release();
run_one_scan_loop();
EXPECT_EQ(default_layer_state, 0b100);
VERIFY_AND_CLEAR(driver);
/* Press regular key */
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
regular_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release regular key */
EXPECT_EMPTY_REPORT(driver);
regular_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
default_layer_state = default_layer_state_bak;
}
TEST_F(OneShot, OSLChainingTwoOSLsAndAdditionalKeypress) {
TestDriver driver;
InSequence s;
KeymapKey osl1_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey osl2_key = KeymapKey{1, 1, 0, OSL(2)};
KeymapKey regular_key = KeymapKey{2, 1, 1, KC_A};
set_keymap({osl1_key, osl2_key, regular_key});
/* Press and release first OSL key */
EXPECT_NO_REPORT(driver);
osl1_key.press();
run_one_scan_loop();
osl1_key.release();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Press and release second OSL */
EXPECT_NO_REPORT(driver);
osl2_key.press();
run_one_scan_loop();
osl2_key.release();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(2));
VERIFY_AND_CLEAR(driver);
/* Press regular key */
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
EXPECT_EMPTY_REPORT(driver);
regular_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release regular key */
EXPECT_NO_REPORT(driver);
regular_key.release();
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(0));
VERIFY_AND_CLEAR(driver);
}
TEST_F(OneShot, OSLWithShortLT) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey lt_key = KeymapKey(1, 1, 0, LT(2, KC_A));
set_keymap({osl_key, lt_key});
/* Tap OSL key */
EXPECT_NO_REPORT(driver);
tap_key(osl_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Tap LT key. */
EXPECT_REPORT(driver, (lt_key.report_code)).Times(1);
EXPECT_EMPTY_REPORT(driver);
tap_key(lt_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(0));
VERIFY_AND_CLEAR(driver);
}
TEST_F(OneShot, OSLWithLongLTAndRegularKey) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey lt_key = KeymapKey(1, 1, 0, LT(2, KC_A));
KeymapKey regular_key = KeymapKey(2, 1, 1, KC_B);
set_keymap({osl_key, lt_key, regular_key});
/* Tap OSL key */
EXPECT_NO_REPORT(driver);
tap_key(osl_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Press LT key. */
EXPECT_NO_REPORT(driver);
lt_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Idle for tapping term of mod tap hold key. */
EXPECT_NO_REPORT(driver);
idle_for(TAPPING_TERM + 1);
VERIFY_AND_CLEAR(driver);
EXPECT_TRUE(layer_state_is(2));
/* Press regular key. */
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
regular_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release regular key. */
EXPECT_EMPTY_REPORT(driver);
regular_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
}
TEST_F(OneShot, OSLWithShortModTapKeyAndRegularKey) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey mod_tap_hold_key = KeymapKey(1, 1, 0, SFT_T(KC_P));
KeymapKey regular_key = KeymapKey(0, 2, 0, KC_A);
set_keymap({osl_key, mod_tap_hold_key, regular_key});
/* Tap OSL key */
EXPECT_NO_REPORT(driver);
tap_key(osl_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Press mod-tap-hold key. */
EXPECT_NO_REPORT(driver);
mod_tap_hold_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release mod-tap-hold key. */
EXPECT_REPORT(driver, (KC_P));
EXPECT_EMPTY_REPORT(driver);
mod_tap_hold_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Press regular key. */
EXPECT_REPORT(driver, (regular_key.report_code));
regular_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release regular key. */
EXPECT_EMPTY_REPORT(driver);
regular_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
}
TEST_F(OneShot, OSLWithLongModTapKeyAndRegularKey) {
TestDriver driver;
InSequence s;
KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
KeymapKey mod_tap_hold_key = KeymapKey(1, 1, 0, SFT_T(KC_P));
KeymapKey regular_key = KeymapKey(1, 2, 0, KC_A);
set_keymap({osl_key, mod_tap_hold_key, regular_key});
/* Tap OSL key */
EXPECT_NO_REPORT(driver);
tap_key(osl_key);
run_one_scan_loop();
EXPECT_TRUE(layer_state_is(1));
VERIFY_AND_CLEAR(driver);
/* Press mod-tap-hold key. */
EXPECT_NO_REPORT(driver);
mod_tap_hold_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Idle for tapping term of mod tap hold key. */
EXPECT_REPORT(driver, (KC_LSFT));
idle_for(TAPPING_TERM + 1);
VERIFY_AND_CLEAR(driver);
/* Release mod-tap-hold key. */
EXPECT_EMPTY_REPORT(driver);
mod_tap_hold_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Press regular key. */
EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
EXPECT_EMPTY_REPORT(driver);
regular_key.press();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
/* Release regular key. */
EXPECT_NO_REPORT(driver);
regular_key.release();
run_one_scan_loop();
VERIFY_AND_CLEAR(driver);
}