Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: Lockout (soft power off) #405

Closed
bcat opened this issue Nov 19, 2020 · 14 comments
Closed

Feature request: Lockout (soft power off) #405

bcat opened this issue Nov 19, 2020 · 14 comments
Labels
behaviors core Core functionality/behavior of ZMK enhancement New feature or request

Comments

@bcat
Copy link
Contributor

bcat commented Nov 19, 2020

I think a couple folks mentioned this on Discord as something desired, but I didn't see an issue for it, so I figured I'd file one. (I'm thinking of trying to hack on it if I have some spare cycles around the holidays, but no promises, sadly.)

Since not all keyboards have hardware power switches (and integrating such a switch sometimes has other drawbacks; e.g., wiring a switch in series with the battery on a nice!nano board means you can't charge the battery when the keyboard is switched off), I think it would be useful to have a lockout feature, e.g., a key combination that toggles on/off sending of key events.

Here's a couple use cases I can think of:

  • Keyboard tossed in a backpack and want to avoid accidental keypresses that might wake laptop, waste battery, etc.
  • Changing keycaps and want to avoid accidental typing on the host.

I think you can sort of fake this today by defining a layer near the top of the stack with almost all keys bound to &none, but there's a few drawbacks I can see:

  1. This likely requires several "dummy" layers to implement in practice. For example, let's say I have an ortho/ergo board with the standard default/lower/raise/adjust layers. If I want a key on the adjust layer (e.g., Lower+Raise+P) to serve as the lockout key, then I need to define a lockout layer, a lockout-lower layer, a lockout-raise layer, and a lockout-adjust layer. Otherwise, the lockout layer will either lock out the layer toggle (if it binds P to &none) or fail to lock out all keys (e.g., allowing Lower+Raise+P, but also allowing Lower+P and Raise+P).
  2. Not all features are controlled via layers today. For example, encoder rotation uses sensor-bindings, which I don't think you can change on different layers.
  3. There are other features I can imagine one would want disabled during lockout. For example, we might want to disable underglow or OLEDs to save battery, or even disconnect Bluetooth connections between central and host.

So I think it makes sense this really should be a core feature of ZMK rather than something hacked up in user keymaps. I don't know much about ZMK's architecture yet, but my rough thoughts are as follows:

  1. Add a bit in each behavior's configuration to determine whether that behavior respects lockout. For example, we want to disable &kp during lockout, but maybe we think &reset should always work. Likewise, we probably want &mo to still work during lockout, so you can put the lockout key on a hard-to-reach layer in the first place. (Or maybe if we had a combo feature, we'd just want to trigger lockout via a combo, independent of the layer system somehow? But I'm not sure what that would look like in practice.)
  2. Implement a global lockout toggle (that's shared across central and all peripherals).
  3. Disable behavior execution for behaviors configured as respecting lockout, when the lockout toggle is enabled.
  4. Implement a &lockout behavior to flip the global lockout toggle.

Does this sound basically sane?

@Nicell Nicell added core Core functionality/behavior of ZMK enhancement New feature or request labels Nov 20, 2020
@okke-formsma
Copy link
Collaborator

Once combo's are in, you could make a "lock" layer (with only &none everywhere) and a combo which uses the &tog to jump to the empty layer. Press the combo again to disable the lock layer and you're on your merry way.

@bcat
Copy link
Contributor Author

bcat commented Jun 4, 2021

Once combo's are in, you could make a "lock" layer (with only &none everywhere) and a combo which uses the &tog to jump to the empty layer. Press the combo again to disable the lock layer and you're on your merry way.

Getting back to this and trying out the new combos feature, it's not actually possible to make a totally empty layer today due to #241. Maybe I can put a momentary layer key or something on my "lock" layer....

@bcat
Copy link
Contributor Author

bcat commented Jun 5, 2021

So using a lock layer like this seems to work well enough. It's a little annoying that there's no feedback when locked/unlocked, but without an OLED to update or an indicator LED to flash, I'm not sure if anything can be done about that.

Is this a good enough workaround to close out this feature request? I'm honestly not sure. I feel like a real lockout behavior would turn off RGB, disable Bluetooth connection to the host, etc. automatically. But maybe this is close enough. I'll leave the issue open for now, but go ahead and resolve it if y'all think it's not worth adding native support for this.

@bcat
Copy link
Contributor Author

bcat commented Jun 7, 2021

Actually, I had to revert that commit. It seems using a combo together with layer keys lead to a strange race condition. If I pressed Lower+Raise+AnyKey (e.g., Lower+Raise+E, which I have bound to C_VOL_UP) quickly (within the combo timeout I set), the keyboard somehow hard locked. Not sure exactly why; maybe I just configured something incorrectly.

@bcat
Copy link
Contributor Author

bcat commented Oct 7, 2021

For some reason, I never could get the combo to disable the lock layer working properly, but here's what I ended up with that does work: https://github.com/bcat/zmk-config/blob/8c92cdf5e93cbb2bd4357891794506e3495fea8d/config/corne.keymap#L89-L103. I think it's good enough for now.

@midgethoen
Copy link
Contributor

Im interested on working on this feature as well. but i was thinking of a different approach. Im quite inexperienced with zephyr though, so maybe somebody else could comment on the feasibility of it:

my idea boils down to implementing a behaviour which puts the central and peripheral devices to a soft poweroff state and prevent them from waking up from any keypresses (im not sure it this is possible).
To wake the devices you would simply reset them.

@willthong
Copy link

@bcat I looked into your mostly-empty-layer solution, but am I not right in thinking that, because you've got transparency enabled on three of your keys, if any of those keys get pressed while the keyboard is in the backpack, the keyboard will be activated (and drain some amount of battery)? Apologies if I've gotten the wrong end of the stick - cheers!

@caksoylar
Copy link
Contributor

Even for positions that are not transparent the keyboard will wake from idle and process the press (but no keycode will eventually be sent). This proposal is less for preserving battery and more for preventing sending keycodes to connected devices, if I understand correctly.

@FilipSipos
Copy link

I'm not sure if this thread is still active, but... is there a way to turn the keyboard off completely with a key combo and then set up the reset switch to act as a "wake button"?

@caksoylar
Copy link
Contributor

There's no such feature in ZMK right now. I guess a deep sleep variant that doesn't use interrupts to wake would be something analogous to what you are asking about. I don't believe you can "power off" the controllers through firmware.

@whoistobias
Copy link

This feels like a very low level feature that a lot of people will need. My use case, I put the keyboard in my backpack and leave it there until I need it. My computer constantly tries to connect to it because it's still broadcasting. It wastes the power on the keyboard, it has potential to send unwanted keystrokes, and if the battery is low, it connects and disconnects from the computer constantly, resulting in me having to forget the connection until I need it again.

I may just add a physical power switch, but it definitely feels like something that could be solved in software.

I'm a developer and would be happy to contribute, but I have absolutely no idea where to begin on a project like this, as I mostly work on backend server programming.

@shifubrams
Copy link

Hi everyone, any news about this feature ?

@MvEerd
Copy link
Contributor

MvEerd commented Jan 6, 2023

@shifubrams There was some discussion around this feature in the ZMK discord recently starting at this message; https://discord.com/channels/719497620560543766/763848253996793856/1058392717933162538

@lesshonor
Copy link
Contributor

lesshonor commented Aug 12, 2024

Arguably closed by #2085

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
behaviors core Core functionality/behavior of ZMK enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.