python xlib xgrabkey密钥释放事件未触发

python xlib xgrabkey密钥释放事件未触发,python,input,xlib,Python,Input,Xlib,我想用pythonxlib捕捉keydown和keyup事件,但是当同时按下一些键时,keyup事件就会消失 如果同时释放2个或多个按键,则会有2个或多个按键事件,但只有1个按键释放事件 要做到这一点,键甚至不必同时释放,例如,如果您快速输入此序列: 按A 按B 发布 释放B 一次只能释放一个按键 按A 按B 释放B 发布 将产生2个密钥释放 从Xlib导入X,XK 从Xlib.display导入显示 输入信号,系统 根=无 显示=无 def抓取密钥名称(n): 全局根 keysym=XK.字符

我想用pythonxlib捕捉keydown和keyup事件,但是当同时按下一些键时,keyup事件就会消失

如果同时释放2个或多个按键,则会有2个或多个按键事件,但只有1个按键释放事件

要做到这一点,键甚至不必同时释放,例如,如果您快速输入此序列:

  • 按A
  • 按B
  • 发布
  • 释放B
  • 一次只能释放一个按键

  • 按A
  • 按B
  • 释放B
  • 发布
  • 将产生2个密钥释放

    从Xlib导入X,XK
    从Xlib.display导入显示
    输入信号,系统
    根=无
    显示=无
    def抓取密钥名称(n):
    全局根
    keysym=XK.字符串\u到\u keysym(n)
    keycode=显示。keysym_至keycode(keysym)
    root.grab_键(keycode,X.AnyModifier,False,X.GrabModeSync,X.GrabModeAsync)
    def main():
    #当前显示
    全局显示,根
    display=display()
    root=display.screen().root
    root.change_属性(event_mask=X.KeyPressMask | X.keyereleaseMask)
    抓取密钥名(“j”)
    抓取密钥名(“k”)
    抓取密钥名(“l”)
    信号。信号(信号。信号,λa,b:系统出口(1))
    信号报警(4)
    尽管如此:
    事件=显示。下一个事件()
    打印事件类型
    main()
    
    尽管这个问题已经有7年历史了,但对于任何遇到这个问题的人来说,这都是一个解决方案:

    这是Xorg中的一个“bug”(显然是故意的),它会导致键盘抓取在按键释放时停止,而在再次按下按钮时才重新开始。因此,(->第二次钥匙释放事件)之间的任何事件都将丢失。看

    提出的解决方案是有一个计数器,指示仍按了多少键,如果仍有未按的键,则手动抓取键盘。此外,在最后一次释放事件之后,键盘需要解锁

    实现可能如下所示:

    keys_pressed = 0
    # ...
    event = display.next_event()
    if event.type == X.KeyPress:
        keys_pressed += 1
    elif event.type == X.KeyRelease:
        if keys_pressed != 0:
            keys_pressed -= 1
            if keys_pressed == 0:
                display.flush()
                display.ungrab_keyboard(X.CurrentTime)
            else:
                root.grab_keyboard(False, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime)
    

    注意检查是否按下了
    键!=发布分支中的0
    :这是因为在解除键盘锁定后,捕获了一个额外的发布事件(可能有一种方法可以防止这种情况发生,但这对我的用例并不重要…

    X开发人员…)。。。。