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
This commit is contained in:
parent
79bd2aede5
commit
3a78d489e6
45
src/tree.c
45
src/tree.c
@ -251,15 +251,29 @@ bool tree_close(Con *con, kill_window_t kill_window, bool dont_kill_parent, bool
|
|||||||
free(con->window);
|
free(con->window);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* kill the X11 part of this container */
|
Con *ws = con_get_workspace(con);
|
||||||
x_con_kill(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);
|
con_detach(con);
|
||||||
|
|
||||||
/* disable urgency timer, if needed */
|
/* disable urgency timer, if needed */
|
||||||
if (con->urgency_timer != NULL) {
|
if (con->urgency_timer != NULL) {
|
||||||
DLOG("Removing urgency timer of con %p\n", con);
|
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);
|
ev_timer_stop(main_loop, con->urgency_timer);
|
||||||
FREE(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);
|
con_fix_percent(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Render the tree so that the surrounding containers take up the space
|
||||||
|
* which 'con' does no longer occupy. If we don’t 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)) {
|
if (con_is_floating(con)) {
|
||||||
Con *ws = con_get_workspace(con);
|
|
||||||
DLOG("Container was floating, killing floating container\n");
|
DLOG("Container was floating, killing floating container\n");
|
||||||
tree_close(parent, DONT_KILL_WINDOW, false, (con == focused));
|
tree_close(parent, DONT_KILL_WINDOW, false, (con == focused));
|
||||||
DLOG("parent container killed\n");
|
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);
|
free(con->name);
|
||||||
|
Loading…
Reference in New Issue
Block a user