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 <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2020-12-04 03:06:30 +00:00
parent e66a452a27
commit f5ee0e12e1
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
2 changed files with 8 additions and 2 deletions

View File

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

View File

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