diff --git a/common_features.mk b/common_features.mk index 6bfc91d277..d3f07c6f61 100644 --- a/common_features.mk +++ b/common_features.mk @@ -477,8 +477,9 @@ ifeq ($(strip $(DYNAMIC_KEYMAP_ENABLE)), yes) endif ifeq ($(strip $(QMK_SETTINGS)), yes) + AUTO_SHIFT_ENABLE := yes SRC += $(QUANTUM_DIR)/qmk_settings.c - OPT_DEFS += -DQMK_SETTINGS + OPT_DEFS += -DQMK_SETTINGS -DAUTO_SHIFT_NO_SETUP endif ifeq ($(strip $(DIP_SWITCH_ENABLE)), yes) diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index 51b0efdb47..521fc1e6e2 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_auto_shift.c @@ -20,6 +20,7 @@ # include # include "process_auto_shift.h" +# include "qmk_settings.h" static uint16_t autoshift_time = 0; static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT; @@ -45,16 +46,14 @@ static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record) return true; } -# ifndef AUTO_SHIFT_MODIFIERS +if (!QS_auto_shift_modifiers) { if (get_mods()) { return true; } -# endif -# ifdef AUTO_SHIFT_REPEAT +} +if (QS_auto_shift_repeat) { const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time); -# ifndef AUTO_SHIFT_NO_AUTO_REPEAT - if (!autoshift_flags.lastshifted) { -# endif + if (QS_auto_shift_no_auto_repeat || !autoshift_flags.lastshifted) { if (elapsed < TAPPING_TERM && keycode == autoshift_lastkey) { // Allow a tap-then-hold for keyrepeat. if (!autoshift_flags.lastshifted) { @@ -66,10 +65,8 @@ static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record) } return false; } -# ifndef AUTO_SHIFT_NO_AUTO_REPEAT } -# endif -# endif +} // Record the keycode so we can simulate it later. autoshift_lastkey = keycode; @@ -105,12 +102,12 @@ static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) { add_weak_mods(MOD_BIT(KC_LSFT)); register_code(autoshift_lastkey); autoshift_flags.lastshifted = true; -# if defined(AUTO_SHIFT_REPEAT) && !defined(AUTO_SHIFT_NO_AUTO_REPEAT) +if (QS_auto_shift_repeat && !QS_auto_shift_no_auto_repeat) { if (matrix_trigger) { // Prevents release. return; } -# endif +} } # if TAP_CODE_DELAY > 0 @@ -140,6 +137,8 @@ static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger) { * to be released. */ void autoshift_matrix_scan(void) { + if (!QS_auto_shift_enable) return; + if (autoshift_flags.in_progress) { const uint16_t now = timer_read(); const uint16_t elapsed = TIMER_DIFF_16(now, autoshift_time); @@ -178,6 +177,7 @@ uint16_t get_autoshift_timeout(void) { return autoshift_timeout; } void set_autoshift_timeout(uint16_t timeout) { autoshift_timeout = timeout; } bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { + if (!QS_auto_shift_enable) return true; // Note that record->event.time isn't reliable, see: // https://github.com/qmk/qmk_firmware/pull/9826#issuecomment-733559550 const uint16_t now = timer_read(); @@ -229,18 +229,16 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { __attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { switch (keycode) { -# ifndef NO_AUTO_SHIFT_ALPHA case KC_A ... KC_Z: -# endif -# ifndef NO_AUTO_SHIFT_NUMERIC + if (!QS_auto_shift_no_auto_shift_alpha) return true; case KC_1 ... KC_0: -# endif -# ifndef NO_AUTO_SHIFT_SPECIAL + if (!QS_auto_shift_no_auto_shift_numeric) return true; + break; case KC_TAB: case KC_MINUS ... KC_SLASH: case KC_NONUS_BSLASH: -# endif - return true; + if (!QS_auto_shift_no_auto_shift_special) return true; + break; } return false; } diff --git a/quantum/qmk_settings.c b/quantum/qmk_settings.c index 1524fd048d..2c66d90c30 100644 --- a/quantum/qmk_settings.c +++ b/quantum/qmk_settings.c @@ -5,16 +5,22 @@ #include "progmem.h" #include "dynamic_keymap.h" +#include "process_auto_shift.h" qmk_settings_t QS; #define DECLARE_SETTING(id, field) { .qsid=id, .ptr=&QS.field, .sz=sizeof(QS.field) } +#define DECLARE_SETTING_CB(id, field, callback) { .qsid=id, .ptr=&QS.field, .sz=sizeof(QS.field), .cb=callback } + +static void auto_shift_timeout_apply(void) { + set_autoshift_timeout(QS.auto_shift_timeout); +} static const qmk_settings_proto_t protos[] PROGMEM = { DECLARE_SETTING(1, grave_esc_override), DECLARE_SETTING(2, debounce_time), DECLARE_SETTING(3, auto_shift), - DECLARE_SETTING(4, auto_shift_timeout), + DECLARE_SETTING_CB(4, auto_shift_timeout, auto_shift_timeout_apply), DECLARE_SETTING(5, osk_tap_toggle), DECLARE_SETTING(6, osk_timeout), DECLARE_SETTING(7, tapping_term), @@ -48,6 +54,13 @@ static void save_settings(void) { void qmk_settings_init(void) { load_settings(); + /* execute all callbacks to initialize the settings */ + for (size_t i = 0; i < sizeof(protos)/sizeof(*protos); ++i) { + const qmk_settings_proto_t *proto = &protos[i]; + qmk_setting_callback_t cb = pgm_read_ptr(&proto->cb); + if (cb) + cb(); + } } void qmk_settings_reset(void) { @@ -62,6 +75,8 @@ void qmk_settings_reset(void) { QS.tap_hold = 0; save_settings(); + /* to trigger all callbacks */ + qmk_settings_init(); } void qmk_settings_query(uint16_t qsid_gt, void *buffer, size_t sz) { @@ -98,5 +113,8 @@ int qmk_settings_set(uint16_t qsid, const void *setting, size_t maxsz) { return -1; memcpy(pgm_read_ptr(&proto->ptr), setting, pgm_read_word(&proto->sz)); save_settings(); + qmk_setting_callback_t cb = pgm_read_ptr(&proto->cb); + if (cb) + cb(); return 0; } diff --git a/quantum/qmk_settings.h b/quantum/qmk_settings.h index 5dff122793..768fa8931b 100644 --- a/quantum/qmk_settings.h +++ b/quantum/qmk_settings.h @@ -32,6 +32,51 @@ #define GRAVE_ESC_SHIFT_OVERRIDE_Defined 0 #endif +/* ========================================================================== */ +/* Auto shift */ +/* ========================================================================== */ +#ifdef AUTO_SHIFT_ENABLE +#define AUTO_SHIFT_ENABLE_Defined 1 +#else +#define AUTO_SHIFT_ENABLE_Defined 0 +#endif + +#ifdef AUTO_SHIFT_MODIFIERS +#define AUTO_SHIFT_MODIFIERS_Defined 1 +#else +#define AUTO_SHIFT_MODIFIERS_Defined 0 +#endif + +#ifdef NO_AUTO_SHIFT_SPECIAL +#define NO_AUTO_SHIFT_SPECIAL_Defined 1 +#else +#define NO_AUTO_SHIFT_SPECIAL_Defined 0 +#endif + +#ifdef NO_AUTO_SHIFT_NUMERIC +#define NO_AUTO_SHIFT_NUMERIC_Defined 1 +#else +#define NO_AUTO_SHIFT_NUMERIC_Defined 0 +#endif + +#ifdef NO_AUTO_SHIFT_ALPHA +#define NO_AUTO_SHIFT_ALPHA_Defined 1 +#else +#define NO_AUTO_SHIFT_ALPHA_Defined 0 +#endif + +#ifdef AUTO_SHIFT_REPEAT +#define AUTO_SHIFT_REPEAT_Defined 1 +#else +#define AUTO_SHIFT_REPEAT_Defined 0 +#endif + +#ifdef AUTO_SHIFT_NO_AUTO_REPEAT +#define AUTO_SHIFT_NO_AUTO_REPEAT_Defined 1 +#else +#define AUTO_SHIFT_NO_AUTO_REPEAT_Defined 0 +#endif + #ifdef QMK_SETTINGS /* dynamic settings framework is enabled */ @@ -49,11 +94,14 @@ typedef struct { } qmk_settings_t; _Static_assert(sizeof(qmk_settings_t) == 12, "unexpected size of the qmk_settings_t structure"); +typedef void (*qmk_setting_callback_t)(void); + /* setting prototype - describes how to get/set settings, stored in flash */ typedef struct { uint16_t qsid; uint16_t sz; void *ptr; + qmk_setting_callback_t cb; } qmk_settings_proto_t; void qmk_settings_init(void); @@ -70,14 +118,31 @@ extern qmk_settings_t QS; #define QS_grave_esc_gui_override (QS.grave_esc_override & 4) #define QS_grave_esc_shift_override (QS.grave_esc_override & 8) +/* Auto shift */ +#define QS_auto_shift_enable (QS.auto_shift & 1) +#define QS_auto_shift_modifiers (QS.auto_shift & 2) +#define QS_auto_shift_no_auto_shift_special (QS.auto_shift & 4) +#define QS_auto_shift_no_auto_shift_numeric (QS.auto_shift & 8) +#define QS_auto_shift_no_auto_shift_alpha (QS.auto_shift & 16) +#define QS_auto_shift_repeat (QS.auto_shift & 32) +#define QS_auto_shift_no_auto_repeat (QS.auto_shift & 64) + #else /* dynamic settings framework is disabled => hardcode the settings and let the compiler optimize extra branches out */ - /* Grave escape */ #define QS_grave_esc_alt_override GRAVE_ESC_ALT_OVERRIDE_Defined #define QS_grave_esc_ctrl_override GRAVE_ESC_CTRL_OVERRIDE_Defined #define QS_grave_esc_gui_override GRAVE_ESC_GUI_OVERRIDE_Defined #define QS_grave_esc_shift_override GRAVE_ESC_SHIFT_OVERRIDE_Defined -#endif \ No newline at end of file +/* Auto shift */ +#define QS_auto_shift_enable AUTO_SHIFT_ENABLE_Defined +#define QS_auto_shift_modifiers AUTO_SHIFT_MODIFIERS_Defined +#define QS_auto_shift_no_auto_shift_special NO_AUTO_SHIFT_SPECIAL_Defined +#define QS_auto_shift_no_auto_shift_numeric NO_AUTO_SHIFT_NUMERIC_Defined +#define QS_auto_shift_no_auto_shift_alpha NO_AUTO_SHIFT_ALPHA_Defined +#define QS_auto_shift_repeat AUTO_SHIFT_REPEAT_Defined +#define QS_auto_shift_no_auto_repeat AUTO_SHIFT_NO_AUTO_REPEAT_Defined + +#endif