mirror of https://github.com/yshui/picom.git
win: track number of in progress animations with transition callbacks
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
c1d2a8fa40
commit
4b3688ddec
10
src/picom.c
10
src/picom.c
|
@ -502,9 +502,8 @@ static bool run_fade(session_t *ps, struct managed_win **_w, unsigned int steps)
|
|||
steps);
|
||||
if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) {
|
||||
// We are not fading
|
||||
assert(!animatable_is_animating(&w->opacity));
|
||||
assert(!animatable_is_animating(&w->blur_opacity));
|
||||
log_trace("|- not fading");
|
||||
assert(w->number_of_animations == 0);
|
||||
log_trace("|- not animated");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -513,8 +512,7 @@ static bool run_fade(session_t *ps, struct managed_win **_w, unsigned int steps)
|
|||
animatable_early_stop(&w->opacity);
|
||||
animatable_early_stop(&w->blur_opacity);
|
||||
}
|
||||
if (!animatable_is_animating(&w->opacity) &&
|
||||
!animatable_is_animating(&w->blur_opacity)) {
|
||||
if (w->number_of_animations == 0) {
|
||||
// We have reached target opacity.
|
||||
// We don't call win_check_fade_finished here because that could destroy
|
||||
// the window, but we still need the damage info from this window
|
||||
|
@ -951,7 +949,7 @@ static bool paint_preprocess(session_t *ps, bool *fade_running, bool *animation,
|
|||
// If was_painted == false, and to_paint is also false, we don't care
|
||||
// If was_painted == false, but to_paint is true, damage will be added in
|
||||
// the loop below
|
||||
if (was_painted && animatable_is_animating(&w->opacity)) {
|
||||
if (was_painted && w->number_of_animations != 0) {
|
||||
add_damage_from_win(ps, w);
|
||||
}
|
||||
|
||||
|
|
25
src/win.c
25
src/win.c
|
@ -892,6 +892,11 @@ static double win_calc_opacity_target(session_t *ps, const struct managed_win *w
|
|||
return opacity;
|
||||
}
|
||||
|
||||
static void win_transition_callback(enum transition_event event attr_unused, void *data) {
|
||||
auto w = (struct managed_win *)data;
|
||||
w->number_of_animations--;
|
||||
}
|
||||
|
||||
/// Call `animatable_set_target` on the opacity of a window, with appropriate
|
||||
/// target opacity and duration.
|
||||
///
|
||||
|
@ -903,8 +908,9 @@ static inline unsigned int win_start_fade(session_t *ps, struct managed_win *w)
|
|||
target_opacity > current_opacity ? ps->o.fade_in_step : ps->o.fade_out_step;
|
||||
unsigned int duration =
|
||||
(unsigned int)(fabs(target_opacity - current_opacity) / step_size);
|
||||
w->number_of_animations++;
|
||||
animatable_set_target(&w->opacity, target_opacity, duration,
|
||||
NULL, NULL);
|
||||
win_transition_callback, w);
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
@ -2413,7 +2419,8 @@ void unmap_win_start(session_t *ps, struct managed_win *w) {
|
|||
w->a.map_state = XCB_MAP_STATE_UNMAPPED;
|
||||
w->state = WSTATE_UNMAPPING;
|
||||
auto duration = win_start_fade(ps, w);
|
||||
animatable_set_target(&w->blur_opacity, 0, duration, NULL, NULL);
|
||||
w->number_of_animations++;
|
||||
animatable_set_target(&w->blur_opacity, 0, duration, win_transition_callback, w);
|
||||
|
||||
#ifdef CONFIG_DBUS
|
||||
// Send D-Bus signal
|
||||
|
@ -2439,10 +2446,10 @@ void unmap_win_start(session_t *ps, struct managed_win *w) {
|
|||
bool win_maybe_finalize_fading(session_t *ps, struct managed_win *w) {
|
||||
if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) {
|
||||
// No fading in progress
|
||||
assert(!animatable_is_animating(&w->opacity));
|
||||
assert(w->number_of_animations == 0);
|
||||
return false;
|
||||
}
|
||||
if (!animatable_is_animating(&w->opacity)) {
|
||||
if (w->number_of_animations == 0) {
|
||||
switch (w->state) {
|
||||
case WSTATE_UNMAPPING: unmap_win_finish(ps, w); return false;
|
||||
case WSTATE_DESTROYING: destroy_win_finish(ps, &w->base); return true;
|
||||
|
@ -2461,7 +2468,7 @@ bool win_maybe_finalize_fading(session_t *ps, struct managed_win *w) {
|
|||
/// @return whether the window is destroyed and freed
|
||||
bool win_skip_fading(session_t *ps, struct managed_win *w) {
|
||||
if (w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED) {
|
||||
assert(!animatable_is_animating(&w->opacity));
|
||||
assert(w->number_of_animations == 0);
|
||||
return false;
|
||||
}
|
||||
log_debug("Skipping fading process of window %#010x (%s)", w->base.id, w->name);
|
||||
|
@ -2528,7 +2535,8 @@ void map_win_start(session_t *ps, struct managed_win *w) {
|
|||
// iff `state` is MAPPED
|
||||
w->state = WSTATE_MAPPING;
|
||||
auto duration = win_start_fade(ps, w);
|
||||
animatable_set_target(&w->blur_opacity, 1, duration, NULL, NULL);
|
||||
w->number_of_animations++;
|
||||
animatable_set_target(&w->blur_opacity, 1, duration, win_transition_callback, w);
|
||||
|
||||
log_debug("Window %#010x has opacity %f, opacity target is %f", w->base.id,
|
||||
animatable_get(&w->opacity), w->opacity.target);
|
||||
|
@ -2561,7 +2569,7 @@ void map_win_start(session_t *ps, struct managed_win *w) {
|
|||
void win_update_opacity_target(session_t *ps, struct managed_win *w) {
|
||||
auto duration = win_start_fade(ps, w);
|
||||
|
||||
if (!animatable_is_animating(&w->opacity)) {
|
||||
if (w->number_of_animations == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2573,8 +2581,9 @@ void win_update_opacity_target(session_t *ps, struct managed_win *w) {
|
|||
} else if (w->state == WSTATE_MAPPING) {
|
||||
// Opacity target changed while fading in, keep the blur_opacity
|
||||
// in lock step with the opacity
|
||||
w->number_of_animations++;
|
||||
animatable_set_target(&w->blur_opacity, w->blur_opacity.target, duration,
|
||||
NULL, NULL);
|
||||
win_transition_callback, w);
|
||||
log_debug("Opacity changed while fading in");
|
||||
} else if (w->state == WSTATE_FADING) {
|
||||
// Opacity target changed while FADING.
|
||||
|
|
Loading…
Reference in New Issue