*
*/
static void handle_unmap_notify_event(xcb_unmap_notify_event_t *event) {
- /* If the client (as opposed to i3) destroyed or unmapped a window, an
- * EnterNotify event will follow (indistinguishable from an EnterNotify
- * event caused by moving your mouse), causing i3 to set focus to whichever
- * window is now visible.
- *
- * In a complex stacked or tabbed layout (take two v-split containers in a
- * tabbed container), when the bottom window in tab2 is closed, the bottom
- * window of tab1 is visible instead. X11 will thus send an EnterNotify
- * event for the bottom window of tab1, while the focus should be set to
- * the remaining window of tab2.
- *
- * Therefore, we ignore all EnterNotify events which have the same sequence
- * as an UnmapNotify event. */
- add_ignore_event(event->sequence, XCB_ENTER_NOTIFY);
-
DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence);
+ xcb_get_input_focus_cookie_t cookie;
Con *con = con_by_window_id(event->window);
if (con == NULL) {
/* This could also be an UnmapNotify for the frame. We need to
LOG("Not a managed window, ignoring UnmapNotify event\n");
return;
}
+
if (con->ignore_unmap > 0)
con->ignore_unmap--;
+ /* See the end of this function. */
+ cookie = xcb_get_input_focus(conn);
DLOG("ignore_unmap = %d for frame of container %p\n", con->ignore_unmap, con);
- return;
+ goto ignore_end;
}
+ /* See the end of this function. */
+ cookie = xcb_get_input_focus(conn);
+
if (con->ignore_unmap > 0) {
DLOG("ignore_unmap = %d, dec\n", con->ignore_unmap);
con->ignore_unmap--;
- return;
+ goto ignore_end;
}
tree_close(con, DONT_KILL_WINDOW, false, false);
tree_render();
x_push_changes(croot);
- return;
+
+ignore_end:
+ /* If the client (as opposed to i3) destroyed or unmapped a window, an
+ * EnterNotify event will follow (indistinguishable from an EnterNotify
+ * event caused by moving your mouse), causing i3 to set focus to whichever
+ * window is now visible.
+ *
+ * In a complex stacked or tabbed layout (take two v-split containers in a
+ * tabbed container), when the bottom window in tab2 is closed, the bottom
+ * window of tab1 is visible instead. X11 will thus send an EnterNotify
+ * event for the bottom window of tab1, while the focus should be set to
+ * the remaining window of tab2.
+ *
+ * Therefore, we ignore all EnterNotify events which have the same sequence
+ * as an UnmapNotify event. */
+ add_ignore_event(event->sequence, XCB_ENTER_NOTIFY);
+
+ /* Since we just ignored the sequence of this UnmapNotify, we want to make
+ * sure that following events use a different sequence. When putting xterm
+ * into fullscreen and moving the pointer to a different window, without
+ * using GetInputFocus, subsequent (legitimate) EnterNotify events arrived
+ * with the same sequence and thus were ignored (see ticket #609). */
+ free(xcb_get_input_focus_reply(conn, cookie, NULL));
}
/*
xcb_icccm_wm_hints_t hints;
- if (reply != NULL) {
- if (!xcb_icccm_get_wm_hints_from_reply(&hints, reply))
- return false;
- } else {
- if (!xcb_icccm_get_wm_hints_reply(conn, xcb_icccm_get_wm_hints_unchecked(conn, con->window->id), &hints, NULL))
+ if (reply == NULL)
+ if (!(reply = xcb_get_property_reply(conn, xcb_icccm_get_wm_hints(conn, window), NULL)))
return false;
- }
+
+ if (!xcb_icccm_get_wm_hints_from_reply(&hints, reply))
+ return false;
if (!con->urgent && focused == con) {
DLOG("Ignoring urgency flag for current client\n");
- FREE(reply);
- return true;
+ goto end;
}
/* Update the flag on the client directly */
tree_render();
- FREE(reply);
+end:
+ if (con->window)
+ window_update_hints(con->window, reply);
+ else free(reply);
return true;
}