Browse Source

Add ability to toggle One Shot functionality (#4198)

Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Ryan <fauxpark@gmail.com>
Drashna Jaelre 4 years ago
parent
commit
0e984b6e7e

+ 3 - 0
docs/keycodes.md

@@ -516,6 +516,9 @@ See also: [One Shot Keys](one_shot_keys.md)
 |------------|----------------------------------|
 |`OSM(mod)`  |Hold `mod` for one keypress       |
 |`OSL(layer)`|Switch to `layer` for one keypress|
+|`OS_ON`     |Turns One Shot keys on            |
+|`OS_OFF`    |Turns One Shot keys off           |
+|`OS_TOGG`   |Toggles One Shot keys status      |
 
 ## Space Cadet :id=space-cadet
 

+ 3 - 0
docs/one_shot_keys.md

@@ -17,6 +17,9 @@ You can control the behavior of one shot keys by defining these in `config.h`:
 
 * `OSM(mod)` - Momentarily hold down *mod*. You must use the `MOD_*` keycodes as shown in [Mod Tap](mod_tap.md), not the `KC_*` codes.
 * `OSL(layer)` - momentary switch to *layer*.
+* `OS_ON` - Turns on One Shot keys.
+* `OS_OFF` - Turns off One Shot keys. OSM act as regular mod keys, OSL act like `MO`.
+* `ON_TOGG` - Toggles the one shot key status.
 
 Sometimes, you want to activate a one-shot key as part of a macro or tap dance routine.  
 

+ 1 - 0
quantum/keycode_config.h

@@ -37,6 +37,7 @@ typedef union {
         bool nkro : 1;
         bool swap_lctl_lgui : 1;
         bool swap_rctl_rgui : 1;
+        bool oneshot_disable : 1;
     };
 } keymap_config_t;
 

+ 11 - 0
quantum/quantum.c

@@ -318,6 +318,17 @@ bool process_record_quantum(keyrecord_t *record) {
             case OUT_BT:
                 set_output(OUTPUT_BLUETOOTH);
                 return false;
+#endif
+#ifndef NO_ACTION_ONESHOT
+            case ONESHOT_TOGGLE:
+                oneshot_toggle();
+                break;
+            case ONESHOT_ENABLE:
+                oneshot_enable();
+                break;
+            case ONESHOT_DISABLE:
+                oneshot_disable();
+                break;
 #endif
         }
     }

+ 9 - 0
quantum/quantum_keycodes.h

@@ -578,6 +578,10 @@ enum quantum_keycodes {
 
 #endif
 
+    ONESHOT_ENABLE,
+    ONESHOT_DISABLE,
+    ONESHOT_TOGGLE,
+
     // always leave at the end
     SAFE_RANGE
 };
@@ -885,3 +889,8 @@ enum quantum_keycodes {
 #define DM_RSTP DYN_REC_STOP
 #define DM_PLY1 DYN_MACRO_PLAY1
 #define DM_PLY2 DYN_MACRO_PLAY2
+
+// One Shot toggle
+#define OS_TOGG ONESHOT_TOGGLE
+#define OS_ON   ONESHOT_ENABLE
+#define OS_OFF  ONESHOT_DISABLE

+ 49 - 9
tmk_core/common/action_util.c

@@ -147,12 +147,16 @@ void clear_oneshot_swaphands(void) {
  * FIXME: needs doc
  */
 void set_oneshot_layer(uint8_t layer, uint8_t state) {
-    oneshot_layer_data = layer << 3 | state;
-    layer_on(layer);
+    if (!keymap_config.oneshot_disable) {
+        oneshot_layer_data = layer << 3 | state;
+        layer_on(layer);
 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
-    oneshot_layer_time = timer_read();
+        oneshot_layer_time = timer_read();
 #    endif
-    oneshot_layer_changed_kb(get_oneshot_layer());
+        oneshot_layer_changed_kb(get_oneshot_layer());
+    } else {
+        layer_on(layer);
+    }
 }
 /** \brief Reset oneshot layer
  *
@@ -172,7 +176,7 @@ void reset_oneshot_layer(void) {
 void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
     uint8_t start_state = oneshot_layer_data;
     oneshot_layer_data &= ~state;
-    if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) {
+    if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) {
         layer_off(get_oneshot_layer());
         reset_oneshot_layer();
     }
@@ -182,6 +186,39 @@ void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
  * FIXME: needs doc
  */
 bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); }
+
+/** \brief set oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_set(bool active) {
+    if (keymap_config.oneshot_disable != active) {
+        keymap_config.oneshot_disable = active;
+        eeconfig_update_keymap(keymap_config.raw);
+        dprintf("Oneshot: active: %d\n", active);
+    }
+}
+
+/** \brief toggle oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_toggle(void) { oneshot_set(!keymap_config.oneshot_disable); }
+
+/** \brief enable oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_enable(void) { oneshot_set(true); }
+
+/** \brief disable oneshot
+ *
+ * FIXME: needs doc
+ */
+void oneshot_disable(void) { oneshot_set(false); }
+
+bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; }
+
 #endif
 
 /** \brief Send keyboard report
@@ -321,14 +358,17 @@ void del_oneshot_mods(uint8_t mods) {
  * FIXME: needs doc
  */
 void set_oneshot_mods(uint8_t mods) {
-    if (oneshot_mods != mods) {
+    if (!keymap_config.oneshot_disable) {
+        if (oneshot_mods != mods) {
 #    if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
-        oneshot_time = timer_read();
+            oneshot_time = timer_read();
 #    endif
-        oneshot_mods = mods;
-        oneshot_mods_changed_kb(mods);
+            oneshot_mods = mods;
+            oneshot_mods_changed_kb(mods);
+        }
     }
 }
+
 /** \brief clear oneshot mods
  *
  * FIXME: needs doc

+ 5 - 0
tmk_core/common/action_util.h

@@ -85,6 +85,11 @@ void oneshot_mods_changed_kb(uint8_t mods);
 void oneshot_layer_changed_user(uint8_t layer);
 void oneshot_layer_changed_kb(uint8_t layer);
 
+void oneshot_toggle(void);
+void oneshot_enable(void);
+void oneshot_disable(void);
+bool is_oneshot_enabled(void);
+
 /* inspect */
 uint8_t has_anymod(void);