# Multiple layers?

**URL:** <https://community.keyboard.io/t/multiple-layers/401>\
**Category:** Programming\
**Created:** [October 10, 2017, 6:29am UTC](https://community.keyboard.io/t/multiple-layers/401 "2017-10-10T06:29:10Z")\
**Posts on this page:** 11\
**Page:** 3

<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 30, 2017, 3:40pm UTC](https://community.keyboard.io/t/multiple-layers/401/41 "2017-10-30T15:40:48Z")

</div>

More detail, if you’re interested:

Whenever a layer gets activated (turned on) or deactivated (turned off), Kaleidoscope updates the current keymap in memory, using the highest-numbered active layer on which each key is defined. So if the top active layer has a transparent key entry ("\_\_\_"), it looks on the next-highest active layer, and so on, until it finds an active layer with a specified keycode for that key.

So, on the default keymap (`Model01-Firmware.ino`), there are three layers: `QWERTY` (0), `FUNCTION` (1), and `NUMPAD` (2). Holding `Fn` activates the `FUNCTION` layer using `ShiftToLayer(FUNCTION)`, which updates the current keymap, overwriting many of the keycodes, but not all of them. In particular, the key that was `Key_Spacebar` defined on the `QWERTY` layer) is now mapped to `Key_Enter`.

When `Fn` is released, the keymap gets updated again, and all of the keys now get their keycodes from the `QWERTY` layer. This example assumes `NumLock` is off the whole time, of course.

---

