I'm trying to send key events by creating a XKeyEvent and sending it using XSendEvent (inspired by this post). The XKeyEvents are prepared as follows:
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;
}
Then they are sent with XSendEvent(event.display, event.window, 1, KeyPressMask, (XEvent *)&event);
The key events are sent and the target program receives them (letters are entered, arrow keys work etc.). However, problems arise with modifier keys. Let's say the program sends a key-down event for the opt/alt key. In this scenario, the text in the menu bar is underlined until a key-up event is sent (indicating that the X-server has received and processed the key-down event).
However, when retrieving the the current state of the modifier keys, the modifier keys do not appear to be pressed at all. When calling XQueryPointer(self->display, winFocus, &root_return, &child_return, &root_x_return, &root_y_return, &win_x_return, &win_y_return, &keyboard_state_mask);
, the keyboard_state_mask is 0. Checking the keyboard with xev
gives the same result. Physically pressing the modifier keys does change the state mask, both in xev
and in my code.
How do I properly change the current modifier-key state?