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:
parent
883d8c9142
commit
927cdd8652
16
src/event.c
16
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) {
|
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) {
|
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 {
|
} else {
|
||||||
// otherwise, find and destroy the window first
|
// otherwise, find and destroy the window first
|
||||||
auto w = find_win(ps, ev->window);
|
auto w = find_win(ps, ev->window);
|
||||||
if (w && w->managed) {
|
if (w) {
|
||||||
unmap_win(ps, (struct managed_win **)&w, true);
|
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
|
// Reset event mask in case something wrong happens
|
||||||
|
10
src/win.c
10
src/win.c
@ -1621,6 +1621,16 @@ static void finish_map_win(session_t *ps, struct managed_win **_w) {
|
|||||||
w->state = WSTATE_MAPPED;
|
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) {
|
void unmap_win(session_t *ps, struct managed_win **_w, bool destroy) {
|
||||||
auto w = *_w;
|
auto w = *_w;
|
||||||
|
|
||||||
|
@ -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);
|
void fill_win(session_t *ps, struct win *win);
|
||||||
/// Unmap or destroy a window
|
/// Unmap or destroy a window
|
||||||
void unmap_win(session_t *ps, struct managed_win **, bool destroy);
|
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(session_t *ps, struct managed_win *w);
|
||||||
void map_win_by_id(session_t *ps, xcb_window_t id);
|
void map_win_by_id(session_t *ps, xcb_window_t id);
|
||||||
|
Loading…
Reference in New Issue
Block a user