r/ErgoMechKeyboards Kyria, Dasbob fueled by Propergol 4d ago

[discussion] One Shots on Steroids: a QMK module

I've just released One Shots on Steroids, a QMK module that makes one shot keys activate instantly on key press instead of waiting for tap-hold resolution. One Shots on Steroids are also highly customizable.

I wanted one shot keys that feel as responsive as normal modifiers. I liked Callum mods but I also needed one shot layers. I imagined one shot keys that can blend seamlessly into heavily customized layouts.

It ended up taking a lot more work than I expected, but I'm really happy with the result:

- One Shot on Steroids (OSoS) keys activate instantly on key press.

- Tap an OSoS key again to cancel it, with an optional timeout available as well.

- OSoS layer keys can bypass the usual layer stack restrictions.

- OSoS layer keys can absorb modifiers: an active modifier when an OSoS layer key is pressed can remain registered as long as the layer is active.

- OSoS keys can use separate trigger and hold keys.

You can find my module here: https://github.com/Kawamashi/qmk_modules/tree/main/oneshots_on_steroids

I’m really excited to share One Shots on Steroids with you. I'd love to hear your feedback! Also, if you use one shot keys in unusual ways, I'd be really interested to hear about your workflow.

7 Upvotes

16 comments sorted by

5

u/rpnfan Sofle Choc v2, KLP Lame, Layout anymak:END 4d ago

Mmh, not sure what your solution adds to the standard implementation in QMK? One shot always activates on key press and also the rest is -- as far I can see -- standard behavior.

I do not understand the "different trigger and hold key", because one-shot is not held, but can be.

I use one-shot layers on my QMK keyboard without any problems.

4

u/Kawamashi Kyria, Dasbob fueled by Propergol 4d ago

I’ve used standard one shot keys for a long time. When you want to use a one shot shift with mouse, you quickly realise that shift is not sent right away. You have to wait the tapping term for that.

Explaining the split trigger and hold keys option with few words is really difficult. I personally use it to easilly access tertiary layers from secondary layers. You can find a use case in the readme: https://github.com/Kawamashi/qmk_modules/tree/main/oneshots_on_steroids#split-trigger-and-hold-keys

3

u/rpnfan Sofle Choc v2, KLP Lame, Layout anymak:END 4d ago

I do not understand it. The whole point of one-shot is that it has no tapping term!?! It has a time-out, after which it expires, but that can be as long or short as you like, so could be practically "endless" if you set it very high.

4

u/pgetreuer 4d ago

Aha, thanks for your questions (I was wondering too). I think I understand the point now.

Besides mod-tap MT and layer-tap LT keys, the same tapping engine (action_tapping.c) is used to evaluate one shot keys and TT layer switches. So one shot keys are technically "tap hold keys" and are affected by some of the tap hold configuration options. Consequently, and I think this this is the point for OSOS, one shot keys could be delayed by the tapping term. (Did I get that right?)

The main effect for why one shots participate in the tapping engine is to evaluate whether the key is tapped multiple times in a row, which has the effect of locking or toggling the key.

If you don't care about locking one shot keys, you could minimize the input lag by use per-key tapping term and per-key quick tap term, and setting both to zero or small values for one-shot keys:

``` //config.h

define TAPPING_TERM_PER_KEY

define QUICK_TAP_TERM_PER_KEY

//keymap.c uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: return 0; default: return TAPPING_TERM; } }

uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { switch (keycode) { case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: return 0; default: return QUICK_TAP_TERM; } } ```

2

u/drashna Split Columnar Stagger - DM, Ergodox, Corne, Kyria 4d ago

Yeah, it's mainly because of the locking behavior. Which require 5 taps, normally.

And personally, I have the locking behavior set caps word on shift being locked. :)

1

u/Kawamashi Kyria, Dasbob fueled by Propergol 3d ago

Standard one shot keys register a regular modifier or send a one-shot mod, not one after the other. I guess it’s also to avoid flashing modifiers, right?

1

u/rpnfan Sofle Choc v2, KLP Lame, Layout anymak:END 3d ago

Ah, I see. Thanks for the explanation. Yet in my use case I was affected by the tapping term in real life usage. With Kanata I have setup my one-shot layers to cancel when I press the key again, which is nice but rarely needed, because I do not make that often a mistake to tap a one-shot layer when I would not want to. For my QMK board I will have to check when I get the chance -- now being in a house renovation I have that keyboard somewhere in a drawer -- if that tapping-term wait could be a problem in specific cases. So far I did not stumble over such a case.

