Use the last known timestamp when calling xcb_set_input_focus(). (#2332)
In most cases this won't make a difference, but consider the following scenario: * Some application acquires input focus on its own (which the window manager is not involved in, so it will "always" work). * Before the FocusIn / FocusOut events are processed by i3, the workflow to push X changes is run, resulting in xcb_set_input_focus() being called. Using XCB_CURRENT_TIME, this means i3 will "win" and override the focus, even though it simply wasn't aware (yet) that focus had already been taken over by someone else. When processing the FocusIn / FocusOut events, i3 assumes that the focus is already set which results in a broken focus state as i3 assumes some container has the input focus when it doesn't. With the new behavior, i3's attempt to set the input focus will fail if the FocusIn / FocusOut events have not yet processed. Once they are processed, the focus state will be automatically corrected. fixes #2322
This commit is contained in:
parent
b2397c9f01
commit
6746aa4b5f
4
src/x.c
4
src/x.c
|
@ -1115,7 +1115,7 @@ void x_push_changes(Con *con) {
|
||||||
values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
|
values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
|
||||||
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
|
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
|
||||||
}
|
}
|
||||||
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
|
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, last_timestamp);
|
||||||
if (focused->window != NULL) {
|
if (focused->window != NULL) {
|
||||||
values[0] = CHILD_EVENT_MASK;
|
values[0] = CHILD_EVENT_MASK;
|
||||||
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
|
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
|
||||||
|
@ -1135,7 +1135,7 @@ void x_push_changes(Con *con) {
|
||||||
/* If we still have no window to focus, we focus the EWMH window instead. We use this rather than the
|
/* If we still have no window to focus, we focus the EWMH window instead. We use this rather than the
|
||||||
* root window in order to avoid an X11 fallback mechanism causing a ghosting effect (see #1378). */
|
* root window in order to avoid an X11 fallback mechanism causing a ghosting effect (see #1378). */
|
||||||
DLOG("Still no window focused, better set focus to the EWMH support window (%d)\n", ewmh_window);
|
DLOG("Still no window focused, better set focus to the EWMH support window (%d)\n", ewmh_window);
|
||||||
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, ewmh_window, XCB_CURRENT_TIME);
|
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, ewmh_window, last_timestamp);
|
||||||
ewmh_update_active_window(XCB_WINDOW_NONE);
|
ewmh_update_active_window(XCB_WINDOW_NONE);
|
||||||
focused_id = ewmh_window;
|
focused_id = ewmh_window;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue