Render tree before destroying X11 containers upon unmap (Thanks Merovius)

When an X11 window is closed (say, urxvt), i3 gets an UnmapNotify event
and destroys (DestroyWindow) the window decorations. Before this commit,
the DestroyWindow call was sent immediately.

This lead to a situation where — due to the DestroyNotify — EnterNotify
events were generated that would cause the focus to be set to the
underlying window.

With this commit, i3 first renders the tree and pushes changes to X11
before calling DestroyWindow. Therefore, the surrounding containers will
take up any space that was freed by the window which was closed and no
EnterNotify will be generated.

fixes #660
next
Michael Stapelberg 2012-12-23 15:54:49 +01:00
parent 79bd2aede5
commit 3a78d489e6
1 changed files with 31 additions and 14 deletions

View File

@ -251,15 +251,29 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
free(con->window);
}
/* kill the X11 part of this container */
x_con_kill(con);
Con *ws = con_get_workspace(con);
/* Figure out which container to focus next before detaching 'con'. */
if (con_is_floating(con)) {
if (con == focused) {
DLOG("This is the focused container, i need to find another one to focus. I start looking at ws = %p\n", ws);
/* go down the focus stack as far as possible */
next = con_next_focused(con);
dont_kill_parent = true;
DLOG("Alright, focusing %p\n", next);
} else {
next = NULL;
}
}
/* Detach the container so that it will not be rendered anymore. */
con_detach(con);
/* disable urgency timer, if needed */
if (con->urgency_timer != NULL) {
DLOG("Removing urgency timer of con %p\n", con);
workspace_update_urgent_flag(con_get_workspace(con));
workspace_update_urgent_flag(ws);
ev_timer_stop(main_loop, con->urgency_timer);
FREE(con->urgency_timer);
}
@ -270,21 +284,24 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
con_fix_percent(parent);
}
/* Render the tree so that the surrounding containers take up the space
* which 'con' does no longer occupy. If we dont render here, there will
* be a gap in our containers and that could trigger an EnterNotify for an
* underlying container, see ticket #660.
*
* Rendering has to be avoided when dont_kill_parent is set (when
* tree_close calls itself recursively) because the tree is in a
* non-renderable state during that time. */
if (!dont_kill_parent)
tree_render();
/* kill the X11 part of this container */
x_con_kill(con);
if (con_is_floating(con)) {
Con *ws = con_get_workspace(con);
DLOG("Container was floating, killing floating container\n");
tree_close(parent, DONT_KILL_WINDOW, false, (con == focused));
DLOG("parent container killed\n");
if (con == focused) {
DLOG("This is the focused container, i need to find another one to focus. I start looking at ws = %p\n", ws);
/* go down the focus stack as far as possible */
next = con_descend_focused(ws);
dont_kill_parent = true;
DLOG("Alright, focusing %p\n", next);
} else {
next = NULL;
}
}
free(con->name);