mirror of https://github.com/yshui/picom.git
transition: add transition event callback
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
31d50fadd1
commit
c1d2a8fa40
|
@ -51,6 +51,11 @@ void animatable_step(struct animatable *a, unsigned int steps) {
|
|||
if (a->step_state) {
|
||||
a->step_state->current = a->target;
|
||||
}
|
||||
if (a->callback) {
|
||||
a->callback(TRANSITION_COMPLETED, a->callback_data);
|
||||
a->callback = NULL;
|
||||
a->callback_data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,6 +81,11 @@ bool animatable_cancel(struct animatable *a) {
|
|||
if (a->step_state) {
|
||||
a->step_state->current = a->start;
|
||||
}
|
||||
if (a->callback) {
|
||||
a->callback(TRANSITION_CANCELED, a->callback_data);
|
||||
a->callback = NULL;
|
||||
a->callback_data = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -93,16 +103,25 @@ bool animatable_early_stop(struct animatable *a) {
|
|||
if (a->step_state) {
|
||||
a->step_state->current = a->target;
|
||||
}
|
||||
if (a->callback) {
|
||||
a->callback(TRANSITION_STOPPED_EARLY, a->callback_data);
|
||||
a->callback = NULL;
|
||||
a->callback_data = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Change the target value of an `animatable`.
|
||||
/// If the `animatable` is already animating, the animation will be canceled first.
|
||||
void animatable_set_target(struct animatable *a, double target, unsigned int duration) {
|
||||
void animatable_set_target(struct animatable *a, double target, unsigned int duration,
|
||||
transition_callback_fn cb, void *data) {
|
||||
animatable_cancel(a);
|
||||
if (!duration) {
|
||||
a->start = target;
|
||||
a->target = target;
|
||||
if (cb) {
|
||||
cb(TRANSITION_COMPLETED, data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -112,6 +131,8 @@ void animatable_set_target(struct animatable *a, double target, unsigned int dur
|
|||
if (a->step_state) {
|
||||
a->step(a, 0);
|
||||
}
|
||||
a->callback = cb;
|
||||
a->callback_data = data;
|
||||
}
|
||||
|
||||
/// Create a new animatable.
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
struct animatable;
|
||||
enum transition_event;
|
||||
/// The interpolator function for an animatable. This function should calculate the
|
||||
/// current value of the `animatable` based on its `start`, `target`, `duration` and
|
||||
/// `progress`.
|
||||
|
@ -18,6 +19,22 @@ typedef double (*interpolator_fn)(const struct animatable *);
|
|||
/// is 0 or `step_state` is NULL, in which case `steps` is 0.
|
||||
typedef void (*step_fn)(struct animatable *, unsigned int steps);
|
||||
|
||||
/// Callback when the transition state changes. Callback might be called by:
|
||||
/// - `animatable_set_target` generates TRANSITION_COMPLETED when the specified duration
|
||||
/// is 0. also generates TRANSITION_CANCELLED if the animatable was already animating.
|
||||
/// - `animatable_cancel` generates TRANSITION_CANCELED
|
||||
/// - `animatable_early_stop` generates TRANSITION_STOPPED_EARLY
|
||||
/// - `animatable_step` generates TRANSITION_COMPLETED when the animation is completed.
|
||||
/// Callback is guaranteed to be called exactly once for each `animatable_set_target`
|
||||
/// call, unless an animatable is freed before the transition is completed.
|
||||
typedef void (*transition_callback_fn)(enum transition_event event, void *data);
|
||||
|
||||
enum transition_event {
|
||||
TRANSITION_COMPLETED,
|
||||
TRANSITION_CANCELED,
|
||||
TRANSITION_STOPPED_EARLY,
|
||||
};
|
||||
|
||||
/// The base type for step_state.
|
||||
struct step_state_base {
|
||||
/// The current value of the `animatable`.
|
||||
|
@ -40,6 +57,9 @@ struct animatable {
|
|||
/// If the `animatable` is not animated, this is 0.
|
||||
unsigned int progress;
|
||||
|
||||
transition_callback_fn callback;
|
||||
void *callback_data;
|
||||
|
||||
/// Step function state.
|
||||
struct step_state_base *step_state;
|
||||
/// The function for calculating the current value. If
|
||||
|
@ -74,7 +94,8 @@ bool animatable_cancel(struct animatable *a);
|
|||
bool animatable_early_stop(struct animatable *a);
|
||||
/// Change the target value of an `animatable`.
|
||||
/// If the `animatable` is already animating, the animation will be canceled first.
|
||||
void animatable_set_target(struct animatable *a, double target, unsigned int duration);
|
||||
void animatable_set_target(struct animatable *a, double target, unsigned int duration,
|
||||
transition_callback_fn cb, void *data);
|
||||
/// Create a new animatable.
|
||||
struct animatable animatable_new(double value, interpolator_fn interpolator, step_fn step);
|
||||
|
||||
|
|
10
src/win.c
10
src/win.c
|
@ -903,7 +903,8 @@ 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);
|
||||
animatable_set_target(&w->opacity, target_opacity, duration);
|
||||
animatable_set_target(&w->opacity, target_opacity, duration,
|
||||
NULL, NULL);
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
@ -2412,7 +2413,7 @@ 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);
|
||||
animatable_set_target(&w->blur_opacity, 0, duration, NULL, NULL);
|
||||
|
||||
#ifdef CONFIG_DBUS
|
||||
// Send D-Bus signal
|
||||
|
@ -2527,7 +2528,7 @@ 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);
|
||||
animatable_set_target(&w->blur_opacity, 1, duration, NULL, NULL);
|
||||
|
||||
log_debug("Window %#010x has opacity %f, opacity target is %f", w->base.id,
|
||||
animatable_get(&w->opacity), w->opacity.target);
|
||||
|
@ -2572,7 +2573,8 @@ 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
|
||||
animatable_set_target(&w->blur_opacity, w->blur_opacity.target, duration);
|
||||
animatable_set_target(&w->blur_opacity, w->blur_opacity.target, duration,
|
||||
NULL, NULL);
|
||||
log_debug("Opacity changed while fading in");
|
||||
} else if (w->state == WSTATE_FADING) {
|
||||
// Opacity target changed while FADING.
|
||||
|
|
Loading…
Reference in New Issue