aboutsummaryrefslogtreecommitdiff
path: root/tmk_core
diff options
context:
space:
mode:
authorZsolt Parragi <zsolt.parragi@cancellar.hu>2020-05-13 23:36:55 +0200
committerGitHub <noreply@github.com>2020-05-14 07:36:55 +1000
commit805f5cb72bb04c10327b40ed0c41e3848ad9ca75 (patch)
tree249680bec133e18dd2399b80cbeb14e980f1095c /tmk_core
parenta8a8bf0ff3d6e1c9637079b925b30cf7eb8913fd (diff)
downloadqmk_firmware-805f5cb72bb04c10327b40ed0c41e3848ad9ca75.tar.gz
qmk_firmware-805f5cb72bb04c10327b40ed0c41e3848ad9ca75.zip
One shot support for swap hands (#8590)
This commits add the SH_OS keycode, which works similarly to one shot layers: * while pressed, the keyboard is swapped * if no keys were pressed while it was pressed, the next key press is swapped SH_OS also supports chaining with one shot layers: OSL(x) + SH_OS + key interprets the key press on the oneshot layer. The ONESHOT_TIMEOUT setting used by one shot keys and layers is also used by oneshot swap hands. In the above chaining scenario the timeout of the oneshot layer is reset when swap hands is activated. Resolves #2682
Diffstat (limited to 'tmk_core')
-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
4 files changed, 90 insertions, 1 deletions
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