|
|
||
|---|---|---|
| etc | ||
| usr/local/bin | ||
| var/local/watch_tablet/.config | ||
| README.md | ||
Keyboard Morphine
Many modern touchscreen laptops have 360° hinges that allow folding the lid backwards and using them as a tablet. On most models, the embedded controller should disable the keyboard automatically when the angle sensor in the hinge detects it being pushed past ~ 185° so keys being depressed against a surface the device is resting on don't cause erroneous inputs. On some models, this either doesn't happen, or isn't properly detected and handled by the corresponding kernel driver under Linux. This script aims to solve that problem without causing any serious usability issues in the process.
I wrote this script for my Lenovo ThinkPad C13 Yoga Chromebook (MORPHIUS) when I noticed that I couldn't really use it in tablet mode on my lap without the keyboard going haywire. I am releasing it as is with the hopes that it will potentially be useful on other models with similar problems, but it will certainly need some adjustments. Several things in this script are specific to this particular model, and some are specific to Chromebooks (notably, the keyd config). I have only tested this with Arch Linux, as I cannot get the Debian kernel to boot on my C13 Yoga. Pull requests to clean things up and make it more configurable for other use-cases are welcome!
Please note that this will probably only work for you if the tablet mode switch (input event) is detected and working, but it doesn't disable the keyboard for some reason. This will probably not work on devices that don't detect or update the tablet switch event properly because it uses that switch to determine the hinge state. It may be possible to configure the watch_tablet dependency to detect some other event, but I have not investigated that.
Dependencies
keyddetect-tablet-mode-git(AUR)sudo(should also work with any drop-in replacement but untested)
Installation
The installation process is currently entirely manual and a bit complicated. This should be replaced with an AUR package as soon as possible.
- Install dependencies:
yay -S keyd detect-tablet-mode-git - Copy all other files from this repo to the respective locations on your root filesystem
- Create directory:
sudo mkdir -p /var/local/watch_tablet/.config - Create symlink:
sudo ln -s /etc/watch_tablet.yml /var/local/watch_tablet/.config/watch_tablet.yml - Create user:
sudo useradd -u 1199 -d /var/local/watch_tablet watch_tablet - Add user to input group:
sudo gpasswd -a watch_tablet input - Reload systemd:
sudo systemctl daemon-reload - Fire it up!
sudo systemctl enable --now detect_tablet
How it works
- At boot, the script detects which input event is used for the tablet switch and generates a configuration file for the
watch_tabletdaemon- This is necessary because there is no consistent
/dev/input/by-*path for the tablet switch on the C13 Yoga - The device information is scraped from
/proc/bus/input/devicesto determine the correct/dev/input/event#for the tablet switch - This happens after
keydstarts, but keyd will be immediately reconfigured at this stage if it doesn't already match the current tablet switch state- This is important because the script will not work correctly if keyd is already using the requested configuration
- This is necessary because there is no consistent
- The
watch_tabletdaemon detects state changes in the tablet switch and runs the script- The daemon does not run as root, though the script requires it. The script detects when it is not running as root and elevates itself
sudoallows thewatch_tabletuser to execute the script (and only the script) as root without a password
- The daemon does not run as root, though the script requires it. The script detects when it is not running as root and elevates itself
- When called upon, the script swaps the configuration file for
keydwith one that rebinds every key to a noop, or vice-versa- Disabling the keyboard was originally accomplished by forking off an evtest process that greedily vaccuums up all keypress events
- Enabling it again was accomplished by killing off all
evtestprocesses - This caused issues with the volume rocker and power button
- evtest effectively becomes yet another system service as long as it's running
- This feels wrong
- Enabling it again was accomplished by killing off all
- The supplied keyd config targets a variety of Chrome keyboards, but shouldn't affect an ordinary USB keyboard
- You will need to make some major adjustments for ordinary (non-Chrome) laptop keyboards
- The volumeup, volumedown, and power keys are not bound to noop because the physical volume rocker and power button are not on the keyboard, despite being detected by the kernel as keyboard events
- Disabling the keyboard was originally accomplished by forking off an evtest process that greedily vaccuums up all keypress events
Power/lock button quirks (with Chromebooks and GNOME)
- In the supplied keyd configuration, I have opted to rebind the lock key (f13) on the Chromebook keyboard to Delete
- This is mostly for force of habit, as the lock key is in the same position as the delete key on most other modern (non-Chrome) ThinkPads and laptops.
- The power button (and lock key if used with modifiers) are bound to f15 (or Launch6)
- This will not necessarily prevent it from functioning as a power button, you must set "Power Button Behavior" to "Nothing" if you wish to use it for something else
- Doing this and using a custom shortcut to manually bind Launch6 to
gnome-session-quit --power-offorsystemctl suspendallows the power button to work normally at the desktop, but wake the screen instead of putting the machine to sleep at the lock screen
- Doing this and using a custom shortcut to manually bind Launch6 to
- You can use it to set up custom keyboard shortcuts to make power management more convenient
- Command reference:
- Lock screen:
xdg-screensaver lock - Sleep:
systemctl suspend - Log out:
gnome-session-quit --logout - Reboot:
gnome-session-quit --reboot - Shutdown:
gnome-session-quit --power-off
- Lock screen:
- Command reference:
- This will not necessarily prevent it from functioning as a power button, you must set "Power Button Behavior" to "Nothing" if you wish to use it for something else
Special thanks
This project is effectively just a little bit of shell scripting glue to hold everything together with my machine. Credit to the following dependencies for doing all the hard technical work involved here.
- keyd
- keyd has literally changed my life. I used to struggle with rebinding keys in a way that was compatible with Wayland for hours, only to still end up with a half-assed solution that doesn't work properly. keyd changes everything, and makes it easy to rebind keys at the kernel level, so it works regardless of Xorg, Wayland, or no graphical environment at all.
- It was an exceptionally clever idea to rebind each individual key to a noop so certain specific keys such as the volume rocker could remain enabled
- linux_detect_tablet_mode (also known as the watch_tablet daemon)
- This project laid out the groundwork for detecting the tablet switch and firing off custom commands, but it lacks a couple key functions that are necessary for my use-case
sudo also gets an honorable mention for being a long-standing solution for allowing certain users to run specific commands as root