如何“锁定键盘”以防止在X11/Linux/Gnome上发送更多的按键?

2024-10-01 11:23:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用python为ubuntulinux编写一个反RSI/typingbreak程序。我想能够“锁定键盘”,这样所有的按键都被忽略,直到我“解锁”它。我希望能够迫使用户暂停打字。在

我想要一些程序化的方法来“关闭”键盘(几乎是瞬间),直到我的程序释放它(可能是0.1秒→10秒以后)。虽然我已经“关闭了键盘”,但不应向任何窗口、窗口管理器等发送按键。最好,屏幕仍应显示相同的内容。即使此程序不在前端且没有焦点,也应锁定键盘。在

有些项目已经能够做到这一点(例如Work Rave)

在Linux上怎么做?(最好使用Python)


Tags: 项目方法用户程序内容管理器屏幕键盘
3条回答

基于that,我想出了一个代码:

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?")

在Linux Mint 12,X11,HP笔记本电脑,Gnome上测试。但不确定这些是否重要:)

更新添加了一个更改路径的选项,例如“serio0”或“serio1”。并打印描述,对我来说serio0给了我:i8042 KBD port,如果你有“KBD”,很可能是这样,继续,否则我不能保证:)

典型的方法是获取输入。为此,没有窗口必须实际可见。一个只输入的窗口通常能做到这一点。但是你应该给用户一些反馈,为什么他的输入不再有效。这样做的好处是程序崩溃不会使系统失去响应。在

顺便说一句:我认为强行打断用户,也许在关键操作过程中是一个巨大的不可能!我从来都不明白这些计划的目的。用户会坐在屏幕前无所事事,也许会失去理智。就我的2美分。在

这可以通过使用xinput的shell脚本轻松完成:

 #!/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

这个逻辑在Python中很容易重写。如果安装xinput有问题,那么最好获取xinput的源代码,并尝试使用pythonxlib这样的库在Python中重新实现它。在

相关问题 更多 >