# LockLayer as a secondary (held) action?

**URL:** <https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666>\
**Category:** Programming\
**Created:** [October 3, 2022, 4:47am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666 "2022-10-03T04:47:01Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Moilleadoir](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/moilleadoir/32/4122_2.png) [@Moilleadoir](https://community.keyboard.io/u/Moilleadoir)\
**Post date:** [October 3, 2022, 4:47am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/1 "2022-10-03T04:47:01Z")

</div>

Is this possible?

I would rarely use the numpad layer, so considering moving it to N.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [October 3, 2022, 7:30pm UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/2 "2022-10-03T19:30:35Z")

</div>

Yes, it is possible, but not yet configurable via Chrysalis. You can set this up by defining a `Qukey` object in a Kaleidoscope sketch, and compiling custom firmware.

---

<div class="post-metadata">

**Author:** ![Moilleadoir](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/moilleadoir/32/4122_2.png) [@Moilleadoir](https://community.keyboard.io/u/Moilleadoir)\
**Post date:** [October 5, 2022, 7:48am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/3 "2022-10-05T07:48:26Z")

</div>

Thanks for the reply. My next question is can I also toggle an LED on the key as an indicator?

I’m guessing this would need to be in a macro, with the code toggling the layer & LED state, but I’m not sure how to get the layer state.

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [October 5, 2022, 10:37am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/4 "2022-10-05T10:37:10Z")

</div>

If you want the color to override any existing LED effect, the best way to implement this is not a macro, but a custom little plugin, something along these lines:

```nohighlight
EventHandlerResult afterEachCycle() {
  if (Layer.isActive(N)) {
    LEDControl.setCrgbAt(KeyAddr(ROW, COL), CRGB(R, G,B ));
  } else {
    LEDControl.refreshAt(KeyAddr(ROW, COL));
  }

  return EventHandlerResult::OK;
}

```

…where `ROW` and `COL` are the row & column of your layer lock key you want to highlight, and `R, G, B` are the red, green, blue components of the color you want to use.

The disadvantage is that you have to hard code the location - or scan the active keymap to discover the key, or do some other tricks to figure out what to highlight. The upside is that this does override any active LED effects, while doing it via a macro would set the color, but if you have any effects active that do animation, those would reset the color to whatever the effect thinks it should be.

If you don’t mind that, the macro way is something like this:

```nohighlight
void moveToAndHighlight(const uint8_t macro_index, KeyEvent &event) {
  if (!KeyToggledOn(event.state)) return;

  if (Layer.isActive(N)) {
    Layer.deactivate(N);
    LEDControl.refreshAt(event.addr);
  } else {
    Layer.activate(N);
    LEDControl.setCrgbAt(event.addr, CRGB(R, G, B));
  }
};

```

---

<div class="post-metadata">

**Author:** ![Moilleadoir](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/moilleadoir/32/4122_2.png) [@Moilleadoir](https://community.keyboard.io/u/Moilleadoir)\
**Post date:** [October 5, 2022, 11:08am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/5 "2022-10-05T11:08:02Z")

</div>

Thanks, that seems straightforward. I’ll stick with the macro for now as I won’t normally have an effect active & I’d have to read up on plugins to implement a plugin.

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [October 5, 2022, 11:12am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/6 "2022-10-05T11:12:58Z")

</div>

Plugins may sound scary, and intimidating, or complicated, but… they’re not. To use the first snippet above as a plugin, you’d just wrap it like this:

```nohighlight
namespace kaleidoscope {
class MoveAndHighlight: public kaleidoscope::Plugin {
 public:
  EventHandlerResult afterEachCycle() { /* the code from above */ }
};
}
kaleidoscope::MoveAndHighlight MoveAndHighlight;

```

…and then you just stick it somewhere into `KALEIDOSCOPE_INIT_PLUGINS`, preferably near the end so it can override whatever comes before it, and you’re all set.

But if you’re not planning to use any LED effects, then the macro is likely simpler, indeed.

---

<div class="post-metadata">

**Author:** ![Moilleadoir](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/moilleadoir/32/4122_2.png) [@Moilleadoir](https://community.keyboard.io/u/Moilleadoir)\
**Post date:** [October 6, 2022, 5:31am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/7 "2022-10-06T05:31:55Z")

</div>

So you can include the plugin code in the same .ino file?

I’ve run into another problem using this idea to swap to another layer. The examples only define the Qukey for layer 0 (so there’s no return if the triggering key isn’t transparent) but when I try using `Qukeys::layer_wildcard` instead I get errors.

```auto
  QUKEYS(
    kaleidoscope::plugin::Qukey(0, KeyAddr(3, 10), LockLayer(NUMPAD)), // N/Numpad layer
    kaleidoscope::plugin::Qukey(Qukeys::layer_wildcard, KeyAddr(2, 5), M(MACRO_SRAITH_G)) // G/Sraith Gaelach
  )

```

```auto
Model100-Sean:847:32: error: expected primary-expression before '(' token
  847 | kaleidoscope::plugin::Qukey(Qukeys::layer_wildcard, KeyAddr(2, 5), M(MACRO_SRAITH_G)) // G/Sraith Gaelach

```

I suppose I’m using this wrong. I could always use a definition for each layer.

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [October 6, 2022, 10:00am UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/8 "2022-10-06T10:00:15Z")

</div>

> [@Moilleadoir](#):
>
> So you can include the plugin code in the same .ino file?

Yep! A plugin is just an instance of a C++ class. You can implement it wherever you want to.

---

<div class="post-metadata">

**Author:** ![merlin](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/merlin/32/3416_2.png) [@merlin](https://community.keyboard.io/u/merlin)\
**Post date:** [October 6, 2022, 1:30pm UTC](https://community.keyboard.io/t/locklayer-as-a-secondary-held-action/5666/9 "2022-10-06T13:30:29Z")

</div>

Sorry about that. The symbol `Qukeys` in the global namespace unfortunately refers only to an instance of the `kaleidoscope::plugin::Qukeys` class, so to refer to the `layer_wildcard` constant, you either need the unwieldy `::kaleidoscope::plugin::Qukeys::layer_wildcard` or the somewhat confusing `::Qukeys.layer_wildcard`. The leading `::` can be dropped in either case, but I included them to clarify everything with an absolute reference, rather than a relative one. `Qukeys.layer_wildcard` is the briefest version.
