我正在尝试通过创建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
和我的代码。
如何正确更改当前修饰符键状态?
答案 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服务器实现中的错误。