XSendEvent不会更改修饰键状态

时间:2016-06-29 07:46:17

标签: c++ c x11 keyboard-events xlib

我正在尝试通过创建XKeyEvent并使用XSendEvent(受this帖子启发)发送密钥事件。 XKeyEvents准备如下:

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     = keycode;
    event.state       = modifiers;

    if (press) {
        event.type = KeyPress;
    } else {
        event.type = KeyRelease;
    }

    return event;
}

然后他们会与XSendEvent(event.display, event.window, 1, KeyPressMask, (XEvent *)&event);

一起发送

发送关键事件并且目标程序接收它们(输入字母,箭头键工作等)。但是,修改键会出现问题。假设程序发送opt / alt键的按键事件。在这种情况下,菜单栏中的文本带有下划线,直到发送了一个键盘事件(表明X服务器已收到并处理了按键事件)。

但是,在检索修改键的当前状态时,根本不会按下修改键。调用XQueryPointer(self->display, winFocus, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &keyboard_state_mask);时,keyboard_state_mask为0.使用xev检查键盘会得到相同的结果。物理按下修饰键确实会改变状态掩码,包括xev和我的代码。

如何正确更改当前修饰符键状态?

2 个答案:

答案 0 :(得分:0)

使用库int XTestFakeButtonEvent(display, button, is_press, delay)中的方法<X11/extensions/XTest.h>解决了问题。由于某种原因,这会导致键盘修改器状态在发送修改键时发生变化(如我所愿),而上述方法则不然。

答案 1 :(得分:0)

来自xsendevent手册页:

“除了在转发事件中强制send_event为True并在事件中正确设置序列号之外,X服务器不会更改事件的内容并取消选中该事件。”

我假设您从以下位置复制了createKeyEvent():http://www.doctort.org/adam/nerd-notes/x11-fake-keypress-event.html

如果您还复制了调用此函数的方式:

createKeyEvent(display,winFocus,winRoot,false,KEYCODE,0);

然后有意义的是“修饰符”没有设置为任何东西,因为最后一个参数是“0”。根据文档,您需要自己设置修改器状态。

我没有验证这些信息。如果它没有按照文档记录的那样工作,那么它可能是文档错误或X服务器实现中的错误。