diff --git a/docs/feature_auto_shift.md b/docs/feature_auto_shift.md index f0b507bc618a..a597783dcfc1 100644 --- a/docs/feature_auto_shift.md +++ b/docs/feature_auto_shift.md @@ -34,6 +34,8 @@ Yes, unfortunately. for a shifted version, but we did not. On the other hand, we may think we are tapping the keys, but really we have held it for a little longer than anticipated. +3. Auto Shift does not apply to Tap Hold keys. For automatic shifting of Tap Hold + keys see [Retro Shift](tap_hold.md#retro-shift). ## How Do I Enable Auto Shift? diff --git a/docs/tap_hold.md b/docs/tap_hold.md index 589ec3181609..38ffb5cf863d 100644 --- a/docs/tap_hold.md +++ b/docs/tap_hold.md @@ -179,6 +179,26 @@ Holding and releasing a dual function key without pressing another key will resu For instance, holding and releasing `LT(2, KC_SPACE)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPACE` instead. +## Retro Shift + +Holding and releasing a Tap Hold key without pressing another key will result in only the hold. With Retro Shift enabled this action will produce a shifted version of the tap keycode. + +This is a supplement to [Auto Shift](feature_auto_shift.md), which does not support Tap Hold. Auto Shift is not required to be enabled, but for consistency it should be enabled and configured with the Auto Shift timeout matching the tapping term. Retro Shift applies to the same tap keycodes as Auto Shift and uses the Auto Shift options `NO_AUTO_SHIFT_SPECIAL`, `NO_AUTO_SHIFT_NUMERIC`, `NO_AUTO_SHIFT_ALPHA`, and `AUTO_SHIFT_MODIFIERS` if defined. + +Retro Shift does not require [Retro Tapping](#retro-tapping) to be enabled, and if both are enabled Retro Tapping will only apply if the tap keycode is not matched by Retro Shift. + +To enable Retro Shift, add the following to your `config.h`: + +```c +#define RETRO_SHIFT +``` + +If `RETRO_SHIFT` is defined to a value, hold times greater than that value will not produce a tap on release. This enables modifiers to be held for combining with mouse clicks without generating taps on release. For example: + +```c +#define RETRO_SHIFT 500 +``` + ## Why do we include the key record for the per key functions? One thing that you may notice is that we include the key record for all of the "per key" functions, and may be wondering why we do that. diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index ee9aa0df77db..a46e0ae15728 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c @@ -39,10 +39,14 @@ along with this program. If not, see . int tp_buttons; -#ifdef RETRO_TAPPING +#if defined RETRO_TAPPING || defined RETRO_SHIFT int retro_tapping_counter = 0; #endif +#ifdef RETRO_SHIFT +# include "quantum.h" +#endif + #ifdef FAUXCLICKY_ENABLE # include #endif @@ -67,7 +71,7 @@ void action_exec(keyevent_t event) { dprint("EVENT: "); debug_event(event); dprintln(); -#ifdef RETRO_TAPPING +#if defined RETRO_TAPPING || defined RETRO_SHIFT retro_tapping_counter++; #endif } @@ -229,10 +233,16 @@ void process_action(keyrecord_t *record, action_t action) { #ifndef NO_ACTION_TAPPING uint8_t tap_count = record->tap.count; #endif +#ifdef RETRO_SHIFT + static uint16_t retro_shift_start_time; +#endif if (event.pressed) { // clear the potential weak mods left by previously pressed keys clear_weak_mods(); +#ifdef RETRO_SHIFT + retro_shift_start_time = event.time; +#endif } #ifndef NO_ACTION_ONESHOT @@ -692,7 +702,7 @@ void process_action(keyrecord_t *record, action_t action) { #endif #ifndef NO_ACTION_TAPPING -# ifdef RETRO_TAPPING +# if defined RETRO_TAPPING || defined RETRO_SHIFT if (!is_tap_action(action)) { retro_tapping_counter = 0; } else { @@ -706,7 +716,39 @@ void process_action(keyrecord_t *record, action_t action) { retro_tapping_counter = 0; } else { if (retro_tapping_counter == 2) { +# ifdef RETRO_SHIFT + if(!(RETRO_SHIFT + 0) || TIMER_DIFF_16(event.time, retro_shift_start_time) < (RETRO_SHIFT + 0)){ + + switch (action.layer_tap.code) { +# ifndef NO_AUTO_SHIFT_ALPHA + case KC_A ... KC_Z: +# endif +# ifndef NO_AUTO_SHIFT_NUMERIC + case KC_1 ... KC_0: +# endif +# ifndef NO_AUTO_SHIFT_SPECIAL + case KC_TAB: + case KC_MINUS ... KC_SLASH: + case KC_NONUS_BSLASH: +# endif +# ifndef AUTO_SHIFT_MODIFIERS + if (get_mods()) { + tap_code(action.layer_tap.code); + break; + } +# endif + tap_code16(LSFT(action.layer_tap.code)); + break; + default: +# ifdef RETRO_TAPPING + tap_code(action.layer_tap.code); +# endif + ; + } + } +# else tap_code(action.layer_tap.code); +# endif } retro_tapping_counter = 0; }