aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/feature_swap_hands.md1
-rw-r--r--docs/keycodes.md1
-rw-r--r--quantum/quantum_keycodes.h1
-rw-r--r--tmk_core/common/action.c27
-rw-r--r--tmk_core/common/action_code.h2
-rw-r--r--tmk_core/common/action_util.c54
-rw-r--r--tmk_core/common/action_util.h8
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;
83inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; } 83inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
84inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; } 84inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
85 85
86# ifdef SWAP_HANDS_ENABLE
87enum {
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))
87static uint16_t oneshot_layer_time = 0; 96static uint16_t oneshot_layer_time = 0;
88inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); } 97inline 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
99static uint16_t oneshot_swaphands_time = 0;
100inline 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
106void 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
117void 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
126void 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
135void 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);
77bool is_oneshot_layer_active(void); 77bool is_oneshot_layer_active(void);
78uint8_t get_oneshot_layer_state(void); 78uint8_t get_oneshot_layer_state(void);
79bool has_oneshot_layer_timed_out(void); 79bool has_oneshot_layer_timed_out(void);
80bool has_oneshot_swaphands_timed_out(void);
80 81
81void oneshot_locked_mods_changed_user(uint8_t mods); 82void oneshot_locked_mods_changed_user(uint8_t mods);
82void oneshot_locked_mods_changed_kb(uint8_t mods); 83void oneshot_locked_mods_changed_kb(uint8_t mods);
@@ -88,6 +89,13 @@ void oneshot_layer_changed_kb(uint8_t layer);
88/* inspect */ 89/* inspect */
89uint8_t has_anymod(void); 90uint8_t has_anymod(void);
90 91
92#ifdef SWAP_HANDS_ENABLE
93void set_oneshot_swaphands(void);
94void release_oneshot_swaphands(void);
95void use_oneshot_swaphands(void);
96void clear_oneshot_swaphands(void);
97#endif
98
91#ifdef __cplusplus 99#ifdef __cplusplus
92} 100}
93#endif 101#endif