4

I have a touchscreen laptop that folds back enough to become like a tablet. If I put it down on the table, I don't want to be hitting keys accidentally, so I'm working on a script to disable the keyboard when I hit Ctrl-F10 and then re-enable it when I do that again. I'm using xlib from PyPI, and I've gotten this so far:

from Xlib.display import Display
from Xlib.ext import xinput

class Handler:
    def __init__(self, display):
        self.enabled = True
        self.display = display

    def handle(self, event):
        if event.data['detail'] == 76 and event.data['mods']['base_mods'] == 4:
            if self.enabled:
                self.display.grab_server()
            else:
                self.display.ungrab_server()
            self.enabled = not self.enabled

try:
    display = Display()
    handler = Handler(display)
    screen = display.screen()
    screen.root.xinput_select_events([
        (xinput.AllDevices, xinput.KeyPressMask),
    ])
    while True:
        event = display.next_event()
        handler.handle(event)
finally:
    display.close()

It does disable the keyboard on Ctrl-F10, but as soon as I re-enable, all the keys I pressed when it was disabled are activated all at once. Is there a way to clear the queue before re-enabling, or a better way to disable the keyboard?

zondo
  • 19,901
  • 8
  • 44
  • 83

1 Answers1

0

Try XGrabKeyboard: https://tronche.com/gui/x/xlib/input/XGrabKeyboard.html

(But this requires you to create your own window for grabbing; you can e.g. create a window of size 1x1 at position -10x-10)

I think the values for things like owner_events and keyboard_mode do not matter much. The main effect should be that the input focus goes to your own window. time should be CurrentTime (which is 0) and pointer_mode should be GrabModeAsync, so that you do not interfere with the pointer.

Uli Schlachter
  • 9,337
  • 1
  • 23
  • 39