]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Fix swap-hands tapping.
authorJoe Wasson <jwasson+github@gmail.com>
Mon, 12 Mar 2018 17:22:49 +0000 (10:22 -0700)
committerJack Humbert <jack.humb@gmail.com>
Fri, 16 Mar 2018 20:33:43 +0000 (16:33 -0400)
This is an inelegant hack for #2522 but makes things work. Basically we give `action.c` a chance to handle the hold event early so that we can swap the keyboard for later keys. Later, to allow the hold to happen again quickly we nuke the key record so that tapping is reset. I tried to find a cleaner way, honestly.

tmk_core/common/action.c
tmk_core/common/action.h
tmk_core/common/action_code.h
tmk_core/common/action_tapping.c

index 947e5118f1797de989fd2b236481cb86c78c889b..33d920554face818ed63da41edd3f15fe4a96c26 100644 (file)
@@ -93,6 +93,7 @@ void action_exec(keyevent_t event)
 
 #ifdef SWAP_HANDS_ENABLE
 bool swap_hands = false;
+bool swap_held = false;
 
 void process_hand_swap(keyevent_t *event) {
     static swap_state_row_t swap_state[MATRIX_ROWS];
@@ -132,6 +133,27 @@ bool process_record_quantum(keyrecord_t *record) {
     return true;
 }
 
+#ifndef NO_ACTION_TAPPING
+// Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress.
+void process_record_tap_hint(keyrecord_t *record)
+{
+    action_t action = layer_switch_get_action(record->event.key);
+
+    switch (action.kind.id) {
+#ifdef SWAP_HANDS_ENABLE
+        case ACT_SWAP_HANDS:
+            switch (action.swap.code) {
+                case OP_SH_TAP_TOGGLE:
+                default:
+                    swap_hands = !swap_hands;
+                    swap_held = true;
+            }
+            break;
+#endif
+    }
+}
+#endif
+
 void process_record(keyrecord_t *record)
 {
     if (IS_NOEVENT(record->event)) { return; }
@@ -551,23 +573,37 @@ void process_action(keyrecord_t *record, action_t action)
     #ifndef NO_ACTION_TAPPING
                 case OP_SH_TAP_TOGGLE:
                     /* tap toggle */
-                    if (tap_count > 0) {
-                        if (!event.pressed) {
+
+                    if (event.pressed) {
+                        if (swap_held) {
+                            swap_held = false;
+                        } else {
                             swap_hands = !swap_hands;
                         }
                     } else {
-                        swap_hands = event.pressed;
+                        if (tap_count < TAPPING_TOGGLE) {
+                            swap_hands = !swap_hands;
+                        }
                     }
                     break;
                 default:
+                    /* tap key */
                     if (tap_count > 0) {
+                        if (swap_held) {
+                            swap_hands = !swap_hands; // undo hold set up in _tap_hint
+                            swap_held = false;
+                        }
                         if (event.pressed) {
                             register_code(action.swap.code);
                         } else {
                             unregister_code(action.swap.code);
+                            *record = (keyrecord_t){}; // hack: reset tap mode
                         }
                     } else {
-                        swap_hands = event.pressed;
+                        if (swap_held && !event.pressed) {
+                            swap_hands = !swap_hands; // undo hold set up in _tap_hint
+                            swap_held = false;
+                        }
                     }
     #endif
             }
index 87027dedea6010cea08e738a9bb4574a09b83558..acc55c7d3881b73e01ae3dc03b2a834be98e8d59 100644 (file)
@@ -96,6 +96,10 @@ void clear_keyboard_but_mods(void);
 void layer_switch(uint8_t new_layer);
 bool is_tap_key(keypos_t key);
 
+#ifndef NO_ACTION_TAPPING
+void process_record_tap_hint(keyrecord_t *record);
+#endif
+
 /* debug */
 void debug_event(keyevent_t event);
 void debug_record(keyrecord_t record);
index 05bc845732f62d927373f3358d349cc6090c6a74..fe2735b97390746acbcc822a9214a91edeeb67af 100644 (file)
@@ -186,7 +186,7 @@ typedef union {
     } func;
     struct action_swap {
         uint8_t  code   :8;
-        uint8_t  opt   :4;
+        uint8_t  opt    :4;
         uint8_t  kind   :4;
     } swap;
 } action_t;
@@ -243,7 +243,7 @@ enum usage_pages {
 
 
 
-/* 
+/*
  * Layer Actions
  */
 enum layer_param_on {
@@ -257,7 +257,7 @@ enum layer_param_bit_op {
     OP_BIT_XOR = 2,
     OP_BIT_SET = 3,
 };
-enum layer_pram_tap_op {
+enum layer_param_tap_op {
     OP_TAP_TOGGLE = 0xF0,
     OP_ON_OFF,
     OP_OFF_ON,
@@ -329,7 +329,7 @@ enum function_opts {
 #define ACTION_FUNCTION_TAP(id)         ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))
 #define ACTION_FUNCTION_OPT(id, opt)    ACTION(ACT_FUNCTION, (opt)<<8 | (id))
 /* OneHand Support */
-enum swap_hands_pram_tap_op {
+enum swap_hands_param_tap_op {
     OP_SH_TOGGLE = 0xF0,
     OP_SH_TAP_TOGGLE,
     OP_SH_ON_OFF,
index 531a3ca345b69f5131370f93f31a6fa6ad756de8..6280c6c36f87293f3bfefb453a227fb0798c180a 100644 (file)
@@ -263,7 +263,7 @@ bool process_tapping(keyrecord_t *keyp)
                 return true;
             }
         } else {
-            // FIX: process_aciton here?
+            // FIX: process_action here?
             // timeout. no sequential tap.
             debug("Tapping: End(Timeout after releasing last tap): ");
             debug_event(event); debug("\n");
@@ -277,6 +277,7 @@ bool process_tapping(keyrecord_t *keyp)
         if (event.pressed && is_tap_key(event.key)) {
             debug("Tapping: Start(Press tap key).\n");
             tapping_key = *keyp;
+            process_record_tap_hint(&tapping_key);
             waiting_buffer_scan_tap();
             debug_tapping_key();
             return true;