feat: Allow layer behaviors to "lock" layers on
Adds a locking property to momentary, to, and toggle layer behaviors. Enabled by default for &to and &tog, a layer being "locked" prevents behaviors without the locking property from deactivating the layer.
~~Conditional layer activation and deactivation is always non-locking, which seems to interact nicely.~~
Common use case: with this PR you can place e.g. a &tog 1 or a &to 1 on layer 1, allowing you to "lock" it in place while it is active.
Closes #1771
PR check-list
- [x] Branch has a clean commit history
- [x] Additional tests are included, if changing behaviors/core code that is testable.
- [x] Pre-commit used to check formatting of files, commit messages, etc.
- [x] Has any necessary documentation updates.
Conditional layer activation and deactivation is always non-locking, which seems to interact nicely.
If you want to get the state of a conditionally activated then-layer, it seems useful to me to propagate the locked state from if-layers (i.e. it is locked if all of the if-layers are locked). This'd be necessary to replace the momentariness tracking I mentioned on Discord.
Can you lock on a then-layer using &tog? I would guess not, since it still needs all the if-layers to be active.
If you want to get the state of a conditionally activated
then-layer, it seems useful to me to propagate the locked state fromif-layers(i.e. it is locked if all of the if-layers are locked). This'd be necessary to replace the momentariness tracking I mentioned on Discord.Can you lock on a
then-layerusing&tog? I would guess not, since it still needs all theif-layersto be active.
I realised that tracking that is unnecessary for this to work as expected. Rather, if both if-layers are locked then the then-layer is semi-locked: If it is deactivated, then on the event triggered by the deactivation the then-layer immediately becomes reactivated.
This also has the effect of allowing the then-layer to be locked using &tog, as if one of the if-layers becomes inactive then the conditional layer effect will try but fail to deactivate the then-layer.
I will rewind a bit: I have this momentariness tracking feature which is being used to filter layer change events that aren't "permanent". I am hoping to replace the tracking of momentariness by checking the "locked" state of the highest active layer instead. For that to work:
- There'd need to be a function like
bool zmk_keymap_layer_locked(zmk_keymap_layer_id_t layer)that'd return the state of a layer - Conditional layers would need to set the default locked status (check if all the if-layers are locked), before it might be locked directly by e.g. a
&tog
I am hoping to replace the tracking of momentariness by checking the "locked" state of the highest active layer instead.
I've added what I believe are the necessary parts to get that to work with the locking system.
Just realised that this makes #1984 obsolete.
Hello,
I see that the changes are ready to merge, but I wonder if the locking property could additionally be implemented for sticky layers. For the case of activating a sticky layer from within a momentary one, to finally return to the default layer after pressing the corresponding key or the after the timeout expires.
I haven't tried in my keyboard tbh, but as far as I understand, if a sticky layer is activated from a momentary layer, then the sticky layer would be deactivated on release of the &mo key, just as for the to and toggle layers.
Hello,
I see that the changes are ready to merge, but I wonder if the
lockingproperty could additionally be implemented for sticky layers. For the case of activating a sticky layer from within a momentary one, to finally return to the default layer after pressing the corresponding key or the after the timeout expires.I haven't tried in my keyboard tbh, but as far as I understand, if a sticky layer is activated from a momentary layer, then the sticky layer would be deactivated on release of the &mo key, just as for the to and toggle layers.
Hi, sticky layer uses &mo internally. Using a custom &mo with the locking property enabled along with a custom &sl would allow this to work as you desire without further changes to this PR.
Hi, sticky layer uses &mo internally. Using a custom &mo with the locking property enabled along with a custom &sl would allow this to work as you desire without further changes to this PR.
You are right about that. Thanks!
Hi @petejohanson, Any chance this gets merged to main? It seems everything is ready for that. I've also tested the implemented changes on my kb and it's working fine from my side.
I don't want to add pressure, just in case this has been forgotten :) It would be great to have this feature in ZMK!