Take the 2-minute tour ×

[SOLVED - Provided example contains the answer!] I am trying to implement a program which is started in fullscreen and does not allow any userinput (wether mouse nor keyboard) because it just reacts on UDEV-Signals, when a usb-stick or cd is inserted. I want to prevent, that a user puts in a keyboard / mouse and does somethin weird with the workstation. The only case, that a keyboard is needed, is when an administrator inserts a keyboard and presses CTRL-T, so my program opens a terminal-window.

I work with a Debian (Squeeze) + Gnome-Desktop-Environment.

I tried to use XLib, which works fine for grabbing all Keyboard-Events, but I cannot ungrab my keyboard, when my program opens my terminal (which works also perfectly), so the user cannot use the shell unless the keyboard-fetching is turned off.

here are some crucial code-fragments:

class ScanWSClient(gtk.Window):

   def __init__(self, url):
         # current display
         disp = Display()
         self.display = disp


         self.terminal_window = None
         self.kb_handler = KeyboardHandler(self).start()


         self._browser= webkit.WebView()
         self.connect('destroy', gtk.main_quit)


class KeyboardHandler(threading.Thread):
   def __init__(self, scanws_client):
         self.running = True
         self.daemon = True          
         self.terminal_window = None
         self.scanws_client = scanws_client #

   def run(self):
         root = self.scanws_client.display.screen().root

         while self.running:
                event = root.display.next_event()

   def handle_event(self,aEvent):
                keycode = aEvent.detail
                state = aEvent.state
                key_type = aEvent.type

                if keycode == 28 and key_type == X.KeyPress:
                      if self.scanws_client.terminal_window == None:
                            self.scanws_client.terminal_window = TerminalWindow(self.scanws_client, "Administrative Shell started...Type  *exit* to return to the locked workstation")
                            self.scanws_client.display.flush() #THIS FLUSH IS NECESSARY TO UNGRAB THE KEYBOARD LATER ON!!!
                      self.scanws_client.display.ungrab_keyboard(1, X.CurrentTime) 
                      print "Key: %s / Mask: %s / Type: %s" % (keycode, state, key_type)

                print self.scanws_client.terminal_window

In my threaded KeyboardHandler, I fetch all xlib-queued events and check with my function "handle_event", if there is CTRL-T pressed. If so, I open my terminal and ungrab my keyboard (doesnt work):

self.scanws_client.display.ungrab_keyboard(1, X.CurrentTime)

Who can tell me why I cannot ungrab my silly Keyboard? (this question is cookie provided ;) )

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

Did you flush the calls to the X server? Xlib is asynchronous and buffers all requests until you fill the buffer, make a call that needs a response from the server, or call XFlush (the C API interface, not sure the python binding name).

share|improve this answer
Works perfect. But in GrabModeAsync, it has a little latency between my CTRL-T input and my terminal-popup... But I think that´s the retention mentioned in the documentation between hardware-event and xlib-handling... I update my example, so everyone sees how to solve it.. thanks –  Cpt.Obvious May 23 '11 at 11:58
add comment

Your Answer


