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

New package: auto lock the attached keyboard when flipped behind tablet #565

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ScottFreeCode
Copy link

This is something that we get a lot of requests for routinely.

It's not 100% foolproof or 100% theoretically complete, but it's about as good as it seems likely to get at the moment.

Some CAVEATS:

  • The "lid close" event it relies upon doesn't fire 100% of the time for some reason. This means:
    • When putting folding the case back to use the tablet in, well, tablet style, make sure you see the keyboard off popup/notification.
    • You should still lock your screen before closing the case. NOTE: You should do that anyway because disabling the keyboard means the screen can't press the keys, but doesn't mean the keys can't tap the screen!
  • The "hinge" on the case is floppy enough that the keyboard can slide to one side or the other far enough that it is no longer detected as "closed" and the keyboard comes back on. This should pop up a notification alerting you, however.
  • If you boot (or wake from hibernate?) and the keyboard is already flipped back, the keyboard will still be on initially.

TL;DR:

  • You should still lock your screen before closing the case.
  • Pay attention to the keyboard on/off notification.

Initial Boot issue

This should really also fire the event or perform the equivalent action when the system starts (including from hibernate if necessary) and the keyboard is already flipped.

In terms of when, we'll want to do this either with a cron job and the @reboot schedule keyword, or by creating and enabling a systemd service that runs once. And maybe (if the other method doesn't work for coming out of hibernate) also check out systemd's support for hooks related to suspend/sleep/hibernate.

In terms of how, on the other hand, we have a conundrum. I can't find how to query the system for the state of the lid / hall sensor. The internet just says to look for the lid in /proc/acpi/… but the PineTab2 doesn't have that. The event does seem to fire on wake from sleep, so, maybe it should fire on boot but either it doesn't or it's somehow too early before USB is ready to be disabled. Or maybe we really do need to be able to find out on-demand, not from an event, what the state is. Someone more familiar with what the device tree is defining for the hall sensor and lid may need to take a look and tell us if this is possible or would be with the right tweaks (I mean, theoretically Linux should be able to read the current gpio state of the sensor somehow…).

Virtual/Onscreen Keyboard

