From 06f02f60040ee7596aefd202fc419a60c809bffe Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Fri, 7 Oct 2016 00:46:57 +0200 Subject: [PATCH] Delay client frame window destruction (#1148) Daniel sees a short flicker of his wallpaper when he closes a client. This happens because the window is destroyed immediately, but other clients are re-arranged only shortly later. In the mean time, the X server updates the display and repaints the root window (= wallpaper becomes visible). Work around this by delaying the destruction of frame windows to the end of the current main loop iteration. This means that we first update the position of all other windows and later destroy the window that was actually closed. Signed-off-by: Uli Schlachter --- event.h | 2 ++ globalconf.h | 3 +++ objects/client.c | 26 +++++++++++++++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/event.h b/event.h index 601b70f1..52cce408 100644 --- a/event.h +++ b/event.h @@ -37,6 +37,7 @@ void drawin_refresh(void); /* objects/client.c */ void client_refresh(void); void client_focus_refresh(void); +void client_destroy_later(void); /* objects/screen.c */ void screen_refresh(void); @@ -50,6 +51,7 @@ awesome_refresh(void) client_refresh(); banning_refresh(); stack_refresh(); + client_destroy_later(); return xcb_flush(globalconf.connection); } diff --git a/globalconf.h b/globalconf.h index 0d4057f7..ae729f2a 100644 --- a/globalconf.h +++ b/globalconf.h @@ -68,6 +68,7 @@ ARRAY_TYPE(client_t *, client) ARRAY_TYPE(drawin_t *, drawin) ARRAY_TYPE(xproperty_t, xproperty) DO_ARRAY(sequence_pair_t, sequence_pair, DO_NOTHING) +DO_ARRAY(xcb_window_t, window, DO_NOTHING) /** Main configuration structure */ typedef struct @@ -189,6 +190,8 @@ typedef struct /** List of enter/leave events to ignore */ sequence_pair_array_t ignore_enter_leave_events; xcb_void_cookie_t pending_enter_leave_begin; + /** List of windows to be destroyed later */ + window_array_t destroy_later_windows; } awesome_t; extern awesome_t globalconf; diff --git a/objects/client.c b/objects/client.c index 0b81bdc1..654be448 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1219,6 +1219,25 @@ client_refresh(void) client_focus_refresh(); } +void +client_destroy_later(void) +{ + bool ignored_enterleave = false; + foreach(window, globalconf.destroy_later_windows) + { + if (!ignored_enterleave) { + client_ignore_enterleave_events(); + ignored_enterleave = true; + } + xcb_destroy_window(globalconf.connection, *window); + } + if (ignored_enterleave) + client_restore_enterleave_events(); + + /* Everything's done, clear the list */ + globalconf.destroy_later_windows.len = 0; +} + static void border_width_callback(client_t *c, uint16_t old_width, uint16_t new_width) { @@ -2088,12 +2107,9 @@ client_unmanage(client_t *c, bool window_valid) c->geometry.x, c->geometry.y); } - /* Ignore all spurious enter/leave notify events */ - client_ignore_enterleave_events(); if (c->nofocus_window != XCB_NONE) - xcb_destroy_window(globalconf.connection, c->nofocus_window); - xcb_destroy_window(globalconf.connection, c->frame_window); - client_restore_enterleave_events(); + window_array_append(&globalconf.destroy_later_windows, c->nofocus_window); + window_array_append(&globalconf.destroy_later_windows, c->frame_window); if(window_valid) {