From: Michael Stapelberg Date: Sun, 15 Dec 2013 14:00:26 +0000 (+0100) Subject: kill placeholder windows when the actual window appears X-Git-Tag: 4.8~185 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=42e359ec60cd0a378e9526e7c40bffde0a6d5799;p=i3%2Fi3 kill placeholder windows when the actual window appears --- diff --git a/include/restore_layout.h b/include/restore_layout.h index a039f92f..75617410 100644 --- a/include/restore_layout.h +++ b/include/restore_layout.h @@ -29,4 +29,13 @@ void restore_connect(void); */ void restore_open_placeholder_windows(Con *con); +/** + * Kill the placeholder window, if placeholder refers to a placeholder window. + * This function is called when manage.c puts a window into an existing + * container. In order not to leak resources, we need to destroy the window and + * all associated X11 objects (pixmap/gc). + * + */ +bool restore_kill_placeholder(xcb_window_t placeholder); + #endif diff --git a/src/manage.c b/src/manage.c index 0eaf35e7..d7a28eb1 100644 --- a/src/manage.c +++ b/src/manage.c @@ -327,6 +327,11 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki } DLOG("new container = %p\n", nc); + if (nc->window != NULL) { + if (!restore_kill_placeholder(nc->window->id)) { + DLOG("Uh?! Container without a placeholder, but with a window, has swallowed this to-be-managed window?!\n"); + } + } nc->window = cwindow; x_reinit(nc); diff --git a/src/restore_layout.c b/src/restore_layout.c index f868cf3e..319b5505 100644 --- a/src/restore_layout.c +++ b/src/restore_layout.c @@ -226,6 +226,32 @@ void restore_open_placeholder_windows(Con *parent) { xcb_flush(restore_conn); } +/* + * Kill the placeholder window, if placeholder refers to a placeholder window. + * This function is called when manage.c puts a window into an existing + * container. In order not to leak resources, we need to destroy the window and + * all associated X11 objects (pixmap/gc). + * + */ +bool restore_kill_placeholder(xcb_window_t placeholder) { + placeholder_state *state; + TAILQ_FOREACH(state, &state_head, state) { + if (state->window != placeholder) + continue; + + xcb_destroy_window(restore_conn, state->window); + xcb_free_pixmap(restore_conn, state->pixmap); + xcb_free_gc(restore_conn, state->gc); + TAILQ_REMOVE(&state_head, state, state); + free(state); + DLOG("placeholder window 0x%08x destroyed.\n", placeholder); + return true; + } + + DLOG("0x%08x is not a placeholder window, ignoring.\n", placeholder); + return false; +} + static void expose_event(xcb_expose_event_t *event) { placeholder_state *state; TAILQ_FOREACH(state, &state_head, state) {