[已解决 - 提供的示例包含答案!] 我正在尝试实现一个以全屏启动的程序,并且不允许任何用户输入(更好的鼠标或键盘),因为它只是在插入usb-stick或cd时对UDEV-Signals做出反应。 我想阻止,用户放入键盘/鼠标,并对工作站做一些奇怪的事情。 唯一需要键盘的情况是,当管理员插入键盘并按下CTRL-T时,我的程序会打开一个终端窗口。
我使用Debian(Squeeze)+ Gnome-Desktop-Environment。
我尝试使用XLib,它可以很好地抓取所有的键盘事件,但是当我的程序打开我的终端(它工作也很完美)时我无法忘记我的键盘,所以用户不能使用shell,除非键盘 - 提取已关闭。
这里有一些重要的代码片段:
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;))
答案 0 :(得分:1)
您是否刷新了对X服务器的呼叫? Xlib是异步的并且缓冲所有请求,直到您填充缓冲区,进行需要服务器响应的调用,或调用XFlush(C API接口,不确定python绑定名称)。