What LockLayer currently does is more like toggling, i.e. every time it’s ran the meaning of the keypresses changes. Would it be possible to make functions for idempotent switching of layers?
Example: assume we have EnableLayer and DisableLayer and I map left palm key to EnableLayer(FUNCTION) and right palm key to DisableLayer(FUNCTION). Then:
Pressing left palm any number of times should result in FUNCTION layer being “enabled”
To “disable” it, I would have to press right palm key
Reason: I’d like to implement vim-like modal cursor movement keys. Toggling doesn’t work for me because I don’t always remember which layer is currently active - I need a stateless behavior in which pressing a key will always result in known result.
I too would like layer switching that doesn’t require me to store state in my head.
In my case I have 4 layers, and 2 ‘fun’ keys on my Model 100 and I want the four combinations of the fun keys being pressed/unpressed to correspond to the four layers.
Left fun Right fun Layer
- - 0
pressed - 1
- pressed 2
pressed pressed 3
I can nearly get their with a shift-to-layer on each fun key like so:
Layer Left fun Right fun
0 shift-to-1 shift-to-2
1 transparent shift-to-3
2 shift-to-3 transparent
3 transparent transparent
However, if I do the following:
Left-fun Down (0 → 1), Right-fun Down (1 → 3), Left-fun Up (3 → 3)
then releasing the left function key at the end makes no difference. I want it to drop back down to layer 2.
Layers seem to be quite tricky for people to get their head around but from what I’ve read I suspect that this isn’t going to be possible through Chrysalis (at the moment at least). Is that right?
Any pointers on how to get this working would be very helpful.
You’ll have to drop down to firmware level to do this. In this sequence of events, Layer 2 was never activated, so Kaleidoscope won’t drop back to it either.
It isn’t possible with Chrysalis, no. The best way I can imagine doing this is dropping down to firmware, completely ignoring the existing layer shift keys, and implement your own layering logic in a plugin. Something along these lines, maybe:
EventHandlerResult afterEachCycle() {
bool leftPalm = Kaleidoscope.device().isKeyswitchPressed(KeyAddr(3, 6));
bool rightPalm = Kaleidoscope.device().isKeyswitchPressed(KeyAddr(3, 9));
if (!leftPalm && !rightPalm) Layer.move(0);
if (leftPalm && !rightPalm) Layer.move(1);
if (!leftPalm && rightPalm) Layer.move(2);
if (leftPalm && rightPalm) Layer.move(3);
return EventHandlerResult::OK;
}
This checks whether the left or right palm keys are held, by coordinates, so you can map them to whatever you wish (though, it’d make sense to map them to blocked or transparent, to not interfere with the mechanism above), and implements a custom layering logic based on their state. It’s probably easier to do this than trying to fit your desired states into the logic Kaleidoscope normally uses.
If you want transparency on one or more layers, then you’ll need to do some more work, to have the desired layers active.
The above code needs to be in a plugin (an example on how to write a plugin is available here), and is completely untested. Hopefully it can serve as a guideline nevertheless.
Here’s an idea: a plugin that implements a layer shift (either using built-in layer shift keys and aborting to stop the built-in layer shifts from happening, or defining its own set of layer shift keys), but it uses the index number as a value to add to the current layer total when the key toggles on (and subtract from when it toggles off). So in @Rachel’s example, left fun becomes “layer shift +1” and right fun becomes “layer shift +2”. This would provide exactly the desired behaviour, and would be fairly simple to write.
I’d like to point out that the thing that makes this difficult with layer shift keys as they are in Kaleidoscope is that, perhaps counter-intuitively, a key doesn’t change it’s value if a layer change happens while the key is active (held). This is a fundamental feature of Kaleidoscope, and avoids all sorts of problems, but it’s not obviously true, and it does mean that a layer shift key does not work the same way as a shift modifier key works.
Yes, that’s exactly what I’d do if I get round to learning how to write a plugin. The function keys being sort of like a bitfield that add up to the desired layer.
Are custom plugins compatible with Chrysalis, or does one end up having to define everything in code at that point?
Still getting my head around Keyboardio, Chrysalis, Kaleidescope, Sketches, Plugins, firmware, .ino files, EEPROM, etc. and how they all relate to each other.