Use a GLib idle source for lazily destroying windows

Ever since the switch from libev to GLib, we have a hack in place. We
use g_main_context_set_poll_func() to replace g_poll() (which is just a
wrapper around poll()) with our own function that does lots of house
keeping. This commit is part of getting rid of this hack: It moves one
step that is done in this poll-replacement into a GLib idle source.

We lazily destroy frame windows, because as soon as the window is
destroyed, clients that now become visible get notified and repaint
themselves. However, it might be the case that we also need to update
the stacking order or unban clients, so that some other client is
visible in the end. To avoid this short flicker of "something else", we
lazily destroy some windows. This commit moves this into a GLib idle
source.

I did not add a variable that tracks whether we already added an idle
source for destroying windows. Instead, each time something is added to
the list, a new idle source is created. When it is dispatched, the first
source will handle the full list of windows to destroy. Later sources
will just do nothing. In my opinion, this is fine, because it is
unlikely that multiple windows end up on the to-be-destroyed list at the
same time.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2019-07-25 18:04:03 +02:00
parent ebd95098a5
commit ff11c40d06
2 changed files with 5 additions and 4 deletions

View file

@ -34,14 +34,12 @@ void luaA_emit_refresh(void);
/* objects/client.c */
void client_refresh(void);
void client_focus_refresh(void);
void client_destroy_later(void);
static inline int
awesome_refresh(void)
{
luaA_emit_refresh();
client_refresh();
client_destroy_later();
return xcb_flush(globalconf.connection);
}

View file

@ -1450,8 +1450,8 @@ client_refresh(void)
client_geometry_refresh();
}
void
client_destroy_later(void)
static gboolean
client_destroy_later_callback(gpointer unused)
{
bool ignored_enterleave = false;
foreach(window, globalconf.destroy_later_windows)
@ -1467,6 +1467,8 @@ client_destroy_later(void)
/* Everything's done, clear the list */
globalconf.destroy_later_windows.len = 0;
return G_SOURCE_REMOVE;
}
static void
@ -2395,6 +2397,7 @@ client_unmanage(client_t *c, bool window_valid)
if (c->nofocus_window != XCB_NONE)
window_array_append(&globalconf.destroy_later_windows, c->nofocus_window);
window_array_append(&globalconf.destroy_later_windows, c->frame_window);
g_idle_add_full(G_PRIORITY_LOW, client_destroy_later_callback, NULL, NULL);
window_cancel_border_refresh((window_t *) c);
if(window_valid)