qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
18.25k stars 39.32k forks source link

[Feature Request] Adding a "Layer Lock" function. For when you momentary enter a layer but want to lock it in place. #16861

Closed ujl123 closed 2 years ago

ujl123 commented 2 years ago

This feature is for when you momentary enter a layer (ex: MO(1)) but you want to remain in the layer without having to hold down MO(1). Currently there is no clean solution to remain in the layer except to deactivate MO(1) and then use another keycode like TT(1) or TG(1). I mention clean because there is in fact a solution of putting DF(1) on layer 1 to make it the default layer, but this might cause some unintentional effects rather than just locking layer 1 in place.

Feature Request Type

Description

https://getreuer.info/posts/keyboards/layer-lock/index.htm

Pascal Getreuer has already provided code snippets on how to do this, as well as an explanation of how it works, and why it's better than using DF(1).

To summarize functionality of the layer lock function:

  1. Hold MO(1) to momentary enter layer 1 (But would work for LT(1,KC), OSL(1) or TT(1)
  2. In layer 1, click on the keycode you've created for "Layer Lock". This will then keep you on layer 1
  3. Do stuff on layer 1
  4. Tap the "Layer Lock" key, or any other layer navigate key to break this lock.
getreuer commented 2 years ago

Thanks for suggesting this! =)

Playing devil's advocate for a moment, the best reason I can come up with against adding Layer Lock to core is that existing features already give a few ways to get a similar effect. Besides TT and DF as you mention, one could use Key Lock to hold an MO.

On the other hand, the DF strategy has a risk of getting stuck in the layer if you forget to make an accessible switch to get back out. Key Lock has the caveat that "switching layers will not cancel the Key Lock." TT seems like the best existing solution. But for me at least, chording an MO key with a Layer Lock key is more comfortable than making multiple taps on a TT key, even if that's just two taps with #define TAPPING_TOGGLE 2.

What are other folks' thoughts on this?

precondition commented 2 years ago

Is there really a situation where you don't know in advance that you want to lock the layer? Besides, it doesn't cost you anything to accidentally hold down a TT(layer) key, realize your mistake, consequently release the key and then tap it in order to toggle the layer. what I've described takes the exact same amount of keystrokes as your suggestion. I don't see a notable added-value from "Layer Lock" over the pre-existing tap-toggle-layer key.

mwpardue commented 2 years ago

I just wanted to chime in with regards to the advantage layer lock has over other methods of locking a layer. I use a 40% board and don't have a lot of extra keys, like many of us, and as such use LT() keys only for layer navigation. I used to put a TO() or TG() key on the layers that I might want to lock in place and that does work just fine. However with this feature I can just put the layer lock key on a low layer key that is transparent through all my layers and then have a single, consistent location to lock into a layer without having to add new TO() or TG() keys to new layers. I know that winds up using the same number of keys as my previous method, but it just makes the keymap a bit simpler and easier to maintain.

In addition, there is now a layer lock timer function that will automatically unlock all layers and return to default if no keys are pressed for a user-configurable amount of time. Honestly, this is the most useful part for me because I sometimes lock a NUM/NAV layer in place while working in spreadsheets or whatever the need may be, and if I'm called away from my desk during this period or the phone rings or whatever distracts me, it's easy to forget that I'm still on a different layer when I return. The timer takes care of this issue.

I know there are other ways to implement similar function in QMK, but I feel like layer lock is a little simpler and it doesn't really add much to the overall firmware size. I guess it ultimately just comes down to preference but I do see a real value to layer lock over TG(), TO(), and other similar keys.

Edit: Wanted to add that the timer also takes care of the problem getreuer mentioned with getting stuck on a layer, even if you somehow manage to get yourself stranded with absolutely no layer lock key or layer navigation keys you can just wait out the timer.

github-actions[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had activity in the last 90 days. It will be closed in the next 30 days unless it is tagged properly or other activity occurs. For maintainers: Please label with bug, in progress, on hold, discussion or to do to prevent the issue from being re-flagged.

github-actions[bot] commented 2 years ago

This issue has been automatically closed because it has not had activity in the last 30 days. If this issue is still valid, re-open the issue and let us know. // [stale-action-closed]

jpsecher commented 1 year ago

I would really love this Layer Lock feature.

I used to put a TO() or TG() key on the layers that I might want to lock in place and that does work just fine

I simply cannot get any of such alternatives to work.

As a minimal example, consider three layers; alpha, navigation and numpad:

Layer 0
┌───────────────┬───────────────┐
│     KC_A      │     KC_B      │
├───────────────┼───────────────┤    
│ LT(1, KC_DEL) │ LT(2, KC_SPC) │
└───────────────┴───────────────┘

Layer 1
┌───────────────┬───────────────┐
│    KC_LEFT    │    KC_RGHT    │
├───────────────┼───────────────┤    
│    _______    │     TO(1)     │
└───────────────┴───────────────┘

Layer 2
┌───────────────┬───────────────┐
│     KC_0      │     KC_1      │
├───────────────┼───────────────┤    
│     TO(2)     │    _______    │
└───────────────┴───────────────┘

Holding the Delete key will switch to navigation, and holding the Space will switch to numpad, as expected.

But holding Delete and tapping Space will not lock the navigation layer.

I would really appreciate if anyone could tell me exactly how this can be achieved with existing features.

morganvenable commented 1 year ago

I'd really like this feature. I use Datahand/lalboard, and there are two-stage keys for Shift/CAPS and number/symbol layer aka NAS/NAS-Lock -- you press through to the second stage to lock the layer (first stage stays pressed until you release entirely). It's a very nice and intuitive physical model.

Seems like the only straightforward way to make it happen is Pascal Getreuer's mods above.

I tried doing it with MO + TG, but the MO release kills the TG every time :P

dcousens commented 2 months ago

Is there really a situation where you don't know in advance that you want to lock the layer?

@precondition if you are on a navigation layer (e.g layer 2), and you found your way there by using a home row modifier, how do you propose I can toggle that layer? I don't have any other keys available to allocate to TO(2) on my default layer.

If I hit a TO(2) while on layer 2, LT_2 key up will still revert the layer back. The only path forward I can see without writing some C is setting DF(2) while on that layer, but that will reset my default layer... ~and I still don't have a path to find my way back to layer 0 without using another key for TO(0).~ (see edit)

A layer lock key would help me, in layer 2, opt-out of the momentary nature of my initial traversal, which is exactly what I want. Then I can simply have a TO(0) to drop out of that layer when I'm ready.

edit: you can use DF(0) to change the default layer AND switch back, which works if you're willing to forgo default layer functionality otherwise.