summaryrefslogtreecommitdiff
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 09e01d50d3..009477d203 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
|`SH_MOFF` |Momentarily turns off swap. |
|`SH_TG` |Toggles swap on and off with every key press. |
|`SH_TT` |Toggles with a tap; momentary when held. |
+|`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 18fd811184..40a46964a8 100644
--- a/docs/keycodes.md
+++ b/docs/keycodes.md
@@ -531,6 +531,7 @@ See also: [Swap Hands](feature_swap_hands.md)
|`SH_MOFF` |Momentarily turns off swap. |
|`SH_TG` |Toggles swap on and off with every key press. |
|`SH_TT` |Toggles with a tap; momentary when held. |
+|`SH_OS` |One shot swap hands: toggle while pressed or until next key press. |
## Unicode Support :id=unicode-support
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index 0958c4f4eb..d8f1fa4bbb 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -794,6 +794,7 @@ enum quantum_keycodes {
# define SH_T(kc) (QK_SWAP_HANDS | (kc))
# define SH_TG (QK_SWAP_HANDS | OP_SH_TOGGLE)
# define SH_TT (QK_SWAP_HANDS | OP_SH_TAP_TOGGLE)
+# define SH_OS (QK_SWAP_HANDS | OP_SH_ONESHOT)
# define SH_MON (QK_SWAP_HANDS | OP_SH_ON_OFF)
# define SH_MOFF (QK_SWAP_HANDS | OP_SH_OFF_ON)
# define SH_ON (QK_SWAP_HANDS | OP_SH_ON)
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index e5e9e27052..3b1268dc94 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -98,6 +98,11 @@ void action_exec(keyevent_t event) {
if (has_oneshot_mods_timed_out()) {
clear_oneshot_mods();
}
+# ifdef SWAP_HANDS_ENABLE
+ if (has_oneshot_swaphands_timed_out()) {
+ clear_oneshot_swaphands();
+ }
+# endif
# endif
#endif
@@ -165,6 +170,8 @@ void process_record_tap_hint(keyrecord_t *record) {
# ifdef SWAP_HANDS_ENABLE
case ACT_SWAP_HANDS:
switch (action.swap.code) {
+ case OP_SH_ONESHOT:
+ break;
case OP_SH_TAP_TOGGLE:
default:
swap_hands = !swap_hands;
@@ -224,7 +231,11 @@ void process_action(keyrecord_t *record, action_t action) {
#ifndef NO_ACTION_ONESHOT
bool do_release_oneshot = false;
// notice we only clear the one shot layer if the pressed key is not a modifier.
- if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)) {
+ if (is_oneshot_layer_active() && event.pressed && !IS_MOD(action.key.code)
+# ifdef SWAP_HANDS_ENABLE
+ && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)
+# endif
+ ) {
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
do_release_oneshot = !is_oneshot_layer_active();
}
@@ -593,6 +604,14 @@ void process_action(keyrecord_t *record, action_t action) {
swap_hands = false;
}
break;
+ case OP_SH_ONESHOT:
+ if (event.pressed) {
+ set_oneshot_swaphands();
+ } else {
+ release_oneshot_swaphands();
+ }
+ break;
+
# ifndef NO_ACTION_TAPPING
case OP_SH_TAP_TOGGLE:
/* tap toggle */
@@ -681,6 +700,12 @@ void process_action(keyrecord_t *record, action_t action) {
# endif
#endif
+#ifdef SWAP_HANDS_ENABLE
+ if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) {
+ use_oneshot_swaphands();
+ }
+#endif
+
#ifndef NO_ACTION_ONESHOT
/* Because we switch layers after a oneshot event, we need to release the
* 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 f80b7a782e..eea554ff21 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 {
OP_SH_OFF_ON,
OP_SH_OFF,
OP_SH_ON,
+ OP_SH_ONESHOT,
};
#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF()
#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE)
+#define ACTION_SWAP_HANDS_ONESHOT() ACTION(ACT_SWAP_HANDS, OP_SH_ONESHOT)
#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key)
#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF)
#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 335aa36e62..371acfa610 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;
inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
+# ifdef SWAP_HANDS_ENABLE
+enum {
+ SHO_OFF,
+ SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet
+ SHO_PRESSED, // Swap hands button is currently pressed
+ SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys
+} swap_hands_oneshot = SHO_OFF;
+# endif
+
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static uint16_t oneshot_layer_time = 0;
inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); }
+# ifdef SWAP_HANDS_ENABLE
+static uint16_t oneshot_swaphands_time = 0;
+inline bool has_oneshot_swaphands_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && !(swap_hands_oneshot >= SHO_PRESSED); }
+# endif
+# endif
+
+# ifdef SWAP_HANDS_ENABLE
+
+void set_oneshot_swaphands(void) {
+ swap_hands_oneshot = SHO_PRESSED;
+ swap_hands = true;
+# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ oneshot_swaphands_time = timer_read();
+ if (oneshot_layer_time != 0) {
+ oneshot_layer_time = oneshot_swaphands_time;
+ }
+# endif
+}
+
+void release_oneshot_swaphands(void) {
+ if (swap_hands_oneshot == SHO_PRESSED) {
+ swap_hands_oneshot = SHO_ACTIVE;
+ }
+ if (swap_hands_oneshot == SHO_USED) {
+ clear_oneshot_swaphands();
+ }
+}
+
+void use_oneshot_swaphands(void) {
+ if (swap_hands_oneshot == SHO_PRESSED) {
+ swap_hands_oneshot = SHO_USED;
+ }
+ if (swap_hands_oneshot == SHO_ACTIVE) {
+ clear_oneshot_swaphands();
+ }
+}
+
+void clear_oneshot_swaphands(void) {
+ swap_hands_oneshot = SHO_OFF;
+ swap_hands = false;
+# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
+ oneshot_swaphands_time = 0;
+# endif
+}
+
# endif
/** \brief Set oneshot layer
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h
index 1ce03ed0e4..5dd8393da4 100644
--- a/tmk_core/common/action_util.h
+++ b/tmk_core/common/action_util.h
@@ -77,6 +77,7 @@ void reset_oneshot_layer(void);
bool is_oneshot_layer_active(void);
uint8_t get_oneshot_layer_state(void);
bool has_oneshot_layer_timed_out(void);
+bool has_oneshot_swaphands_timed_out(void);
void oneshot_locked_mods_changed_user(uint8_t mods);
void oneshot_locked_mods_changed_kb(uint8_t mods);
@@ -88,6 +89,13 @@ void oneshot_layer_changed_kb(uint8_t layer);
/* inspect */
uint8_t has_anymod(void);
+#ifdef SWAP_HANDS_ENABLE
+void set_oneshot_swaphands(void);
+void release_oneshot_swaphands(void);
+void use_oneshot_swaphands(void);
+void clear_oneshot_swaphands(void);
+#endif
+
#ifdef __cplusplus
}
#endif