Блок Клавиатура, но получить глобальные горячие клавиши XLib - PullRequest
3 голосов
/ 17 мая 2011

[решено - Приведенный пример содержит ответ!] Я пытаюсь реализовать программу, которая запускается в полноэкранном режиме и не допускает никакого пользовательского ввода (мышь или клавиатура), потому что она просто реагирует на сигналы UDEV, когда вставляется флешка или компакт-диск. Я хочу предупредить, что пользователь вставляет клавиатуру / мышь и делает что-то странное с рабочей станцией. Единственный случай, когда требуется клавиатура, - это когда администратор вставляет клавиатуру и нажимает CTRL-T, поэтому моя программа открывает окно терминала.

Я работаю с Debian (Squeeze) + Gnome-Desktop-Environment.

Я пытался использовать XLib, который отлично работает для захвата всех событий клавиатуры, но я не могу отсоединить клавиатуру, когда моя программа открывает мой терминал (который также работает отлично), поэтому пользователь не может использовать оболочку, если только клавиатура загрузка отключена.

Вот несколько важных фрагментов кода:

class ScanWSClient(gtk.Window):

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

         gtk.Window.__init__(self)           

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

         #self.fullscreen()

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

         self._browser.open(url)
         self.show_all()

class KeyboardHandler(threading.Thread):
   def __init__(self, scanws_client):
         super(KeyboardHandler,self).__init__()
         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()
                self.handle_event(event)
                time.sleep(1)

   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")
                      else:
                            self.scanws_client.terminal_window.present()
                            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

В моем многопоточном KeyboardHandler я извлекаю все события в очереди xlib и проверяю с помощью своей функции handle_event, нажата ли CTRL-T. Если это так, я открываю свой терминал и убираю клавиатуру (не работает):

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

Кто может сказать мне, почему я не могу снять свою глупую клавиатуру? (этот вопрос предоставлен cookie;))

1 Ответ

1 голос
/ 19 мая 2011

Вы сбрасывали вызовы на X-сервер?Xlib является асинхронным и буферизует все запросы до тех пор, пока вы не заполните буфер, не сделаете вызов, который требует ответа от сервера, или вызовите XFlush (интерфейс C API, не уверен, что имя привязки python).

...