qmk_settings: wrap one shot keys

This commit is contained in:
Ilya Zhuravlev 2021-07-01 20:13:00 -04:00
parent e692dee6c7
commit 2f37c69ac9
3 changed files with 25 additions and 41 deletions

View file

@ -127,6 +127,10 @@ extern qmk_settings_t QS;
#define QS_auto_shift_repeat (QS.auto_shift & 32) #define QS_auto_shift_repeat (QS.auto_shift & 32)
#define QS_auto_shift_no_auto_repeat (QS.auto_shift & 64) #define QS_auto_shift_no_auto_repeat (QS.auto_shift & 64)
/* One Shot Keys */
#define QS_oneshot_tap_toggle (QS.osk_tap_toggle)
#define QS_oneshot_timeout (QS.osk_timeout)
#else #else
/* dynamic settings framework is disabled => hardcode the settings and let the compiler optimize extra branches out */ /* dynamic settings framework is disabled => hardcode the settings and let the compiler optimize extra branches out */
@ -145,4 +149,8 @@ extern qmk_settings_t QS;
#define QS_auto_shift_repeat AUTO_SHIFT_REPEAT_Defined #define QS_auto_shift_repeat AUTO_SHIFT_REPEAT_Defined
#define QS_auto_shift_no_auto_repeat AUTO_SHIFT_NO_AUTO_REPEAT_Defined #define QS_auto_shift_no_auto_repeat AUTO_SHIFT_NO_AUTO_REPEAT_Defined
/* One Shot Keys */
#define QS_oneshot_tap_toggle ONESHOT_TAP_TOGGLE
#define QS_oneshot_timeout ONESHOT_TIMEOUT
#endif #endif

View file

@ -26,6 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_util.h" #include "action_util.h"
#include "action.h" #include "action.h"
#include "wait.h" #include "wait.h"
#include "qmk_settings.h"
#ifdef BACKLIGHT_ENABLE #ifdef BACKLIGHT_ENABLE
# include "backlight.h" # include "backlight.h"
@ -90,7 +91,7 @@ void action_exec(keyevent_t event) {
keyrecord_t record = {.event = event}; keyrecord_t record = {.event = event};
#ifndef NO_ACTION_ONESHOT #ifndef NO_ACTION_ONESHOT
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) if (QS_oneshot_timeout > 0) {
if (has_oneshot_layer_timed_out()) { if (has_oneshot_layer_timed_out()) {
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
} }
@ -102,7 +103,7 @@ void action_exec(keyevent_t event) {
clear_oneshot_swaphands(); clear_oneshot_swaphands();
} }
# endif # endif
# endif }
#endif #endif
#ifndef NO_ACTION_TAPPING #ifndef NO_ACTION_TAPPING
@ -301,13 +302,11 @@ void process_action(keyrecord_t *record, action_t action) {
} else if (tap_count == 1) { } else if (tap_count == 1) {
dprint("MODS_TAP: Oneshot: start\n"); dprint("MODS_TAP: Oneshot: start\n");
set_oneshot_mods(mods | get_oneshot_mods()); set_oneshot_mods(mods | get_oneshot_mods());
# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 } else if (QS_oneshot_tap_toggle > 1 && tap_count == QS_oneshot_tap_toggle) {
} else if (tap_count == ONESHOT_TAP_TOGGLE) {
dprint("MODS_TAP: Toggling oneshot"); dprint("MODS_TAP: Toggling oneshot");
clear_oneshot_mods(); clear_oneshot_mods();
set_oneshot_locked_mods(mods); set_oneshot_locked_mods(mods);
register_mods(mods); register_mods(mods);
# endif
} else { } else {
register_mods(mods | get_oneshot_mods()); register_mods(mods | get_oneshot_mods());
} }
@ -317,15 +316,15 @@ void process_action(keyrecord_t *record, action_t action) {
unregister_mods(mods); unregister_mods(mods);
} else if (tap_count == 1) { } else if (tap_count == 1) {
// Retain Oneshot mods // Retain Oneshot mods
# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 if (QS_oneshot_tap_toggle > 1) {
if (mods & get_mods()) { if (mods & get_mods()) {
clear_oneshot_locked_mods(); clear_oneshot_locked_mods();
clear_oneshot_mods(); clear_oneshot_mods();
unregister_mods(mods); unregister_mods(mods);
} }
} else if (tap_count == ONESHOT_TAP_TOGGLE) { }
} else if (QS_oneshot_tap_toggle > 1 && tap_count == QS_oneshot_tap_toggle) {
// Toggle Oneshot Layer // Toggle Oneshot Layer
# endif
} else { } else {
clear_oneshot_mods(); clear_oneshot_mods();
unregister_mods(mods); unregister_mods(mods);
@ -547,7 +546,7 @@ void process_action(keyrecord_t *record, action_t action) {
# ifndef NO_ACTION_ONESHOT # ifndef NO_ACTION_ONESHOT
case OP_ONESHOT: case OP_ONESHOT:
// Oneshot modifier // Oneshot modifier
# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 if (QS_oneshot_tap_toggle > 1) {
do_release_oneshot = false; do_release_oneshot = false;
if (event.pressed) { if (event.pressed) {
del_mods(get_oneshot_locked_mods()); del_mods(get_oneshot_locked_mods());
@ -555,13 +554,13 @@ void process_action(keyrecord_t *record, action_t action) {
reset_oneshot_layer(); reset_oneshot_layer();
layer_off(action.layer_tap.val); layer_off(action.layer_tap.val);
break; break;
} else if (tap_count < ONESHOT_TAP_TOGGLE) { } else if (tap_count < QS_oneshot_tap_toggle) {
layer_on(action.layer_tap.val); layer_on(action.layer_tap.val);
set_oneshot_layer(action.layer_tap.val, ONESHOT_START); set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
} }
} else { } else {
add_mods(get_oneshot_locked_mods()); add_mods(get_oneshot_locked_mods());
if (tap_count >= ONESHOT_TAP_TOGGLE) { if (tap_count >= QS_oneshot_tap_toggle) {
reset_oneshot_layer(); reset_oneshot_layer();
clear_oneshot_locked_mods(); clear_oneshot_locked_mods();
set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED);
@ -569,7 +568,7 @@ void process_action(keyrecord_t *record, action_t action) {
clear_oneshot_layer_state(ONESHOT_PRESSED); clear_oneshot_layer_state(ONESHOT_PRESSED);
} }
} }
# else } else {
if (event.pressed) { if (event.pressed) {
layer_on(action.layer_tap.val); layer_on(action.layer_tap.val);
set_oneshot_layer(action.layer_tap.val, ONESHOT_START); set_oneshot_layer(action.layer_tap.val, ONESHOT_START);
@ -579,7 +578,7 @@ void process_action(keyrecord_t *record, action_t action) {
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
} }
} }
# endif }
break; break;
# endif # endif
default: default:

