Skip to content

Commit caba8be

Browse files
drashnatzarcfauxpark
authored
Add ability to toggle One Shot functionality (qmk#4198)
Co-authored-by: Nick Brassel <[email protected]> Co-authored-by: Ryan <[email protected]>
1 parent a9ebf04 commit caba8be

File tree

7 files changed

+81
-9
lines changed

7 files changed

+81
-9
lines changed

docs/keycodes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,9 @@ See also: [One Shot Keys](one_shot_keys.md)
516516
|------------|----------------------------------|
517517
|`OSM(mod)` |Hold `mod` for one keypress |
518518
|`OSL(layer)`|Switch to `layer` for one keypress|
519+
|`OS_ON` |Turns One Shot keys on |
520+
|`OS_OFF` |Turns One Shot keys off |
521+
|`OS_TOGG` |Toggles One Shot keys status |
519522

520523
## Space Cadet :id=space-cadet
521524

docs/one_shot_keys.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ You can control the behavior of one shot keys by defining these in `config.h`:
1717
1818
* `OSM(mod)` - Momentarily hold down *mod*. You must use the `MOD_*` keycodes as shown in [Mod Tap](mod_tap.md), not the `KC_*` codes.
1919
* `OSL(layer)` - momentary switch to *layer*.
20+
* `OS_ON` - Turns on One Shot keys.
21+
* `OS_OFF` - Turns off One Shot keys. OSM act as regular mod keys, OSL act like `MO`.
22+
* `ON_TOGG` - Toggles the one shot key status.
2023
2124
Sometimes, you want to activate a one-shot key as part of a macro or tap dance routine.
2225

quantum/keycode_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ typedef union {
3737
bool nkro : 1;
3838
bool swap_lctl_lgui : 1;
3939
bool swap_rctl_rgui : 1;
40+
bool oneshot_disable : 1;
4041
};
4142
} keymap_config_t;
4243

quantum/quantum.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,17 @@ bool process_record_quantum(keyrecord_t *record) {
318318
case OUT_BT:
319319
set_output(OUTPUT_BLUETOOTH);
320320
return false;
321+
#endif
322+
#ifndef NO_ACTION_ONESHOT
323+
case ONESHOT_TOGGLE:
324+
oneshot_toggle();
325+
break;
326+
case ONESHOT_ENABLE:
327+
oneshot_enable();
328+
break;
329+
case ONESHOT_DISABLE:
330+
oneshot_disable();
331+
break;
321332
#endif
322333
}
323334
}

quantum/quantum_keycodes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,10 @@ enum quantum_keycodes {
578578

579579
#endif
580580

581+
ONESHOT_ENABLE,
582+
ONESHOT_DISABLE,
583+
ONESHOT_TOGGLE,
584+
581585
// always leave at the end
582586
SAFE_RANGE
583587
};
@@ -885,3 +889,8 @@ enum quantum_keycodes {
885889
#define DM_RSTP DYN_REC_STOP
886890
#define DM_PLY1 DYN_MACRO_PLAY1
887891
#define DM_PLY2 DYN_MACRO_PLAY2
892+
893+
// One Shot toggle
894+
#define OS_TOGG ONESHOT_TOGGLE
895+
#define OS_ON ONESHOT_ENABLE
896+
#define OS_OFF ONESHOT_DISABLE

tmk_core/common/action_util.c

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,16 @@ void clear_oneshot_swaphands(void) {
147147
* FIXME: needs doc
148148
*/
149149
void set_oneshot_layer(uint8_t layer, uint8_t state) {
150-
oneshot_layer_data = layer << 3 | state;
151-
layer_on(layer);
150+
if (!keymap_config.oneshot_disable) {
151+
oneshot_layer_data = layer << 3 | state;
152+
layer_on(layer);
152153
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
153-
oneshot_layer_time = timer_read();
154+
oneshot_layer_time = timer_read();
154155
# endif
155-
oneshot_layer_changed_kb(get_oneshot_layer());
156+
oneshot_layer_changed_kb(get_oneshot_layer());
157+
} else {
158+
layer_on(layer);
159+
}
156160
}
157161
/** \brief Reset oneshot layer
158162
*
@@ -172,7 +176,7 @@ void reset_oneshot_layer(void) {
172176
void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
173177
uint8_t start_state = oneshot_layer_data;
174178
oneshot_layer_data &= ~state;
175-
if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) {
179+
if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) || keymap_config.oneshot_disable) {
176180
layer_off(get_oneshot_layer());
177181
reset_oneshot_layer();
178182
}
@@ -182,6 +186,39 @@ void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
182186
* FIXME: needs doc
183187
*/
184188
bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); }
189+
190+
/** \brief set oneshot
191+
*
192+
* FIXME: needs doc
193+
*/
194+
void oneshot_set(bool active) {
195+
if (keymap_config.oneshot_disable != active) {
196+
keymap_config.oneshot_disable = active;
197+
eeconfig_update_keymap(keymap_config.raw);
198+
dprintf("Oneshot: active: %d\n", active);
199+
}
200+
}
201+
202+
/** \brief toggle oneshot
203+
*
204+
* FIXME: needs doc
205+
*/
206+
void oneshot_toggle(void) { oneshot_set(!keymap_config.oneshot_disable); }
207+
208+
/** \brief enable oneshot
209+
*
210+
* FIXME: needs doc
211+
*/
212+
void oneshot_enable(void) { oneshot_set(true); }
213+
214+
/** \brief disable oneshot
215+
*
216+
* FIXME: needs doc
217+
*/
218+
void oneshot_disable(void) { oneshot_set(false); }
219+
220+
bool is_oneshot_enabled(void) { return keymap_config.oneshot_disable; }
221+
185222
#endif
186223

187224
/** \brief Send keyboard report
@@ -321,14 +358,17 @@ void del_oneshot_mods(uint8_t mods) {
321358
* FIXME: needs doc
322359
*/
323360
void set_oneshot_mods(uint8_t mods) {
324-
if (oneshot_mods != mods) {
361+
if (!keymap_config.oneshot_disable) {
362+
if (oneshot_mods != mods) {
325363
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
326-
oneshot_time = timer_read();
364+
oneshot_time = timer_read();
327365
# endif
328-
oneshot_mods = mods;
329-
oneshot_mods_changed_kb(mods);
366+
oneshot_mods = mods;
367+
oneshot_mods_changed_kb(mods);
368+
}
330369
}
331370
}
371+
332372
/** \brief clear oneshot mods
333373
*
334374
* FIXME: needs doc

tmk_core/common/action_util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ void oneshot_mods_changed_kb(uint8_t mods);
8585
void oneshot_layer_changed_user(uint8_t layer);
8686
void oneshot_layer_changed_kb(uint8_t layer);
8787

88+
void oneshot_toggle(void);
89+
void oneshot_enable(void);
90+
void oneshot_disable(void);
91+
bool is_oneshot_enabled(void);
92+
8893
/* inspect */
8994
uint8_t has_anymod(void);
9095

0 commit comments

Comments
 (0)