Python 如何在X11中捕获另一个按键事件后发送按键

Python 如何在X11中捕获另一个按键事件后发送按键,python,input,keyboard,x11,xlib,Python,Input,Keyboard,X11,Xlib,我试图在Linux中实现一个Python脚本,以捕获按键a再次发送按键a(因此它会发送a两次) 通过一些代码,我得出以下结论 可以很好地捕获按键,但发送按键事件不会起任何作用。我错过了什么 我也看了这个问题。发布的解决方案甚至似乎没有收到事件(在将打印移植到Python3之后) 今天我在谷歌上搜索了很多,发现了一些对我有用的东西 关键思想是使用display而不是window来发送事件,以及sync显示。如果不同步显示,则根本不会注册按键 显示发送事件(窗口、事件、传播=True) disp.s

我试图在Linux中实现一个Python脚本,以捕获按键
a
再次发送按键
a
(因此它会发送
a
两次)

通过一些代码,我得出以下结论

可以很好地捕获按键,但发送按键事件不会起任何作用。我错过了什么

我也看了这个问题。发布的解决方案甚至似乎没有收到事件(在将
打印
移植到Python3之后)


今天我在谷歌上搜索了很多,发现了一些对我有用的东西

关键思想是使用
display
而不是
window
来发送事件,以及
sync
显示。如果不同步显示,则根本不会注册按键

显示发送事件(窗口、事件、传播=True) disp.sync() 将其应用于上面的脚本,我们有以下工作版本:

import time

from Xlib import X, protocol
from Xlib.display import Display
from Xlib.ext import record

display = None
root = None

def handler(reply):
    data = reply.data
    while len(data):
        event, data = protocol.rq.EventField(None).parse_binary_value(data, display.display, None, None)
        if event.type == X.KeyPress:
            keycode = event.detail
            print(keycode)
            if keycode == 38:
                disp = Display()
                window = disp.get_input_focus().focus
                root = disp.screen().root
                event = protocol.event.KeyPress(
                    time=0,
                    root=root, window=window, same_screen=0, child=X.NONE,
                    root_x=0, root_y=0, event_x=0, event_y=0,
                    state=0, detail=keycode
                )
                disp.send_event(window, event, propagate=True)
                disp.sync()
                event = protocol.event.KeyRelease(
                    time=0,
                    root=root, window=window, same_screen=0, child=X.NONE,
                    root_x=0, root_y=0, event_x=0, event_y=0,
                    state=0, detail=keycode
                )
                disp.send_event(window, event, propagate=True)
                disp.sync()


def main():
    global display, root
    display = Display()
    root = display.screen().root

    ctx = display.record_create_context(
        0,
        [record.AllClients],
        [{
            'core_requests': (0, 0),
            'core_replies': (0, 0),
            'ext_requests': (0, 0, 0, 0),
            'ext_replies': (0, 0, 0, 0),
            'delivered_events': (0, 0),
            'device_events': (X.KeyReleaseMask, X.ButtonReleaseMask),
            'errors': (0, 0),
            'client_started': False,
            'client_died': False,
        }]
    )
    display.record_enable_context(ctx, handler)
    display.record_free_context(ctx)

    while True:
        # Infinite wait, doesn't do anything as no events are grabbed.
        event = root.display.next_event()


if __name__ == '__main__':
    main()
import time

from Xlib import X, protocol
from Xlib.display import Display
from Xlib.ext import record

display = None
root = None

def handler(reply):
    data = reply.data
    while len(data):
        event, data = protocol.rq.EventField(None).parse_binary_value(data, display.display, None, None)
        if event.type == X.KeyPress:
            keycode = event.detail
            print(keycode)
            if keycode == 38:
                disp = Display()
                window = disp.get_input_focus().focus
                root = disp.screen().root
                event = protocol.event.KeyPress(
                    time=0,
                    root=root, window=window, same_screen=0, child=X.NONE,
                    root_x=0, root_y=0, event_x=0, event_y=0,
                    state=0, detail=keycode
                )
                disp.send_event(window, event, propagate=True)
                disp.sync()
                event = protocol.event.KeyRelease(
                    time=0,
                    root=root, window=window, same_screen=0, child=X.NONE,
                    root_x=0, root_y=0, event_x=0, event_y=0,
                    state=0, detail=keycode
                )
                disp.send_event(window, event, propagate=True)
                disp.sync()


def main():
    global display, root
    display = Display()
    root = display.screen().root

    ctx = display.record_create_context(
        0,
        [record.AllClients],
        [{
            'core_requests': (0, 0),
            'core_replies': (0, 0),
            'ext_requests': (0, 0, 0, 0),
            'ext_replies': (0, 0, 0, 0),
            'delivered_events': (0, 0),
            'device_events': (X.KeyReleaseMask, X.ButtonReleaseMask),
            'errors': (0, 0),
            'client_started': False,
            'client_died': False,
        }]
    )
    display.record_enable_context(ctx, handler)
    display.record_free_context(ctx)

    while True:
        # Infinite wait, doesn't do anything as no events are grabbed.
        event = root.display.next_event()


if __name__ == '__main__':
    main()