It would be nice to toggle the onscreen/virtual keyboard so when the attachment keyboard is not available the touchscreen keyboard is. However, this poses several problems:

  • Surely it should also turn back on when the keyboard is detached. While we can receive an event for switching in and out of "tablet mode" i.e. the keyboard detaching, this is arguably a different event/action category?
  • How to disable/enable the onscreen keyboard may depend on the desktop environment and/or the keyboard program.
  • Some users may want the onscreen keyboard enabled even with the hardware keyboard attached and enabled. Either they should be able to configure it not to turn off the virtual keyboard or they should be able to not install that part.
  • Other users may want the onscreen keyboard disabled even with the hardware keyboard flipped back, they may prefer to flip the keyboard and use it when needed rather than ever activating the onscreen keyboard. (Arguably this can also be achieved by selecting "None" for the virtual keyboard or, if there are no circumstances in which they are wanted, uninstalling them all. But maybe that's extreme or unhelpful in other contexts when it would still be good to be able to tap the tray icon and turn it on.)
  • Any of that might depend which desktop environment they're using, e.g. I might want the onscreen keyboard in Plasma but not in Phosh.
  • There's a tray icon you can tap to turn the virtual keyboard on or off manually.

The long and short of which is that it would make a lot more sense to offer enabling/disabling the virtual/onscreen keyboard as a separate package or family of packages, if it's truly needed vs. the manual option; it's either going to take a lot of variants or a lot of configuring, and none of it needs to touch the functionality of disabling/enabling the attached keyboard.


ACTION=bind
MESSAGE=on
if [[ "$3" = "close" ]]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we had a command (let's just call it lid-closed for example) that detected whether the keyboard's current state is flipped shut, then we could call this script on boot with the following modification:

Suggested change
if [[ "$3" = "close" ]]
if [[ "$3" = "close" ]] || lid-closed

@ScottFreeCode
Copy link
Author

As an Arch noob, let me know if there's a good place in the package itself to document the "CAVEATS" section.

@ArenM
Copy link
Contributor

ArenM commented Jul 16, 2023

TLDR: does kde already handle this if the kernel gives it the right events? And if not would it be in scope to have it added to kde?

I know both gnome and kde have some sort of tablet mode handling, which seems like the ideal place if possible. Although I can't find any information on whether they disable the keyboard if it's tablet mode is enabled, I assume there are 2 in 1 devices that don't do it in hardware so it might be implemented already if the kernel emits the right signals.

As for the on screen keyboard, I know gnome will do it's best to guess if there's a keyboard present and hide / show the on screen keyboard based on that12. I assume kde does something similar, but searching isn't turning up much for me.

Footnotes

  1. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1044

  2. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1710

PKGBUILDS/pine64/acpi-kbd-autolock-pinetab2/PKGBUILD Outdated Show resolved Hide resolved
@@ -0,0 +1,2 @@
event=button/lid
action=/etc/acpi/toggle-keyboard.sh %e
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to use logind for this? iirc it has an option to handle lid switch events, and that way you don't need to add an extra dependency.

Copy link
Author

@ScottFreeCode ScottFreeCode Jul 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to dig up my research, but from what I read the systemd login interface only lets you choose from a predefined list of behaviors – screen off, suspend, shutdown, etc. – and there's theoretically a way to redefine those behaviors (suspend.target, etc.) but I didn't really think that was appropriate (anything more than screen off, e.g. suspend, should prevent keyboard usage anyway; and more importantly people's screens might be configured to turn off via other conditions as well), plus I didn't see an event that can turn the keyboard back on. As far as I was able to find out, ACPI is intended to be the lower level interface for more control of customization like this.

@ScottFreeCode
Copy link
Author

Re. implementation at the DE level… I'm not sure.

I doubt this implementation is appropriate at that level: it disables the keyboard's (and touchpad's) USB port, which is obviously at least somewhat specific to this device (PineTab2).

Maybe this solution becomes obsolete if we get a solution into all the DEs, but, I wouldn't know what to tell the DEs to do to implement it instead, and that does require each DE to do it (so this package is still useful as a fallback for any DEs that don't yet).

@ScottFreeCode
Copy link
Author

As for KDE specifically, I was under the impression tablet mode is activated/deactivated based on attaching/detaching the case, not closing it.

That said, having turned off the acpid service so my keyboard toggler no longer is running, and making sure that the "touch mode" setting (which enlarges certain icons and buttons for tablets) is set to "automatic" rather than "always on/off", it still changes sizes when I flip the keyboard behind, which suggests that KDE is doing something on keyboard flip even though (and I tested this by pushing keys to be sure!) the keyboard is still active.

So there's clearly some kind of KDE response to the right event but I have no idea on the other hand about getting KDE to include onscreen or attached keyboards' disable/enable to that event response.

@ScottFreeCode
Copy link
Author

One other thing I found on the topic of checking the initial state on boot… There's also a kernel C interface we're supposed to be able to use, if we wanted to compile a tiny helper program.

#include <acpi/button.h>

int main() {
  return acpi_lid_open();
}

To compile this, I have to add the headers to the include path. (cc -I /usr/lib/modules/*/build/include/) It also gives me an error about an IS_ENABLED line. If I add #define IS_ENABLED(_) 1 at the beginning to force it to try to link the API, it gives me a linker error saying that the function is not actually defined. So, either the kernel doesn't currently support this ACPI interface, or I don't know how to link a C program to make that kernel call – or maybe it can't, maybe those APIs are only available to kernel modules and not CLI programs?

(I still think reading from /proc/acpi/**/lid would be easier if available.)

@ArenM
Copy link
Contributor

ArenM commented Jul 17, 2023

That header file is for use in the kernel (e.g. by modules) not a syscall. You might be on the wrong path with acpi, iiuc acpi is a firmware <-> kernel interface and isn't used on most arm systems. I'm not entirely sure what the correct place to read from would be unfortunately.

@ScottFreeCode
Copy link
Author

All I know is what comes up in internet search results, and I happen to be the only person so far to publicize that they've (mostly) solved the problem.

(Couple that with, I want my notes here and not lying around locally where they might get wiped by a reimage or taking up tabs in the browser. So whatever I've got, this is my way of documenting it if nothing else.)

If there's a better way to take a crack at it, then by all means. Besides, personally I'd rather end up not having to be the guy maintaining any packages to be honest. It's just that this solution is the only advice I have and my options, given people keep asking on IRC and can't pull up my past messages from Discord, appear to be: make it installable (i.e. package it), vs. put instructions in text on the Pine wiki pages that Funeral (in Discord) keeps suggesting should/shall be deleted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants