Oneshot not deactivating after a macro: how to fix?

I’m trying to get a key to generate different strings, depending on whether shift has been pressed. This to be able to speed up typing common sequences like “th” and “Th”. I can generate these strings, but the interaction with OneShot modifiers surprised me.

If I hit a key that triggers a macro the oneshot modifier remains active until I hit the next key that does not contain a macro. This also happens with the anykey macro that is in the default firmware, so I assume this is expected behavior. Unfortunately it evades me how to get the behavior I want to prevent the next key having shift applied.

Can anyone give me a hint how I can adapt the macro below to ensure that it does indeed deactivate the modifier. The first attempt at the macro I put together is below (it would be more ideal to have a function I can feed shifted/unshifted strings to, but this at least got me close to what I want).

case MACRO_TH:
if (keyToggledOn(keyState)) {
if ( wasShiftActive() ) {
return Macros.type(PSTR(“Th”));
} else {
return Macros.type(PSTR(“th”));
}
}
break;

in which I have used:

bool wasShiftActive() {
return kaleidoscope::hid::wasModifierKeyActive(Key_LeftShift) ||
kaleidoscope::hid::wasModifierKeyActive(Key_RightShift);
}

This is one of the cases where the order in which you list plugins in KALEIDOSCOPE_INIT_PLUGINS matters. If you put Macros first, it will swallow the key event when you press a macro key, and OneShot won’t see it, and thus, won’t be able to interrupt itself. Place OneShot ahead of Macros in the list, and things should work after that.

Hope this helps!

Many thanks for your response and insight. Moving OneShot ahead of Macros in the list indeed fixes the problem!

Now sticking this in a function I can reuse also works. For those that try similar things. I ended up with:

static void macroShifted (const char* unshifted, const char* shifted) {
  if (kaleidoscope::hid::wasModifierKeyActive(Key_LeftShift) ||
      kaleidoscope::hid::wasModifierKeyActive(Key_RightShift)) {
    Macros.type(shifted);
  } else {
    Macros.type(unshifted);
  }

using a macro like

case MACRO_TH:
      if (keyToggledOn(keyState)) {
        macroShifted(PSTR("th"),PSTR("Th"));
      }
      break;

The only thing I can’t yet get to work is to get the keys to repeat in a sensible manner when held. :frowning:

1 Like