From ff37cf97562008fc38dce4f09b230dabee3f701f Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Thu, 21 Feb 2019 02:12:07 +0000 Subject: [PATCH] Don't start fading when screen is unredirected If a window is destroyed and starts to fade out when screen is unredirected, when the screen become redirected again, we will generate errors when trying to render that window. Also make sure the assumption that all window are either MAPPED or UNMAPPED when screen is unredirected holds. Signed-off-by: Yuxuan Shui --- src/compton.c | 6 +----- src/win.c | 32 ++++++++++++++++++++++++++------ src/win.h | 4 ++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/compton.c b/src/compton.c index 95bd8aa..aa022ff 100644 --- a/src/compton.c +++ b/src/compton.c @@ -2018,11 +2018,7 @@ redir_stop(session_t *ps) { for (win *w = ps->list, *next; w; w = next) { next = w->next; // Wrapping up fading in progress - if (w->opacity != w->opacity_tgt) { - assert(w->state != WSTATE_UNMAPPED && w->state != WSTATE_MAPPED); - w->opacity = w->opacity_tgt; - win_check_fade_finished(ps, &w); - } + win_skip_fading(ps, &w); // `w` might be freed by win_check_fade_finished if (!w) { diff --git a/src/win.c b/src/win.c index d75864b..c5433d4 100644 --- a/src/win.c +++ b/src/win.c @@ -1367,12 +1367,11 @@ finish_destroy_win(session_t *ps, win **_w) { win *w = *_w; win **prev = NULL; - // Window can't go from UNMAPPED to DESTROYING, and - // UNMAPPED is the only state where the window resource - // is freed. That means the window resources have not - // been freed at this point. call finish_unmap_win to - // free them. - finish_unmap_win(ps, _w); + if (w->state != WSTATE_UNMAPPED) { + // Only UNMAPPED state has window resources freed, otherwise + // we need to call finish_unmap_win to free them. + finish_unmap_win(ps, _w); + } log_trace("Trying to destroy (%#010x)", w->id); for (prev = &ps->list; *prev; prev = &(*prev)->next) { @@ -1477,6 +1476,10 @@ unmap_win(session_t *ps, win **_w, bool destroy) { } } #endif + + if (!ps->redirected) { + win_skip_fading(ps, _w); + } } /** @@ -1501,6 +1504,18 @@ win_check_fade_finished(session_t *ps, win **_w) { } } +/// Skip the current in progress fading of window, +/// transition the window straight to its end state +void win_skip_fading(session_t *ps, win **_w) { + win *w = *_w; + if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) { + assert(w->opacity_tgt == w->opacity); + return; + } + w->opacity = w->opacity_tgt; + win_check_fade_finished(ps, _w); +} + /** * Get the Xinerama screen a window is on. * @@ -1637,6 +1652,11 @@ map_win(session_t *ps, xcb_window_t id) { cdbus_ev_win_mapped(ps, w); } #endif + + if (!ps->redirected) { + win_skip_fading(ps, &w); + assert(w); + } } diff --git a/src/win.h b/src/win.h index 8000ae7..ee3451f 100644 --- a/src/win.h +++ b/src/win.h @@ -368,6 +368,10 @@ win_check_fade_finished(session_t *ps, win **_w); // Stop receiving events (except ConfigureNotify, XXX why?) from a window void win_ev_stop(session_t *ps, win *w); +/// Skip the current in progress fading of window, +/// transition the window straight to its end state +void win_skip_fading(session_t *ps, win **_w); + /** * Get the leader of a window. *