win: handle destruction of unmanaged window

Previous destructions of unmanaged window are silently ignored, causing
windows with duplicated IDs.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-04-19 02:15:31 +01:00
parent 883d8c9142
commit 927cdd8652
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
3 changed files with 24 additions and 4 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);