From c8c55ff83192363e4a3631d086ee416dfdc2345a Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Fri, 19 Apr 2019 02:15:31 +0100 Subject: [PATCH] win: handle destruction of unmanaged window Previous destructions of unmanaged window are silently ignored, causing windows with duplicated IDs. Signed-off-by: Yuxuan Shui --- src/event.c | 16 ++++++++++++---- src/win.c | 10 ++++++++++ src/win.h | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/event.c b/src/event.c index 1804c247..c0c8a049 100644 --- a/src/event.c +++ b/src/event.c @@ -184,9 +184,13 @@ static inline void ev_configure_notify(session_t *ps, xcb_configure_notify_event } static inline void ev_destroy_notify(session_t *ps, xcb_destroy_notify_event_t *ev) { - auto w = find_managed_win(ps, ev->window); + auto w = find_win(ps, ev->window); if (w) { - unmap_win(ps, &w, true); + if (w->managed) { + unmap_win(ps, (struct managed_win **)&w, true); + } else { + destroy_unmanaged_win(ps, &w); + } } } @@ -217,8 +221,12 @@ static inline void ev_reparent_notify(session_t *ps, xcb_reparent_notify_event_t } else { // otherwise, find and destroy the window first auto w = find_win(ps, ev->window); - if (w && w->managed) { - unmap_win(ps, (struct managed_win **)&w, true); + if (w) { + if (w->managed) { + unmap_win(ps, (struct managed_win **)&w, true); + } else { + destroy_unmanaged_win(ps, &w); + } } // Reset event mask in case something wrong happens diff --git a/src/win.c b/src/win.c index 417e7497..6a7f541d 100644 --- a/src/win.c +++ b/src/win.c @@ -1621,6 +1621,16 @@ static void finish_map_win(session_t *ps, struct managed_win **_w) { w->state = WSTATE_MAPPED; } +void destroy_unmanaged_win(session_t *ps, struct win **_w) { + auto w = *_w; + assert(!w->managed); + assert(!w->destroyed); + list_remove(&w->stack_neighbour); + HASH_DEL(ps->windows, w); + free(w); + *_w = NULL; +} + void unmap_win(session_t *ps, struct managed_win **_w, bool destroy) { auto w = *_w; diff --git a/src/win.h b/src/win.h index 43fdde31..e6876b29 100644 --- a/src/win.h +++ b/src/win.h @@ -421,6 +421,8 @@ struct win *add_win_top(session_t *ps, xcb_window_t id); void fill_win(session_t *ps, struct win *win); /// Unmap or destroy a window void unmap_win(session_t *ps, struct managed_win **, bool destroy); +/// Destroy an unmanaged window +void destroy_unmanaged_win(session_t *ps, struct win **w); void map_win(session_t *ps, struct managed_win *w); void map_win_by_id(session_t *ps, xcb_window_t id);