Merge pull request #3301 from Streetwalrus/swallow-reframe

Reframe swallowed windows if depth doesn't match
This commit is contained in:
Ingo Bürk 2018-06-02 14:51:18 +02:00 committed by GitHub
commit 05a1dc0f6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 6 deletions

View File

@ -49,6 +49,12 @@ void x_reinit(Con *con);
*/ */
void x_con_kill(Con *con); void x_con_kill(Con *con);
/*
* Completely reinitializes the container's frame, without destroying the old window.
*
*/
void x_con_reframe(Con *con);
/** /**
* Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW) * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
* *

View File

@ -355,8 +355,16 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
} }
} }
} }
xcb_window_t old_frame = XCB_NONE;
if (nc->window != cwindow && nc->window != NULL) { if (nc->window != cwindow && nc->window != NULL) {
window_free(nc->window); window_free(nc->window);
/* Match frame and window depth. This is needed because X will refuse to reparent a
* window whose background is ParentRelative under a window with a different depth. */
if (nc->depth != cwindow->depth) {
old_frame = nc->frame.id;
nc->depth = cwindow->depth;
x_con_reframe(nc);
}
} }
nc->window = cwindow; nc->window = cwindow;
x_reinit(nc); x_reinit(nc);
@ -647,6 +655,12 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
tree_render(); tree_render();
/* Destroy the old frame if we had to reframe the container. This needs to be done
* after rendering in order to prevent the background from flickering in its place. */
if (old_frame != XCB_NONE) {
xcb_destroy_window(conn, old_frame);
}
/* Windows might get managed with the urgency hint already set (Pidgin is /* Windows might get managed with the urgency hint already set (Pidgin is
* known to do that), so check for that and handle the hint accordingly. * known to do that), so check for that and handle the hint accordingly.
* This code needs to be in this part of manage_window() because the window * This code needs to be in this part of manage_window() because the window

25
src/x.c
View File

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