tapping the layer lock key again releases the Win key and takes you off of that layer
there are other keys on the layer that do not have the Win key held down - i.e., either the other keys release the Win key before they do anything, or the 0-9 keys have the Win key held down the first time they are pressed on the layer
How do I do that? The simplest approach does not work because with the new revisions, a macro can’t release a key that it didn’t press.
Upon closer examination, I am not sure this is true. The docs say:
Macros now operates by manipulating keys on a small supplemental virtual keyboard when using Macros.press() and Macros.release() (which are called by D() and U(), et al, respectively). This means that it has no built-in facility for releasing other keys that are held on the keyboard.
So it looks like if a key was pressed by one macro on the virtual keyboard, another one could release it.
The problem is that this doesn’t work:
case M_Purple:
if (keyToggledOn(event.state)) {
if (Layer.isActive(PURPLELAYER)) {
Layer.deactivate(PURPLELAYER);
return MACRO(U(LeftGui));
}
else {
Layer.activate(PURPLELAYER);
return MACRO(D(LeftGui));
}
}
break;
What happens is that running this macro doesn’t hold down the Win key, it just taps it, even though I’m using the D macro!
Looking at the docs, I see that the macro doesn’t hold keys… but I can’t use event.key or Macros.press, either, since those options will release the modifier after I release the macro key.
So how do I make a macro that holds down a modifier?
@gdxpr in the Discord was able to help me and was kind enough to write a small custom plugin to do this.
I put ML(LeftGui, PURPLELAYER) in the keymap - these are the new ModLayer keys that combine a mod with a ShiftToLayer.
Then to make it lock, I needed this plugin:
namespace kaleidoscope {
namespace plugin {
class AutoStickyGuiLayer : public Plugin {
public:
EventHandlerResult onKeyEvent(KeyEvent &event) {
if (keyToggledOn(event.state) &&
event.key == ML(LeftGui, PURPLELAYER) &&
!::OneShot.isSticky(event.addr)) {
::OneShot.setSticky(event.addr);
// To stop OneShot from processing this as an event that cancels the
// sticky key, we mark it as "injected".
event.state |= INJECTED;
}
return EventHandlerResult::OK;
}
};
} // namespace plugin
} // namespace kaleidoscope
Then I just had to put AutoStickyGuiLayer in KALEIDOSCOPE_INIT_PLUGINS somewhere after OneShot.