diff --git a/src/event.c b/src/event.c index f21e346..69b326b 100644 --- a/src/event.c +++ b/src/event.c @@ -180,8 +180,9 @@ static inline void ev_focus_out(session_t *ps, xcb_focus_out_event_t *ev) { } static inline void ev_create_notify(session_t *ps, xcb_create_notify_event_t *ev) { - assert(ev->parent == ps->root); - add_win_top(ps, ev->window); + if (ev->parent == ps->root) { + add_win_top(ps, ev->window); + } } /// Handle configure event of a regular window @@ -263,8 +264,21 @@ 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_win(ps, ev->window); - if (w) { + auto mw = find_toplevel(ps, ev->window); + if (mw && mw->client_win == mw->base.id) { + // We only want _real_ frame window + assert(&mw->base == w); + mw = NULL; + } + assert(w == NULL || mw == NULL); + + if (w != NULL) { auto _ attr_unused = destroy_win_start(ps, w); + } else if (mw != NULL) { + win_recheck_client(ps, mw); + } else { + log_debug("Received a destroy notify from an unknown window, %#010x", + ev->window); } } diff --git a/src/picom.c b/src/picom.c index bbade20..fcc2a41 100644 --- a/src/picom.c +++ b/src/picom.c @@ -303,9 +303,9 @@ uint32_t determine_evmask(session_t *ps, xcb_window_t wid, win_evmode_t mode) { struct managed_win *w = NULL; // Check if it's a mapped frame window - if (WIN_EVMODE_FRAME == mode || + if (mode == WIN_EVMODE_FRAME || ((w = find_managed_win(ps, wid)) && w->a.map_state == XCB_MAP_STATE_VIEWABLE)) { - evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE; + evmask |= XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; if (!ps->o.use_ewmh_active_win) { evmask |= XCB_EVENT_MASK_FOCUS_CHANGE; } diff --git a/src/win.c b/src/win.c index 10f4424..1a10e06 100644 --- a/src/win.c +++ b/src/win.c @@ -53,8 +53,6 @@ static const int WIN_GET_LEADER_MAX_RECURSION = 20; static const int ROUNDED_PIXELS = 1; static const double ROUNDED_PERCENT = 0.05; -static void win_recheck_client(session_t *ps, struct managed_win *w); - /// Generate a "return by value" function, from a function that returns the /// region via a region_t pointer argument. /// Function signature has to be (win *, region_t *) @@ -1031,6 +1029,8 @@ void win_mark_client(session_t *ps, struct managed_win *w, xcb_window_t client) */ void win_unmark_client(session_t *ps, struct managed_win *w) { xcb_window_t client = w->client_win; + log_debug("Detaching client window %#010x from frame %#010x (%s)", client, + w->base.id, w->name); w->client_win = XCB_NONE; @@ -1074,7 +1074,7 @@ static xcb_window_t find_client_win(session_t *ps, xcb_window_t w) { * @param ps current session * @param w struct _win of the parent window */ -static void win_recheck_client(session_t *ps, struct managed_win *w) { +void win_recheck_client(session_t *ps, struct managed_win *w) { // Initialize wmwin to false w->wmwin = false; @@ -1084,14 +1084,14 @@ static void win_recheck_client(session_t *ps, struct managed_win *w) { // sets override-redirect flags on all frame windows. xcb_window_t cw = find_client_win(ps, w->base.id); if (cw) { - log_trace("(%#010x): client %#010x", w->base.id, cw); + log_debug("(%#010x): client %#010x", w->base.id, cw); } // Set a window's client window to itself if we couldn't find a // client window if (!cw) { cw = w->base.id; w->wmwin = !w->a.override_redirect; - log_trace("(%#010x): client self (%s)", w->base.id, + log_debug("(%#010x): client self (%s)", w->base.id, (w->wmwin ? "wmwin" : "override-redirected")); } diff --git a/src/win.h b/src/win.h index d6778b6..4f1ee41 100644 --- a/src/win.h +++ b/src/win.h @@ -298,6 +298,7 @@ void win_on_win_size_change(session_t *ps, struct managed_win *w); void win_update_wintype(session_t *ps, struct managed_win *w); void win_mark_client(session_t *ps, struct managed_win *w, xcb_window_t client); void win_unmark_client(session_t *ps, struct managed_win *w); +void win_recheck_client(session_t *ps, struct managed_win *w); bool win_get_class(session_t *ps, struct managed_win *w); /**