From f5ee0e12e1946776b2ca64b9db83879cd324feb7 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Fri, 4 Dec 2020 03:06:30 +0000 Subject: [PATCH] win: fix window not being rendered when it's mapped and damged while fading out Consider these 2 cases: * A window is mapped while fading out * A window is mapped and damaged while fading out From the perspective of map_win_start, these 2 cases look the same. The window will has ever_damage = true in both cases. However, map_win_start has to distinguish between these 2 cases, because at the end of map_win_start, window in the first case cannot have ever_damage = true, while window in the second case should have ever_damage = true. Currently, map_win_start always clears ever_damage in both cases (indirectly through win_skip_fading), which causes windows in the second case to not be rendered when they should be. This commit move clearing of ever_damage from unmap_win_finish to unmap_win_start, so when map_win_start sees ever_damage = true, it's always to second case. And to make sure windows which are fading out are still rendered, we relax the ever_damage check in paint_preprocess to also accept windows that are fading out. (see code comment for explanation why this is fine) Signed-off-by: Yuxuan Shui --- src/picom.c | 7 ++++++- src/win.c | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/picom.c b/src/picom.c index e781076b..d2a7820c 100644 --- a/src/picom.c +++ b/src/picom.c @@ -713,7 +713,12 @@ static struct managed_win *paint_preprocess(session_t *ps, bool *fade_running) { unlikely(w->base.id == ps->debug_window || w->client_win == ps->debug_window)) { to_paint = false; - } else if (!w->ever_damaged) { + } else if (!w->ever_damaged && w->state != WSTATE_UNMAPPING && + w->state != WSTATE_DESTROYING) { + // Unmapping clears w->ever_damaged, but the fact that the window + // is fading out means it must have been damaged when it was still + // mapped (because unmap_win_start will skip fading if it wasn't), + // so we still need to paint it. log_trace("Window %#010x (%s) will not be painted because it has " "not received any damages", w->base.id, w->name); diff --git a/src/win.c b/src/win.c index bf8a502f..2d541735 100644 --- a/src/win.c +++ b/src/win.c @@ -1978,7 +1978,6 @@ void win_ev_stop(session_t *ps, const struct win *w) { /// Finish the unmapping of a window (e.g. after fading has finished). /// Doesn't free `w` static void unmap_win_finish(session_t *ps, struct managed_win *w) { - w->ever_damaged = false; w->reg_ignore_valid = false; w->state = WSTATE_UNMAPPED; @@ -2234,6 +2233,8 @@ void unmap_win_start(session_t *ps, struct managed_win *w) { assert(false); } + w->ever_damaged = false; + if (unlikely(w->state == WSTATE_UNMAPPING || w->state == WSTATE_UNMAPPED)) { if (win_check_flags_all(w, WIN_FLAGS_MAPPED)) { // Clear the pending map as this window is now unmapped