XSendEvent不起作用

XSendEvent not working

本文关键字:不起作用 XSendEvent      更新时间:2023-10-16

我正试图根据这个例子和随后的注释发送一个X事件:

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <cstdio>
#include <iostream>
#include <string>
#include <unistd.h>
// #include <X11/extensions/XTest.h> // Uncomment to use XTestFakeKeyEvent()
// The key code to be sent.
// A full list of available codes can be found in /usr/include/X11/keysymdef.h
#define KEYCODE XK_Down
// Function to create an X11 keyboard event
// http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html
XKeyEvent createKeyEvent(Display *display, Window &win, Window &winRoot,
                         bool press, int keycode, int modifiers) {
    XKeyEvent event;
    event.display = display;
    event.window = win;
    event.root = winRoot;
    event.subwindow = None;
    event.time = CurrentTime;
    event.x = 1;
    event.y = 1;
    event.x_root = 1;
    event.y_root = 1;
    event.same_screen = True;
    event.keycode = XKeysymToKeycode(display, keycode);
    event.state = modifiers;
    if (press)
        event.type = KeyPress;
    else
        event.type = KeyRelease;
    return event;
}
int main() {
    // Obtain the X11 display.
    Display *display = XOpenDisplay(0);
    if (display == NULL) return -1;
    // Get the root window for the current display.
    Window winRoot = XDefaultRootWindow(display);
    // Find the window which has the current keyboard focus.
    Window winFocus;
    int revert;
    XGetInputFocus(display, &winFocus, &revert);
    // Send a fake key press event to the window.
    XKeyEvent event =
        createKeyEvent(display, winFocus, winRoot, true, KEYCODE, 0);
    int res = XSendEvent(event.display, event.window, True, KeyPressMask,
                         (XEvent *)&event);
    // int res =
    //     XTestFakeKeyEvent(event.display, event.keycode, True, CurrentTime);
    std::cout << ((res != 0) ? std::string("Sent successfully")
                             : std::string("Sending failed")) << std::endl;
    sleep(1);
    if (XPending(display))
        std::cout << "Got it!" << std::endl;
    else
        std::cout << "It's lost..." << std::endl;
    // Done.
    XCloseDisplay(display);
    return 0;
}

根据输出,无论我使用XSendEvent还是XTestFakeKeyEvent(注释掉的代码),事件都会被发送为OK,然后丢失。我正在Ubuntu 14.04下使用gcc 4.8.2编译代码。缺少什么?

为了接收事件,X11应用程序通常需要注册对它们的兴趣。这是通过XSelectInput功能完成的:

XSelectInput(display, winFocus, KeyPressMask|KeyReleaseMask); 

告诉X11这个客户端想要接收与winFocus相关联的按键和按键释放事件。