Reframe swallowed windows if depth doesn't match

X will not allow a window with ParentRelative background to be created
or reparented under a window with mismatching color depth.
Deal with this by destroying the container frame and creating a new one
with the right depth upon swallowing.
Defer destruction of the frame window until after the updated tree has
been rendered to avoid some distracting flickering.

Fixes #3297
This commit is contained in:
Dan Elkouby
2018-06-01 18:55:35 +03:00
parent 26f50898fd
commit 7ac37d8ae4
3 changed files with 39 additions and 6 deletions

25
src/x.c
View File

@ -249,11 +249,7 @@ void x_move_win(Con *src, Con *dest) {
}
}
/*
* Kills the window decoration associated with the given container.
*
*/
void x_con_kill(Con *con) {
static void _x_con_kill(Con *con) {
con_state *state;
if (con->colormap != XCB_NONE) {
@ -262,7 +258,6 @@ void x_con_kill(Con *con) {
draw_util_surface_free(conn, &(con->frame));
draw_util_surface_free(conn, &(con->frame_buffer));
xcb_destroy_window(conn, con->frame.id);
xcb_free_pixmap(conn, con->frame_buffer.id);
state = state_for_frame(con->frame.id);
CIRCLEQ_REMOVE(&state_head, state, state);
@ -275,6 +270,24 @@ void x_con_kill(Con *con) {
focused_id = last_focused = XCB_NONE;
}
/*
* Kills the window decoration associated with the given container.
*
*/
void x_con_kill(Con *con) {
_x_con_kill(con);
xcb_destroy_window(conn, con->frame.id);
}
/*
* Completely reinitializes the container's frame, without destroying the old window.
*
*/
void x_con_reframe(Con *con) {
_x_con_kill(con);
x_con_init(con);
}
/*
* Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
*