diff --git a/src/layers.cpp b/src/layers.cpp index 765615e1..369dafcc 100644 --- a/src/layers.cpp +++ b/src/layers.cpp @@ -12,27 +12,46 @@ static void handleKeymapKeyswitchEvent(Key keymapEntry, uint8_t keyState) { if (keymapEntry.keyCode >= MOMENTARY_OFFSET) { uint8_t target = keymapEntry.keyCode - MOMENTARY_OFFSET; - if (keyToggledOn(keyState)) { - if (target == KEYMAP_NEXT) { + switch (target) { + case KEYMAP_NEXT: + if (keyToggledOn(keyState)) Layer.next(); - } else if (target == KEYMAP_PREVIOUS) { + else if (keyToggledOff(keyState)) Layer.previous(); - } else { - Layer.on(target); - } - } - if (keyToggledOff(keyState)) { - if (target == KEYMAP_NEXT) { + break; + + case KEYMAP_PREVIOUS: + if (keyToggledOn(keyState)) Layer.previous(); - } else if (target == KEYMAP_PREVIOUS) { + else if (keyToggledOff(keyState)) Layer.next(); - } else { + break; + + default: + /* The default case is when we are switching to a layer by its number, and + * is a bit more complicated than switching there when the key toggles on, + * and away when it toggles off. + * + * We want to handle the case where we have more than one momentary layer + * key on our keymap that point to the same target layer, and we hold + * both, and release one. In this case, the layer should remain active, + * because the second momentary key is still held. + * + * To do this, we turn the layer back on if the switcher key is still + * held, not only when it toggles on. So when one of them is released, + * that does turn the layer off, but with the other still being held, the + * layer will toggle back on in the same cycle. + */ + if (keyIsPressed(keyState)) { + if (!Layer.isOn(target)) + Layer.on(target); + } else if (keyToggledOff(keyState)) { Layer.off(target); } + break; } - - // switch keymap and stay there } else if (keyToggledOn(keyState)) { + // switch keymap and stay there if (Layer.isOn(keymapEntry.keyCode) && keymapEntry.keyCode) Layer.off(keymapEntry.keyCode); else