mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-07-17 13:12:08 +00:00
Fix One Shot Modifiers getting stuck or releasing early
This commit is contained in:
parent
096696d86d
commit
2fce0f2ab1
@ -112,7 +112,7 @@ void action_exec(keyevent_t event) {
|
||||
if (has_oneshot_layer_timed_out()) {
|
||||
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
|
||||
}
|
||||
if (has_oneshot_mods_timed_out()) {
|
||||
if (has_oneshot_mods_timed_out() && !get_oneshot_mods_fired()) {
|
||||
clear_oneshot_mods();
|
||||
}
|
||||
# ifdef SWAP_HANDS_ENABLE
|
||||
|
@ -46,9 +46,13 @@ extern inline void clear_keys(void);
|
||||
#ifndef NO_ACTION_ONESHOT
|
||||
static uint8_t oneshot_mods = 0;
|
||||
static uint8_t oneshot_locked_mods = 0;
|
||||
static bool oneshot_mods_fired = false;
|
||||
uint8_t get_oneshot_locked_mods(void) {
|
||||
return oneshot_locked_mods;
|
||||
}
|
||||
bool get_oneshot_mods_fired(void) {
|
||||
return oneshot_mods_fired;
|
||||
}
|
||||
void add_oneshot_locked_mods(uint8_t mods) {
|
||||
if ((oneshot_locked_mods & mods) != mods) {
|
||||
oneshot_locked_mods |= mods;
|
||||
@ -260,16 +264,15 @@ static uint8_t get_mods_for_report(void) {
|
||||
|
||||
#ifndef NO_ACTION_ONESHOT
|
||||
if (oneshot_mods) {
|
||||
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
|
||||
if (has_oneshot_mods_timed_out()) {
|
||||
dprintf("Oneshot: timeout\n");
|
||||
// Fire oneshots when other keys are pressed
|
||||
// Release oneshots when everything else is released
|
||||
if (has_anykey() || mods) {
|
||||
oneshot_mods_fired = true;
|
||||
} else if (oneshot_mods_fired) {
|
||||
oneshot_mods_fired = false;
|
||||
clear_oneshot_mods();
|
||||
}
|
||||
# endif
|
||||
mods |= oneshot_mods;
|
||||
if (has_anykey()) {
|
||||
clear_oneshot_mods();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -68,6 +68,7 @@ void clear_oneshot_mods(void);
|
||||
bool has_oneshot_mods_timed_out(void);
|
||||
|
||||
uint8_t get_oneshot_locked_mods(void);
|
||||
bool get_oneshot_mods_fired(void);
|
||||
void add_oneshot_locked_mods(uint8_t mods);
|
||||
void set_oneshot_locked_mods(uint8_t mods);
|
||||
void clear_oneshot_locked_mods(void);
|
||||
|
@ -17,3 +17,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
#define ONESHOT_TAP_TOGGLE 5
|
||||
|
@ -254,7 +254,7 @@ TEST_F(OneShot, OSMHoldNotLockingOSMs) {
|
||||
|
||||
/* Press and release regular key */
|
||||
EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
|
||||
EXPECT_REPORT(driver, (osm_key2.report_code)).Times(1);
|
||||
EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code)).Times(1);
|
||||
tap_key(regular_key);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
@ -277,6 +277,118 @@ TEST_F(OneShot, OSMHoldNotLockingOSMs) {
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSMHoldRelease) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osm_key = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
|
||||
|
||||
set_keymap({osm_key});
|
||||
|
||||
/* Press and release OSM */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osm_key);
|
||||
idle_for(TAPPING_TERM);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press and hold OSM */
|
||||
EXPECT_REPORT(driver, (osm_key.report_code)).Times(1);
|
||||
osm_key.press();
|
||||
run_one_scan_loop();
|
||||
idle_for(TAPPING_TERM);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release OSM */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
osm_key.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSMHoldReleaseTwoOSMs) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
|
||||
KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
|
||||
|
||||
set_keymap({osm_key1, osm_key2});
|
||||
|
||||
/* Press and release OSM1 */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osm_key1);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press and release OSM2 */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osm_key2);
|
||||
idle_for(TAPPING_TERM);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press and hold OSM1 */
|
||||
EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code)).Times(1);
|
||||
osm_key1.press();
|
||||
run_one_scan_loop();
|
||||
idle_for(TAPPING_TERM);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release OSM1 */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
osm_key1.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSMNonOSMMod) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osm_key = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
|
||||
KeymapKey regular_mod = KeymapKey{0, 1, 0, KC_LCTL};
|
||||
|
||||
set_keymap({osm_key, regular_mod});
|
||||
|
||||
/* Press and release OSM */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osm_key);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Press regular mod */
|
||||
EXPECT_REPORT(driver, (osm_key.report_code, regular_mod.report_code)).Times(1);
|
||||
regular_mod.press();
|
||||
run_one_scan_loop();
|
||||
idle_for(TAPPING_TERM);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Release regular mod */
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
regular_mod.release();
|
||||
run_one_scan_loop();
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSMLockRelease) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
KeymapKey osm_key = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
|
||||
|
||||
set_keymap({osm_key});
|
||||
|
||||
EXPECT_NO_REPORT(driver);
|
||||
for (int i = 1; i < ONESHOT_TAP_TOGGLE; i++) {
|
||||
/* Press and release OSM */
|
||||
tap_key(osm_key);
|
||||
}
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Lock OSM */
|
||||
EXPECT_REPORT(driver, (osm_key.report_code)).Times(1);
|
||||
tap_key(osm_key);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
/* Unlock OSM */
|
||||
EXPECT_NO_REPORT(driver);
|
||||
tap_key(osm_key);
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(OneShot, OSLWithAdditionalKeypress) {
|
||||
TestDriver driver;
|
||||
InSequence s;
|
||||
|
Loading…
Reference in New Issue
Block a user