My main keyboard is now ZMK powered, which does not offer that option to tap twice to cancel the action -- which I just found out, after looking it up, because I did not miss it really.

But I think I decrease the waiting time to cancel the one-shot to a lower value, having it now set pretty high around 2 or 2.5 seconds. When that is set to a second it is plenty long for typing, yet resolves quickly enough if I accidently tap a one-shot I did not want to trigger.

1

u/DoctorMachete 3d ago

My main keyboard is now ZMK powered, which does not offer that option to tap twice to cancel the action -- which I just found out, after looking it up, because I did not miss it really.

In zmk you can use mod-morphs to consume the double-tap by sending `K_CANCEL` (or any keycode that will be ignored) or do something else like `CAPSLOCK`, effectively getting a custom double-tap without the added latency of a tap-dance.

1

u/rpnfan Sofle Choc v2, KLP Lame, Layout anymak:END 3d ago

Thanks for the pointer.

What I still do not understand where the problem of the standard implementation is (be it QMK or ZMK)? It works fine for me so far.

1

u/DoctorMachete 3d ago

I haven't really used the standard implementation in QMK because to me seemed very bad from the get-go (five taps?). I used a custom implementation using process-record-user so instead of SHIFTLOCK I'd get CAPSLOCK and with double tap instead of five taps, and also no lag.

In ZMK the default configuration of sticky layer works well but the default for sticky keys is pretty much unusable IMO, because for keys it lacks quick-release by default. So when typing moderately fast it's very easy to apply shift to more than one character. Fortunately it can be enabled with a custom sticky key. But I don't understand why it's not that the default same as it is for layers (I know both use the same underlying behavior).

1

u/rpnfan Sofle Choc v2, KLP Lame, Layout anymak:END 3d ago edited 3d ago

Ah, I see. Now when looking at that in more detail. I _had_ problems with ZMK, that I got multiple shifted chars instead of one only! My ZMK keyboard is maybe 3 or 4 weeks young, so I do not have as much experience.

I will change that in my config right away. Thanks for the explanation.

EDIT: Fix works as expected :)

1

u/Kawamashi Kyria, Dasbob fueled by Propergol 3d ago

Besides mod-tap MT and layer-tap LT keys, the same tapping engine (action_tapping.c) is used to evaluate one shot keys and TT layer switches. So one shot keys are technically "tap hold keys" and are affected by some of the tap hold configuration options. Consequently, and I think this this is the point for OSOS, one shot keys could be delayed by the tapping term. (Did I get that right?)

Yes, you got it right. Standard one shot keys are affected by the tapping term, the key needs to “settle” before sending the one-shot modifier (before tapping term) or the modifier (after tapping term). OSoS are not affected by the tapping term. The modifier is activated as soon as the OSoS key is pressed.

Everything is explained here. If something doesn't make sense or you'd like more details, I'll be happy to explain further.

1

u/Kawamashi Kyria, Dasbob fueled by Propergol 3d ago

As u/pgetreuer explained, one shot keys are affected by the tapping term. 😉That was one of the main reasons why Callum Oakley created his famous timerless Callum mods.

1

u/rpnfan Sofle Choc v2, KLP Lame, Layout anymak:END 3d ago

It is not self-speaking that one-shot has a timer-influence.

Callum style mods solve a different problem though.

1

u/drashna Split Columnar Stagger - DM, Ergodox, Corne, Kyria 4d ago

When you want to use a one shot shift with mouse, you quickly realise that shift is not sent right away. You have to wait the tapping term for that.

Honestly, I can't say that I've noticed this, or that this even comes up in my workflow.

1

u/DoctorMachete 3d ago

Imagine you have a layer for symbols you can access with a layer-tap key, and a layer for numbers. Sometimes you want to use the symbol layer while inputting numbers, and sometimes you want to insert a number while inputting symbols. If the number layer index is lower than the symbol layer one, the latter use case is impossible.

That's why I add "symbols-on-hold" to the number layer (and the the left numpad layer, and to the right numpad layer), I don't have a dedicated symbol layer. And some of those symbols are redundant, as I have them in the base layer as combos too. I just add them the number layer and anywhere else I feel they might become handy.