Cleaning my laptop keyboard has always been a minor annoyance. I either had to turn the entire machine off (slow and disruptive), or lock the session and clean it anyway. The latter meant that keys pressed during cleaning would wake the monitor, spam random characters into the lock screen password prompt, and sometimes trigger security lockouts or run system macros if function keys were hit.
I wanted a way to press a single button, have the desktop remain completely visible, disable all physical keyboard hardware inputs temporarily, and enable them back using my mouse or touchpad once the keyboard was clean.
Hyprland allows modifying input configuration dynamically via its IPC socket using the device keyword. I can disable or enable specific devices on-the-fly using commands like:
hyprctl keyword "device[at-translated-set-2-keyboard]:enabled" false
By querying all connected keyboards programmatically and generating this rule for each of them, I could block all physical keyboard typing without affecting my mouse, touchpad, or overall UI rendering.
Here is how I wired the solution inside my Caelestia Shell configuration:
Create the KeyboardLock Singleton Service
I created a new Singleton service in Quickshell that queries the keyboard list via hyprctl devices -j and toggles the enabled state of each physical keyboard device.
pragma Singleton
import QtQuick
import Quickshell
Singleton {
id: root
property bool enabled: false
onEnabledChanged: {
if (enabled) {
Quickshell.execDetached([
"bash", "-c",
"hyprctl devices -j | jq -r '.keyboards[].name' | " +
"while read -r kb; do hyprctl keyword \"device[$kb]:enabled\" false; done"
]);
Toaster.toast(qsTr("Keyboard Locked"), qsTr("All keyboard inputs are disabled."), "keyboard");
} else {
Quickshell.execDetached([
"bash", "-c",
"hyprctl devices -j | jq -r '.keyboards[].name' | " +
"while read -r kb; do hyprctl keyword \"device[$kb]:enabled\" true; done"
]);
Toaster.toast(qsTr("Keyboard Unlocked"), qsTr("Keyboard inputs enabled."), "keyboard");
}
}
}
Add the Toggle button to Quick Settings
I added a toggle card in Toggles.qml linking to this service, rendering a keyboard icon. Since mouse inputs are untouched, clicking the toggle again with the mouse or touchpad seamlessly restores physical keyboard inputs.
Solve the Lockscreen Deadlock
During testing, I found a dangerous deadlock: if I left the keyboard locked for too long, my system's idle monitor daemon would think I'm inactive and trigger the desktop lock screen automatically. With the lock screen active and the physical keyboard disabled, I could no longer type my password to unlock the session!
To solve this, I modified the idle monitor wrapper in my shell config to temporarily suspend screen locking actions while the keyboard lock is active.
// Inhibit automatic screen locking while KeyboardLock is enabled
readonly property bool enabled: (!GlobalConfig.general.idle.inhibitWhenAudio || !Players.list.some(p => p.isPlaying)) && !KeyboardLock.enabled
hyprctl devices -j lists all devices categorized under keyboards, virtual keyboard drivers (such as Bluetooth headsets registers) and peripheral mouse buttons may also be toggled. Ensure your pointing device (touchpad/mouse) is active to toggle the mode off.