zmk icon indicating copy to clipboard operation
zmk copied to clipboard

feat: Allow layer behaviors to "lock" layers on

Open nmunnich opened this issue 1 year ago • 9 comments

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.

nmunnich avatar Dec 16 '24 16:12 nmunnich

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.

caksoylar avatar Dec 16 '24 19:12 caksoylar

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.

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.

nmunnich avatar Dec 16 '24 19:12 nmunnich

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

caksoylar avatar Dec 16 '24 20:12 caksoylar

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.

nmunnich avatar Jan 05 '25 21:01 nmunnich

Just realised that this makes #1984 obsolete.

nmunnich avatar Mar 01 '25 20:03 nmunnich

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.

omulh avatar May 07 '25 12:05 omulh

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.

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.

nmunnich avatar May 07 '25 13:05 nmunnich

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!

omulh avatar May 07 '25 14:05 omulh

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!

omulh avatar May 13 '25 12:05 omulh