]> git.sur5r.net Git - i3/i3/commitdiff
Bugfix: Either use SetInputFocus *or* send WM_TAKE_FOCUS, not both
authorMichael Stapelberg <michael@stapelberg.de>
Tue, 17 Jan 2012 23:33:33 +0000 (23:33 +0000)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 17 Jan 2012 23:33:33 +0000 (23:33 +0000)
This fixes problems with the Oracle JRE7, which checks the current focus after
receiving WM_TAKE_FOCUS and just does nothing when the focus is on one of its
windows. Hopefully it doesn’t introduce any regressions :).

src/x.c

diff --git a/src/x.c b/src/x.c
index e8bfaeb4ecd1c2e4576c0c0b9a1dabb880d14c6c..42bb744d1c3a7382dd98829e935be3fd65b30238 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -849,26 +849,29 @@ void x_push_changes(Con *con) {
             /* Invalidate focused_id to correctly focus new windows with the same ID */
             focused_id = XCB_NONE;
         } else {
-            DLOG("Updating focus (focused: %p / %s)\n", focused, focused->name);
-            /* We remove XCB_EVENT_MASK_FOCUS_CHANGE from the event mask to get
-             * no focus change events for our own focus changes. We only want
-             * these generated by the clients. */
-            if (focused->window != NULL) {
-                values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
-                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);
-            if (focused->window != NULL) {
-                values[0] = CHILD_EVENT_MASK;
-                xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
-            }
-
             if (focused->window != NULL &&
                 focused->window->needs_take_focus) {
+                DLOG("Updating focus by sending WM_TAKE_FOCUS to window 0x%08x only (focused: %p / %s)\n",
+                     to_focus, focused, focused->name);
                 send_take_focus(to_focus);
+            } else {
+                DLOG("Updating focus (focused: %p / %s)\n", focused, focused->name);
+                /* We remove XCB_EVENT_MASK_FOCUS_CHANGE from the event mask to get
+                 * no focus change events for our own focus changes. We only want
+                 * these generated by the clients. */
+                if (focused->window != NULL) {
+                    values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
+                    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);
+                if (focused->window != NULL) {
+                    values[0] = CHILD_EVENT_MASK;
+                    xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
+                }
+
+                ewmh_update_active_window(to_focus);
             }
 
-            ewmh_update_active_window(to_focus);
             focused_id = to_focus;
         }
     }