diff options
-rw-r--r-- | docs/feature_swap_hands.md | 1 | ||||
-rw-r--r-- | docs/keycodes.md | 1 | ||||
-rw-r--r-- | quantum/quantum_keycodes.h | 1 | ||||
-rw-r--r-- | tmk_core/common/action.c | 27 | ||||
-rw-r--r-- | tmk_core/common/action_code.h | 2 | ||||
-rw-r--r-- | tmk_core/common/action_util.c | 54 | ||||
-rw-r--r-- | tmk_core/common/action_util.h | 8 |
7 files changed, 93 insertions, 1 deletions
diff --git a/docs/feature_swap_hands.md b/docs/feature_swap_hands.md index 09e01d50d..009477d20 100644 --- a/docs/feature_swap_hands.md +++ b/docs/feature_swap_hands.md | |||
@@ -28,3 +28,4 @@ Note that the array indices are reversed same as the matrix and the values are o | |||
28 | |`SH_MOFF` |Momentarily turns off swap. | | 28 | |`SH_MOFF` |Momentarily turns off swap. | |
29 | |`SH_TG` |Toggles swap on and off with every key press. | | 29 | |`SH_TG` |Toggles swap on and off with every key press. | |
30 | |`SH_TT` |Toggles with a tap; momentary when held. | | 30 | |`SH_TT` |Toggles with a tap; momentary when held. | |
31 | |`SH_OS` |One shot swap hands: toggles while pressed or until next key press. | | ||
diff --git a/docs/keycodes.md b/docs/keycodes.md index 18fd81118..40a46964a 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md | |||
@@ -531,6 +531,7 @@ See also: [Swap Hands](feature_swap_hands.md) | |||
531 | |`SH_MOFF` |Momentarily turns off swap. | | 531 | |`SH_MOFF` |Momentarily turns off swap. | |
532 | |`SH_TG` |Toggles swap on and off with every key press. | | 532 | |`SH_TG` |Toggles swap on and off with every key press. | |
533 | |`SH_TT` |Toggles with a tap; momentary when held. | | 533 | |`SH_TT` |Toggles with a tap; momentary when held. | |
534 | |`SH_OS` |One shot swap hands: toggle while pressed or until next key press. | | ||
534 | 535 | ||
535 | ## Unicode Support :id=unicode-support | 536 | ## Unicode Support :id=unicode-support |
536 | 537 | ||
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 0958c4f4e..d8f1fa4bb 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h | |||
@@ -794,6 +794,7 @@ enum quantum_keycodes { | |||
794 | # define SH_T(kc) (QK_SWAP_HANDS | (kc)) | 794 | # define SH_T(kc) (QK_SWAP_HANDS | (kc)) |
795 | # define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) | 795 | # define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE) |
796 | # define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) | 796 | # define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE) |
797 | # define SH_OS (QK_SWAP_HANDS | OP_SH_ONESHOT) | ||
797 | # define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF) | 798 | # define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF) |
798 | # define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON) | 799 | # define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON) |
799 | # define SH_ON (QK_SWAP_HANDS | OP_SH_ON) | 800 | # define SH_ON (QK_SWAP_HANDS | OP_SH_ON) |
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index e5e9e2705..3b1268dc9 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c | |||
@@ -98,6 +98,11 @@ void action_exec(keyevent_t event) { | |||
98 | if (has_oneshot_mods_timed_out()) { | 98 | if (has_oneshot_mods_timed_out()) { |
99 | clear_oneshot_mods(); | 99 | clear_oneshot_mods(); |
100 | } | 100 | } |
101 | # ifdef SWAP_HANDS_ENABLE | ||
102 | if (has_oneshot_swaphands_timed_out()) { | ||
103 | clear_oneshot_swaphands(); | ||
104 | } | ||
105 | # endif | ||
101 | # endif | 106 | # endif |
102 | #endif | 107 | #endif |
103 | 108 | ||
@@ -165,6 +170,8 @@ void process_record_tap_hint(keyrecord_t *record) { | |||
165 | # ifdef SWAP_HANDS_ENABLE | 170 | # ifdef SWAP_HANDS_ENABLE |
166 | case ACT_SWAP_HANDS: | 171 | case ACT_SWAP_HANDS: |
167 | switch (action.swap.code) { | 172 | switch (action.swap.code) { |
173 | case OP_SH_ONESHOT: | ||
174 | break; | ||
168 | case OP_SH_TAP_TOGGLE: | 175 | case OP_SH_TAP_TOGGLE: |
169 | default: | 176 | default: |
170 | swap_hands = !swap_hands; | 177 | swap_hands = !swap_hands; |
@@ -224,7 +231,11 @@ void process_action(keyrecord_t *record, action_t action) { | |||
224 | #ifndef NO_ACTION_ONESHOT | 231 | #ifndef NO_ACTION_ONESHOT |
225 | bool do_release_oneshot = false; | 232 | bool do_release_oneshot = false; |
226 | // notice we only clear the one shot layer if the pressed key is not a modifier. | 233 | // notice we only clear the one shot layer if the pressed key is not a modifier. |
227 | if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) { | 234 | if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code) |
235 | # ifdef SWAP_HANDS_ENABLE | ||
236 | && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT) | ||
237 | # endif | ||
238 | ) { | ||
228 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); | 239 | clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); |
229 | do_release_oneshot = !is_oneshot_layer_active(); | 240 | do_release_oneshot = !is_oneshot_layer_active(); |
230 | } | 241 | } |
@@ -593,6 +604,14 @@ void process_action(keyrecord_t *record, action_t action) { | |||
593 | swap_hands = false; | 604 | swap_hands = false; |
594 | } | 605 | } |
595 | break; | 606 | break; |
607 | case OP_SH_ONESHOT: | ||
608 | if (event.pressed) { | ||
609 | set_oneshot_swaphands(); | ||
610 | } else { | ||
611 | release_oneshot_swaphands(); | ||
612 | } | ||
613 | break; | ||
614 | |||
596 | # ifndef NO_ACTION_TAPPING | 615 | # ifndef NO_ACTION_TAPPING |
597 | case OP_SH_TAP_TOGGLE: | 616 | case OP_SH_TAP_TOGGLE: |
598 | /* tap toggle */ | 617 | /* tap toggle */ |
@@ -681,6 +700,12 @@ void process_action(keyrecord_t *record, action_t action) { | |||
681 | # endif | 700 | # endif |
682 | #endif | 701 | #endif |
683 | 702 | ||
703 | #ifdef SWAP_HANDS_ENABLE | ||
704 | if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) { | ||
705 | use_oneshot_swaphands(); | ||
706 | } | ||
707 | #endif | ||
708 | |||
684 | #ifndef NO_ACTION_ONESHOT | 709 | #ifndef NO_ACTION_ONESHOT |
685 | /* Because we switch layers after a oneshot event, we need to release the | 710 | /* Because we switch layers after a oneshot event, we need to release the |
686 | * key before we leave the layer or no key up event will be generated. | 711 | * key before we leave the layer or no key up event will be generated. |
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index f80b7a782..eea554ff2 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h | |||
@@ -294,11 +294,13 @@ enum swap_hands_param_tap_op { | |||
294 | OP_SH_OFF_ON, | 294 | OP_SH_OFF_ON, |
295 | OP_SH_OFF, | 295 | OP_SH_OFF, |
296 | OP_SH_ON, | 296 | OP_SH_ON, |
297 | OP_SH_ONESHOT, | ||
297 | }; | 298 | }; |
298 | 299 | ||
299 | #define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF() | 300 | #define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF() |
300 | #define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) | 301 | #define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) |
301 | #define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) | 302 | #define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) |
303 | #define ACTION_SWAP_HANDS_ONESHOT() ACTION(ACT_SWAP_HANDS, OP_SH_ONESHOT) | ||
302 | #define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key) | 304 | #define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key) |
303 | #define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) | 305 | #define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) |
304 | #define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) | 306 | #define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) |
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c index 335aa36e6..371acfa61 100644 --- a/tmk_core/common/action_util.c +++ b/tmk_core/common/action_util.c | |||
@@ -83,9 +83,63 @@ static int8_t oneshot_layer_data = 0; | |||
83 | inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } | 83 | inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } |
84 | inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } | 84 | inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } |
85 | 85 | ||
86 | # ifdef SWAP_HANDS_ENABLE | ||
87 | enum { | ||
88 | SHO_OFF, | ||
89 | SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet | ||
90 | SHO_PRESSED, // Swap hands button is currently pressed | ||
91 | SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys | ||
92 | } swap_hands_oneshot = SHO_OFF; | ||
93 | # endif | ||
94 | |||
86 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | 95 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) |
87 | static uint16_t oneshot_layer_time = 0; | 96 | static uint16_t oneshot_layer_time = 0; |
88 | inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); } | 97 | inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); } |
98 | # ifdef SWAP_HANDS_ENABLE | ||
99 | static uint16_t oneshot_swaphands_time = 0; | ||
100 | inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && !(swap_hands_oneshot >= SHO_PRESSED); } | ||
101 | # endif | ||
102 | # endif | ||
103 | |||
104 | # ifdef SWAP_HANDS_ENABLE | ||
105 | |||
106 | void set_oneshot_swaphands(void) { | ||
107 | swap_hands_oneshot = SHO_PRESSED; | ||
108 | swap_hands = true; | ||
109 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
110 | oneshot_swaphands_time = timer_read(); | ||
111 | if (oneshot_layer_time != 0) { | ||
112 | oneshot_layer_time = oneshot_swaphands_time; | ||
113 | } | ||
114 | # endif | ||
115 | } | ||
116 | |||
117 | void release_oneshot_swaphands(void) { | ||
118 | if (swap_hands_oneshot == SHO_PRESSED) { | ||
119 | swap_hands_oneshot = SHO_ACTIVE; | ||
120 | } | ||
121 | if (swap_hands_oneshot == SHO_USED) { | ||
122 | clear_oneshot_swaphands(); | ||
123 | } | ||
124 | } | ||
125 | |||
126 | void use_oneshot_swaphands(void) { | ||
127 | if (swap_hands_oneshot == SHO_PRESSED) { | ||
128 | swap_hands_oneshot = SHO_USED; | ||
129 | } | ||
130 | if (swap_hands_oneshot == SHO_ACTIVE) { | ||
131 | clear_oneshot_swaphands(); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | void clear_oneshot_swaphands(void) { | ||
136 | swap_hands_oneshot = SHO_OFF; | ||
137 | swap_hands = false; | ||
138 | # if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) | ||
139 | oneshot_swaphands_time = 0; | ||
140 | # endif | ||
141 | } | ||
142 | |||
89 | # endif | 143 | # endif |
90 | 144 | ||
91 | /** \brief Set oneshot layer | 145 | /** \brief Set oneshot layer |
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h index 1ce03ed0e..5dd8393da 100644 --- a/tmk_core/common/action_util.h +++ b/tmk_core/common/action_util.h | |||
@@ -77,6 +77,7 @@ void reset_oneshot_layer(void); | |||
77 | bool is_oneshot_layer_active(void); | 77 | bool is_oneshot_layer_active(void); |
78 | uint8_t get_oneshot_layer_state(void); | 78 | uint8_t get_oneshot_layer_state(void); |
79 | bool has_oneshot_layer_timed_out(void); | 79 | bool has_oneshot_layer_timed_out(void); |
80 | bool has_oneshot_swaphands_timed_out(void); | ||
80 | 81 | ||
81 | void oneshot_locked_mods_changed_user(uint8_t mods); | 82 | void oneshot_locked_mods_changed_user(uint8_t mods); |
82 | void oneshot_locked_mods_changed_kb(uint8_t mods); | 83 | void oneshot_locked_mods_changed_kb(uint8_t mods); |
@@ -88,6 +89,13 @@ void oneshot_layer_changed_kb(uint8_t layer); | |||
88 | /* inspect */ | 89 | /* inspect */ |
89 | uint8_t has_anymod(void); | 90 | uint8_t has_anymod(void); |
90 | 91 | ||
92 | #ifdef SWAP_HANDS_ENABLE | ||
93 | void set_oneshot_swaphands(void); | ||
94 | void release_oneshot_swaphands(void); | ||
95 | void use_oneshot_swaphands(void); | ||
96 | void clear_oneshot_swaphands(void); | ||
97 | #endif | ||
98 | |||
91 | #ifdef __cplusplus | 99 | #ifdef __cplusplus |
92 | } | 100 | } |
93 | #endif | 101 | #endif |