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. *