From e9ab9709896688d5bf54555f70aa6341a8c65c0f Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Sun, 5 Apr 2020 22:41:45 +0100 Subject: [PATCH] event: destroy: recheck client instead of unmark client We detach the client window from its frame when it's destroyed, so later a new window can be attached to that frame. But turns out that's not enough. When i3 restarts, it attaches a placeholder window to the frame, then the real window, and only after that, it will destroy the placeholder. The real window will fail to attach as the frame already has a client. When the placeholder is destroyed, we have to call recheck client to pick up the real window that failed to attach previously. Related: #299 Signed-off-by: Yuxuan Shui --- src/event.c | 2 +- src/win.c | 8 +++++--- src/win.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/event.c b/src/event.c index 46340d60..7cd50a2e 100644 --- a/src/event.c +++ b/src/event.c @@ -274,7 +274,7 @@ static inline void ev_destroy_notify(session_t *ps, xcb_destroy_notify_event_t * if (w != NULL) { auto _ attr_unused = destroy_win_start(ps, w); } else if (mw != NULL) { - win_unmark_client(ps, mw); + win_recheck_client(ps, mw); } else { log_debug("Received a destroy notify from an unknown window, %#010x", ev->window); diff --git a/src/win.c b/src/win.c index 2da27ebe..a9aa8ab3 100644 --- a/src/win.c +++ b/src/win.c @@ -1037,6 +1037,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; @@ -1052,7 +1054,7 @@ void win_unmark_client(session_t *ps, struct managed_win *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; @@ -1062,14 +1064,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 d3d90716..738529cd 100644 --- a/src/win.h +++ b/src/win.h @@ -299,6 +299,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); /**