summary refs log tree commit diff
path: root/quantum/action_tapping.c
diff options
context:
space:
mode:
authorIsaac Elenbaas <isaacelenbaas@gmail.com>2021-11-25 07:12:14 -0500
committerGitHub <noreply@github.com>2021-11-25 23:12:14 +1100
commitd9393b86842b7ef143259b5f771ae7969f98cbb4 (patch)
treee0760c20f65c4cac7b6ffb3fedf3f36c6f7c13a2 /quantum/action_tapping.c
parent282e916d86a5d353b7cbdfef3afad3c7b011eb14 (diff)
Add Retro Shift (Auto Shift for Tap Hold via Retro Tapping) and Custom Auto Shifts (#11059)
* Add Retro Shift and Custom Auto Shifts

* Fix compilation errors with no RETRO_SHIFT value
Diffstat (limited to 'quantum/action_tapping.c')
-rw-r--r--quantum/action_tapping.c106
1 files changed, 93 insertions, 13 deletions
diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c
index 60e56fb811..0586fad421 100644
--- a/quantum/action_tapping.c
+++ b/quantum/action_tapping.c
@@ -44,6 +44,10 @@ __attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *re
 __attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { return false; }
 #    endif
 
+#    if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
+#        include "process_auto_shift.h"
+#    endif
+
 static keyrecord_t tapping_key                         = {};
 static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
 static uint8_t     waiting_buffer_head                 = 0;
@@ -107,12 +111,29 @@ void action_tapping_process(keyrecord_t record) {
 /* return true when key event is processed or consumed. */
 bool process_tapping(keyrecord_t *keyp) {
     keyevent_t event = keyp->event;
+#    if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(TAPPING_TERM_PER_KEY) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(TAPPING_FORCE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEYPRESS_PER_KEY)
+    uint16_t tapping_keycode = get_record_keycode(&tapping_key, false);
+#    endif
 
     // if tapping
     if (IS_TAPPING_PRESSED()) {
-        if (WITHIN_TAPPING_TERM(event)) {
+        // clang-format off
+        if (WITHIN_TAPPING_TERM(event)
+#    if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
+            || (
+#        ifdef RETRO_TAPPING_PER_KEY
+                get_retro_tapping(tapping_keycode, keyp) &&
+#        endif
+                (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16(event.time, tapping_key.event.time) < (RETRO_SHIFT + 0)
+            )
+#    endif
+        ) {
+            // clang-format on
             if (tapping_key.tap.count == 0) {
                 if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
+#    if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
+                    retroshift_swap_times();
+#    endif
                     // first tap!
                     debug("Tapping: First tap(0->1).\n");
                     tapping_key.tap.count = 1;
@@ -128,22 +149,70 @@ bool process_tapping(keyrecord_t *keyp) {
                  * This can register the key before settlement of tapping,
                  * useful for long TAPPING_TERM but may prevent fast typing.
                  */
-#    if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY)
-                else if (((
+                // clang-format off
+#    if defined(TAPPING_TERM_PER_KEY) || (TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
+                else if (
+                    (
+                        (
+                            (
 #        ifdef TAPPING_TERM_PER_KEY
-                              get_tapping_term(get_record_keycode(&tapping_key, false), keyp)
+                                get_tapping_term(tapping_keycode, keyp)
 #        else
-                              TAPPING_TERM
+                                TAPPING_TERM
 #        endif
-                              >= 500)
+                                >= 500
+                            )
 
 #        ifdef PERMISSIVE_HOLD_PER_KEY
-                          || get_permissive_hold(get_record_keycode(&tapping_key, false), keyp)
+                            || get_permissive_hold(tapping_keycode, keyp)
 #        elif defined(PERMISSIVE_HOLD)
-                          || true
+                            || true
+#        endif
+                        ) && IS_RELEASED(event) && waiting_buffer_typed(event)
+                    )
+                    // Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT
+                    // unnecessarily and fixes them for Layer Taps.
+#        if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
+                    || (
+#            ifdef RETRO_TAPPING_PER_KEY
+                        get_retro_tapping(tapping_keycode, keyp) &&
+#            endif
+                        (
+                            // Rolled over the two keys.
+                            (
+                                (
+                                    false
+#            if defined(HOLD_ON_OTHER_KEYPRESS) || defined(HOLD_ON_OTHER_KEYPRESS_PER_KEY)
+                                    || (
+                                        IS_LT(tapping_keycode)
+#                ifdef HOLD_ON_OTHER_KEYPRESS_PER_KEY
+                                        && get_hold_on_other_keypress(tapping_keycode, keyp)
+#                endif
+                                    )
+#            endif
+#            if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY)
+                                    || (
+                                        IS_MT(tapping_keycode)
+#                ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY
+                                        && !get_ignore_mod_tap_interrupt(tapping_keycode, keyp)
+#                endif
+                                    )
+#            endif
+                                ) && tapping_key.tap.interrupted == true
+                            )
+                            // Makes Retro Shift ignore [IGNORE_MOD_TAP_INTERRUPT's
+                            // effects on nested taps for MTs and the default
+                            // behavior of LTs] below TAPPING_TERM or RETRO_SHIFT.
+                            || (
+                                IS_RETRO(tapping_keycode)
+                                && (event.key.col != tapping_key.event.key.col || event.key.row != tapping_key.event.key.row)
+                                && IS_RELEASED(event) && waiting_buffer_typed(event)
+                            )
+                        )
+                    )
 #        endif
-                              ) &&
-                         IS_RELEASED(event) && waiting_buffer_typed(event)) {
+                ) {
+                    // clang-format on
                     debug("Tapping: End. No tap. Interfered by typing key\n");
                     process_record(&tapping_key);
                     tapping_key = (keyrecord_t){};
@@ -181,7 +250,7 @@ bool process_tapping(keyrecord_t *keyp) {
                         tapping_key.tap.interrupted = true;
 #    if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
 #        if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
-                        if (get_hold_on_other_key_press(get_record_keycode(&tapping_key, false), keyp))
+                        if (get_hold_on_other_key_press(tapping_keycode, keyp))
 #        endif
                         {
                             debug("Tapping: End. No tap. Interfered by pressed key\n");
@@ -284,14 +353,25 @@ bool process_tapping(keyrecord_t *keyp) {
             }
         }
     } else if (IS_TAPPING_RELEASED()) {
-        if (WITHIN_TAPPING_TERM(event)) {
+        // clang-format off
+        if (WITHIN_TAPPING_TERM(event)
+#    if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
+            || (
+#        ifdef RETRO_TAPPING_PER_KEY
+                get_retro_tapping(tapping_keycode, keyp) &&
+#        endif
+                (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16(event.time, tapping_key.event.time) < (RETRO_SHIFT + 0)
+            )
+#    endif
+        ) {
+            // clang-format on
             if (event.pressed) {
                 if (IS_TAPPING_RECORD(keyp)) {
 //#    ifndef TAPPING_FORCE_HOLD
 #    if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY)
                     if (
 #        ifdef TAPPING_FORCE_HOLD_PER_KEY
-                        !get_tapping_force_hold(get_record_keycode(&tapping_key, false), keyp) &&
+                        !get_tapping_force_hold(tapping_keycode, keyp) &&
 #        endif
                         !tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
                         // sequential tap.