<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 30, 2017, 3:48pm UTC](https://community.keyboard.io/t/multiple-layers/401/42 "2017-10-30T15:48:20Z")

</div>

Running through that example has made me wonder what would happen if I defined both palm keys as `ShiftToLayer(1)` on layer 0, and `LockLayer(1)` on layer 1. I could then shift to layer 1 by holding down a palm key (which I believe retains its mapping from layer 0 as long as it’s held), start typing on layer 1, then decide I want to stay in layer 1, and tap the other palm key before releasing the held palm key. Would releasing the `ShiftToLayer(1)` key result in layer 1 toggling off, or would the tap on `LockLayer(1)` keep layer 1 active in the keymap?

---

<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 30, 2017, 5:48pm UTC](https://community.keyboard.io/t/multiple-layers/401/43 "2017-10-30T17:48:42Z")

</div>

> [@merlin](#):
>
> Would releasing the ShiftToLayer(1) key result in layer 1 toggling off, or would the tap on LockLayer(1) keep layer 1 active in the keymap?

In this case, since the release would be for a `LockLayer(1)` key, you’d stay on that layer. However, with this setup `ShiftToLayer(1)` would effectively work as a `LockLayer()`, because the firmware would never see a release event for it.

---

<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 31, 2017, 1:56am UTC](https://community.keyboard.io/t/multiple-layers/401/44 "2017-10-31T01:56:09Z")

</div>

> [@algernon](#):
>
> In this case, since the release would be for a LockLayer(1) key, you’d stay on that layer. However, with this setup ShiftToLayer(1) would effectively work as a LockLayer(), because the firmware would never see a release event for it.

I didn’t make that example clear enough. Here’s the sequence of events, starting with only layer 0 active:

1. press left palm key: `ShiftToLayer(1)`

2. press right palm key: `LockLayer(1)`

3. release right palm key

4. release left palm key

Unless I misunderstand, the left palm key continues to be mapped to `ShiftToLayer(1)` until step 4, because it was held at the time of a layer update, so it wouldn’t be effectively the same as `LockLayer(1)`. Then, when it’s released, I’m not sure if it changes to `LockLayer(1)` before it would trigger the call to `Layer.off()`.

---

<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 31, 2017, 2:47am UTC](https://community.keyboard.io/t/multiple-layers/401/45 "2017-10-31T02:47:50Z")

</div>

> [@merlin](#):
>
> Then, when it’s released, I’m not sure if it changes to LockLayer(1) before it would trigger the call to Layer.off().

Ah, I see. In this case, the layer would still be turned off, because the lock/shift mechanism is currently implemented by the key event handler, not the layering code itself. In other words, we are tied to key events, and don’t keep track of whether a layer is locked or shifted.

If/when the layer stuff moves to a plugin, it would be quite easy to write a plugin that would make the behaviour you described possible. I have a feeling that we could build it on the same foundation that the current behaviour is built upon, with very little change (they’d share a base class).

Making this possible with the current code… hmm, that would be more complicated than I’d feel comfortable with. At least if we stick to `ShiftToLayer`/`LockLayer`… because there’s another option, that can work on top of what we already have! We can create a plugin that implements this behaviour! All it has to do is capture `LockLayer`/`ShiftToLayer`, and flip a bit in a bitfield if a layer is locked to, and refuse to turn it off via `ShiftToLayer`. Should be a few dozen lines, I guess.

Can you file a GitHub issue about this, linking to your post (or copying it there, whichever is more convenient)? Makes it easier for me to remember to try doing it at some point in the not so distant future =)

---

<div class="post-metadata">

**Author:** ![samaaron](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/samaaron/32/1942_2.png) [@samaaron](https://community.keyboard.io/u/samaaron)\
**Post date:** [June 1, 2018, 10:26pm UTC](https://community.keyboard.io/t/multiple-layers/401/46 "2018-06-01T22:26:35Z")

</div>

Apologies if this has been asked already, but I’m struggling to find a way to toggle/lock multiple layers simultaneously.

The closest I seem to be able to get to is to have a Macro bound to a key which then resolves to a function such as:

```auto
static void resetFunctionLeft(uint8_t keyState) {
  if (keyToggledOn(keyState)) {
    LockLayer(FUNCTION_LEFT);
    LockLayer(YTREWQ);
  }
}

```

However, this unfortunately doesn’t work. I assume because I’m mixing Macros with functions here.

I essentially want to unlock (_not toggle_) two specific layers. Luckily I know that my context is such that when this function is called, both those layers are enabled, so calling `LockLayer` will unlock them.

---

<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:** [June 2, 2018, 3:55am UTC](https://community.keyboard.io/t/multiple-layers/401/47 "2018-06-02T03:55:16Z")

</div>

> [@samaaron](#):
>
> I essentially want to unlock ( _not toggle_ ) two specific layers. Luckily I know that my context is such that when this function is called, both those layers are enabled, so calling `LockLayer` will unlock them.

You can use `Layer.off(FUNCTION_LEFT); Layer.off(YTREWQ);` to do just that.

---

<div class="post-metadata">

**Author:** ![samaaron](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/samaaron/32/1942_2.png) [@samaaron](https://community.keyboard.io/u/samaaron)\
**Post date:** [June 2, 2018, 8:35am UTC](https://community.keyboard.io/t/multiple-layers/401/48 "2018-06-02T08:35:35Z")

</div>

Brilliant, thanks! This works a treat 🙂

---

<div class="post-metadata">

**Author:** ![jamadagni](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jamadagni/32/2030_2.png) [@jamadagni](https://community.keyboard.io/u/jamadagni)\
**Post date:** [June 22, 2018, 11:54pm UTC](https://community.keyboard.io/t/multiple-layers/401/49 "2018-06-22T23:54:36Z")

</div>

Sorry for bumping this old thread but I came across when searching for something else.

I too found `LockLayer` somewhat not entirely descriptive and confusing for the same reason as @merlin. To me if `ShiftToLayer` were named **`TempLayer`** instead, then `LockLayer` could be renamed to **`ToggleLayer`** and the contrast with `TempLayer` would convey all that is needed. Normally if you “toggle” something it is understood that it stays on/off until the next toggle happens, IMO.

---

<div class="post-metadata">

**Author:** ![eritain](https://avatars.discourse-cdn.com/v4/letter/e/3ab097/32.png) [@eritain](https://community.keyboard.io/u/eritain)\
**Post date:** [October 9, 2020, 12:34am UTC](https://community.keyboard.io/t/multiple-layers/401/50 "2020-10-09T00:34:10Z")

</div>

> [@jesse](#):
>
> If we changed to use “ToggleLayer” instead of LockLayer, would you rename ‘ShiftToLayer’?

MomentaryLayer?

It fails the “functions are verbs” heuristic, and kind of causes ToggleLayer to start failing it too, but it does import a handy physical metaphor, if you’re an electronics nerd.

As long as the underlying design allows multiple active layers, MoveToLayer is an ill-named function too. But now that I’ve given up on verb-named functions, SoleLayer might work.

---

<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 9, 2020, 2:18am UTC](https://community.keyboard.io/t/multiple-layers/401/51 "2020-10-09T02:18:35Z")

</div>

Ah, but those macros are not functions; they’re really just a shorthand for naming a `Key` value. It’s true that something happens when you press a `ShiftToLayer(N)` key, but that’s also true of `Key_A`. This is one reason why I think the names `LayerShift` and `LayerLock` would be better.

[Previous page](https://community.keyboard.io/t/multiple-layers/401.md?page=2)
