# Need help making a layer that has a modifier key held down for some keys

**URL:** <https://community.keyboard.io/t/need-help-making-a-layer-that-has-a-modifier-key-held-down-for-some-keys/5889>\
**Category:** Programming\
**Tags:** question\
**Created:** [November 2, 2022, 12:52pm UTC](https://community.keyboard.io/t/need-help-making-a-layer-that-has-a-modifier-key-held-down-for-some-keys/5889 "2022-11-02T12:52:29Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [November 2, 2022, 12:52pm UTC](https://community.keyboard.io/t/need-help-making-a-layer-that-has-a-modifier-key-held-down-for-some-keys/5889/1 "2022-11-02T12:52:29Z")

</div>

I want to make a layer that works like this:

- tapping the layer lock key holds the Win key down
- there are keys on that layer for tapping 0-9
- 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. ☹

---

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [November 3, 2022, 9:17am UTC](https://community.keyboard.io/t/need-help-making-a-layer-that-has-a-modifier-key-held-down-for-some-keys/5889/2 "2022-11-03T09:17:55Z")

</div>

> [@fire](#):
>
> 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.

[https://kaleidoscope.readthedocs.io/en/latest/UPGRADING.html](https://kaleidoscope.readthedocs.io/en/latest/UPGRADING.html)

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:

```auto
  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?

---

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [November 7, 2022, 2:26am UTC](https://community.keyboard.io/t/need-help-making-a-layer-that-has-a-modifier-key-held-down-for-some-keys/5889/3 "2022-11-07T02:26:49Z")

</div>

@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:

```auto
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.
