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 <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2016-10-07 00:46:57 +02:00 committed by Daniel Hahler
parent c79e49b985
commit 06f02f6004
3 changed files with 26 additions and 5 deletions

View File

@ -37,6 +37,7 @@ void drawin_refresh(void);
/* objects/client.c */ /* objects/client.c */
void client_refresh(void); void client_refresh(void);
void client_focus_refresh(void); void client_focus_refresh(void);
void client_destroy_later(void);
/* objects/screen.c */ /* objects/screen.c */
void screen_refresh(void); void screen_refresh(void);
@ -50,6 +51,7 @@ awesome_refresh(void)
client_refresh(); client_refresh();
banning_refresh(); banning_refresh();
stack_refresh(); stack_refresh();
client_destroy_later();
return xcb_flush(globalconf.connection); return xcb_flush(globalconf.connection);
} }

View File

@ -68,6 +68,7 @@ ARRAY_TYPE(client_t *, client)
ARRAY_TYPE(drawin_t *, drawin) ARRAY_TYPE(drawin_t *, drawin)
ARRAY_TYPE(xproperty_t, xproperty) ARRAY_TYPE(xproperty_t, xproperty)
DO_ARRAY(sequence_pair_t, sequence_pair, DO_NOTHING) DO_ARRAY(sequence_pair_t, sequence_pair, DO_NOTHING)
DO_ARRAY(xcb_window_t, window, DO_NOTHING)
/** Main configuration structure */ /** Main configuration structure */
typedef struct typedef struct
@ -189,6 +190,8 @@ typedef struct
/** List of enter/leave events to ignore */ /** List of enter/leave events to ignore */
sequence_pair_array_t ignore_enter_leave_events; sequence_pair_array_t ignore_enter_leave_events;
xcb_void_cookie_t pending_enter_leave_begin; xcb_void_cookie_t pending_enter_leave_begin;
/** List of windows to be destroyed later */
window_array_t destroy_later_windows;
} awesome_t; } awesome_t;
extern awesome_t globalconf; extern awesome_t globalconf;

View File

@ -1219,6 +1219,25 @@ client_refresh(void)
client_focus_refresh(); 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 static void
border_width_callback(client_t *c, uint16_t old_width, uint16_t new_width) 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); c->geometry.x, c->geometry.y);
} }
/* Ignore all spurious enter/leave notify events */
client_ignore_enterleave_events();
if (c->nofocus_window != XCB_NONE) if (c->nofocus_window != XCB_NONE)
xcb_destroy_window(globalconf.connection, c->nofocus_window); window_array_append(&globalconf.destroy_later_windows, c->nofocus_window);
xcb_destroy_window(globalconf.connection, c->frame_window); window_array_append(&globalconf.destroy_later_windows, c->frame_window);
client_restore_enterleave_events();
if(window_valid) if(window_valid)
{ {