How do I 'lock the keyboard' to prevent any more keypresses being sent on X11/Linux/Gnome?
Solution 1:
Based on that, here's a code I came up with:
class KeyboardLocker:
def __init__(self, serio=0):
self._on = False
self.serio = serio
def on(self):
return self._on
def write_value(self,path, value):
with open(path, "a") as f:
f.write(value)
def toggle(self):
if self.on():
self.turn_off()
else:
self.turn_on()
def description(self):
path = '/sys/devices/platform/i8042/serio%d/description' % (self.serio,)
with open(path, "r") as f:
description = f.read()
return description
def turn_on(self):
try:
self.write_value('/sys/devices/platform/i8042/serio%d/bind_mode' % (self.serio,),
'auto')
except IOError, e:
self._on = False
raise
else:
self._on = True
return self.on()
def turn_off(self):
try:
self.write_value('/sys/devices/platform/i8042/serio%d/bind_mode' % (self.serio,),
'manual')
self.write_value('/sys/devices/platform/i8042/serio%d/drvctl' % (self.serio,),
'psmouse')
except IOError, e:
self._on = True
raise
else:
self._on = False
return self.on()
if __name__ == "__main__":
kl = KeyboardLocker(serio=0)
device = kl.description()
print "We got a lock on", device
proceed = raw_input("Do you want to proceed? (y/n)").lower().startswith("y")
import sys
if not proceed: sys.exit(1)
kl.turn_off()
import time
wait = 5
print "Sleeping few seconds...", wait
time.sleep(wait)
print "Voila!"
kl.turn_on()
raw_input("Does it work now?")
Tested on Linux Mint 12, X11, HP Laptop, Gnome. Not sure if any of that matters though :)
UPDATE Added an option to change the path, e.g. "serio0" or "serio1". And prints the description, for me serio0 gave me: i8042 KBD port
, most likely if you have "KBD" in it, it's right, continue, otherwise I give you no guarantee :)
Solution 2:
The canonical way to do this is by grabbing the input. For this no window must be actually visible. A input only window usually does the trick. However you should give the user some sort of feedback, why his input no longer works. Doing this as a focus grab has the advantage that a crash of the program won't turn the system unresponsive.
BTW: I think forcibly interrupting the user, maybe in the middle of a critical operations is a huge No-Go! I never understood the purpose of those programs. The user will sit in front of the screen idling, maybe loosing his thoughts. Just my 2 cents.
Solution 3:
This can be done easily with a shell script using xinput :
#!/bin/sh
do_it() {
# need error checking there. We should also restrict which device gets
# deactivated, by checking other properties.
keyboard_ids="$(xinput list | sed -rn 's/.*id=([0-9]+).*slave\s+keyboard.*/\1/p')"
for keyboard_id in $keyboard_ids; do
# 121 is "Device Active".
# use xinput watch-props $device_id to see some properties.
xinput set-int-prop $keyboard_id 121 8 $1;
done;
}
# you maybe don't want to exit in case of failure there.
do_it 0 ; sleep 5; do_it 1
This logic is easily rewritable in Python. If installing xinput is problematic, it might be a good idea to fetch the source of xinput and try to reimplement it in Python using a library like python-xlib.