View file

@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_layer.h" #include "action_layer.h"
#include "timer.h" #include "timer.h"
#include "keycode_config.h" #include "keycode_config.h"
#include "qmk_settings.h"
extern keymap_config_t keymap_config; extern keymap_config_t keymap_config;
@ -62,12 +63,8 @@ void clear_oneshot_locked_mods(void) {
oneshot_locked_mods_changed_kb(oneshot_locked_mods); oneshot_locked_mods_changed_kb(oneshot_locked_mods);
} }
} }
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static uint16_t oneshot_time = 0; static uint16_t oneshot_time = 0;
bool has_oneshot_mods_timed_out(void) { return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; } bool has_oneshot_mods_timed_out(void) { return QS_oneshot_timeout > 0 && TIMER_DIFF_16(timer_read(), oneshot_time) >= QS_oneshot_timeout; }
# else
bool has_oneshot_mods_timed_out(void) { return false; }
# endif
#endif #endif
/* oneshot layer */ /* oneshot layer */
@ -92,26 +89,22 @@ enum {
} swap_hands_oneshot = SHO_OFF; } swap_hands_oneshot = SHO_OFF;
# endif # endif
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static uint16_t oneshot_layer_time = 0; static uint16_t oneshot_layer_time = 0;
inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); } inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= QS_oneshot_timeout && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); }
# ifdef SWAP_HANDS_ENABLE # ifdef SWAP_HANDS_ENABLE
static uint16_t oneshot_swaphands_time = 0; static uint16_t oneshot_swaphands_time = 0;
inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE); } inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= QS_oneshot_timeout && (swap_hands_oneshot == SHO_ACTIVE); }
# endif # endif
# endif
# ifdef SWAP_HANDS_ENABLE # ifdef SWAP_HANDS_ENABLE
void set_oneshot_swaphands(void) { void set_oneshot_swaphands(void) {
swap_hands_oneshot = SHO_PRESSED; swap_hands_oneshot = SHO_PRESSED;
swap_hands = true; swap_hands = true;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_swaphands_time = timer_read(); oneshot_swaphands_time = timer_read();
if (oneshot_layer_time != 0) { if (oneshot_layer_time != 0) {
oneshot_layer_time = oneshot_swaphands_time; oneshot_layer_time = oneshot_swaphands_time;
} }
# endif
} }
void release_oneshot_swaphands(void) { void release_oneshot_swaphands(void) {
@ -135,9 +128,7 @@ void use_oneshot_swaphands(void) {
void clear_oneshot_swaphands(void) { void clear_oneshot_swaphands(void) {
swap_hands_oneshot = SHO_OFF; swap_hands_oneshot = SHO_OFF;
swap_hands = false; swap_hands = false;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_swaphands_time = 0; oneshot_swaphands_time = 0;
# endif
} }
# endif # endif
@ -150,9 +141,7 @@ void set_oneshot_layer(uint8_t layer, uint8_t state) {
if (!keymap_config.oneshot_disable) { if (!keymap_config.oneshot_disable) {
oneshot_layer_data = layer << 3 | state; oneshot_layer_data = layer << 3 | state;
layer_on(layer); layer_on(layer);
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_layer_time = timer_read(); oneshot_layer_time = timer_read();
# endif
oneshot_layer_changed_kb(get_oneshot_layer()); oneshot_layer_changed_kb(get_oneshot_layer());
} else { } else {
layer_on(layer); layer_on(layer);
@ -164,9 +153,7 @@ void set_oneshot_layer(uint8_t layer, uint8_t state) {
*/ */
void reset_oneshot_layer(void) { void reset_oneshot_layer(void) {
oneshot_layer_data = 0; oneshot_layer_data = 0;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_layer_time = 0; oneshot_layer_time = 0;
# endif
oneshot_layer_changed_kb(get_oneshot_layer()); oneshot_layer_changed_kb(get_oneshot_layer());
} }
/** \brief Clear oneshot layer /** \brief Clear oneshot layer
@ -231,12 +218,10 @@ void send_keyboard_report(void) {
keyboard_report->mods |= macro_mods; keyboard_report->mods |= macro_mods;
#ifndef NO_ACTION_ONESHOT #ifndef NO_ACTION_ONESHOT
if (oneshot_mods) { if (oneshot_mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) if (QS_oneshot_timeout > 0 && has_oneshot_mods_timed_out()) {
if (has_oneshot_mods_timed_out()) {
dprintf("Oneshot: timeout\n"); dprintf("Oneshot: timeout\n");
clear_oneshot_mods(); clear_oneshot_mods();
} }
# endif
keyboard_report->mods |= oneshot_mods; keyboard_report->mods |= oneshot_mods;
if (has_anykey(keyboard_report)) { if (has_anykey(keyboard_report)) {
clear_oneshot_mods(); clear_oneshot_mods();
@ -335,9 +320,7 @@ uint8_t get_oneshot_mods(void) { return oneshot_mods; }
void add_oneshot_mods(uint8_t mods) { void add_oneshot_mods(uint8_t mods) {
if ((oneshot_mods & mods) != mods) { if ((oneshot_mods & mods) != mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read(); oneshot_time = timer_read();
# endif
oneshot_mods |= mods; oneshot_mods |= mods;
oneshot_mods_changed_kb(mods); oneshot_mods_changed_kb(mods);
} }
@ -346,9 +329,7 @@ void add_oneshot_mods(uint8_t mods) {
void del_oneshot_mods(uint8_t mods) { void del_oneshot_mods(uint8_t mods) {
if (oneshot_mods & mods) { if (oneshot_mods & mods) {
oneshot_mods &= ~mods; oneshot_mods &= ~mods;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = oneshot_mods ? timer_read() : 0; oneshot_time = oneshot_mods ? timer_read() : 0;
# endif
oneshot_mods_changed_kb(oneshot_mods); oneshot_mods_changed_kb(oneshot_mods);
} }
} }
@ -360,9 +341,7 @@ void del_oneshot_mods(uint8_t mods) {
void set_oneshot_mods(uint8_t mods) { void set_oneshot_mods(uint8_t mods) {
if (!keymap_config.oneshot_disable) { if (!keymap_config.oneshot_disable) {
if (oneshot_mods != mods) { if (oneshot_mods != mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read(); oneshot_time = timer_read();
# endif
oneshot_mods = mods; oneshot_mods = mods;
oneshot_mods_changed_kb(mods); oneshot_mods_changed_kb(mods);
} }
@ -376,9 +355,7 @@ void set_oneshot_mods(uint8_t mods) {
void clear_oneshot_mods(void) { void clear_oneshot_mods(void) {
if (oneshot_mods) { if (oneshot_mods) {
oneshot_mods = 0; oneshot_mods = 0;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = 0; oneshot_time = 0;
# endif
oneshot_mods_changed_kb(oneshot_mods); oneshot_mods_changed_kb(oneshot_mods);
} }
} }