完成layer打开动画

This commit is contained in:
DreamMaoMao 2025-11-04 12:18:58 +08:00
parent 498a09bc06
commit 7cf782070a
4 changed files with 44 additions and 19 deletions

View file

@ -666,7 +666,7 @@ int fadeout_client_animation_next_tick(void *data) {
}
if (animation_passed >= 1.0) {
destroy_animation_timer(c);
client_destroy_animation_timer(c);
wl_list_remove(&c->fadeout_link);
wlr_scene_node_destroy(&c->scene->node);
free(c);
@ -717,7 +717,7 @@ int client_animation_next_tick(void *data) {
c->is_pending_open_animation = false;
if (animation_passed >= 1.0) {
client_destroy_animation_timer(c);
// clear the open action state
// To prevent him from being mistaken that
// it's still in the opening animation in resize
@ -744,7 +744,6 @@ int client_animation_next_tick(void *data) {
// end flush in next frame, not the current frame
c->need_output_flush = false;
destroy_animation_timer(c);
} else {
wl_event_source_timer_update(c->animation.timer, c->animation.frame_duration);
}

View file

@ -277,9 +277,16 @@ void request_fresh_all_monitors(void) {
}
}
void destroy_animation_timer(Client *c) {
void client_destroy_animation_timer(Client *c) {
if(c->animation.timer) {
wl_event_source_remove(c->animation.timer);
c->animation.timer = NULL;
}
}
void layer_destroy_animation_timer(LayerSurface *l) {
if(l->animation.timer) {
wl_event_source_remove(l->animation.timer);
l->animation.timer = NULL;
}
}

View file

@ -290,15 +290,15 @@ void fadeout_layer_animation_next_tick(LayerSurface *l) {
}
}
void layer_animation_next_tick(LayerSurface *l) {
int layer_animation_next_tick(void *data) {
if (!l || !l->mapped)
return;
LayerSurface *l = (LayerSurface *)data;
double animation_passed =
l->animation.total_frames
? (double)l->animation.passed_frames / l->animation.total_frames
: 1.0;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint32_t passed_time = timespec_to_ms(&now) - l->animation.time_started;
double animation_passed = (double)passed_time / (double)l->animation.duration;
int type = l->animation.action == NONE ? MOVE : l->animation.action;
double factor = find_animation_curve_at(animation_passed, type);
@ -350,12 +350,23 @@ void layer_animation_next_tick(LayerSurface *l) {
};
if (animation_passed == 1.0) {
layer_destroy_animation_timer(l);
l->animation.running = false;
l->need_output_flush = false;
l->animation.action = MOVE;
} else {
l->animation.passed_frames++;
wl_event_source_timer_update(l->animation.timer, l->animation.frame_duration);
}
layer_draw_shadow(l);
if(l->animation.running) {
wlr_output_schedule_frame(l->mon->wlr_output);
return 1;
} else {
return 0;
}
}
void init_fadeout_layers(LayerSurface *l) {
@ -535,9 +546,13 @@ void layer_commit(LayerSurface *l) {
l->animation.initial = l->animainit_geom;
// 设置动画速度
l->animation.passed_frames = 0;
l->animation.total_frames =
l->animation.duration / output_frame_duration_ms(l->mon);
l->animation.time_started = get_now_in_ms();
l->animation.frame_duration = get_fastest_output_refresh_ms();
if(!l->animation.running)
l->animation.timer =
wl_event_loop_add_timer(wl_display_get_event_loop(dpy), layer_animation_next_tick, l);
wl_event_source_timer_update(l->animation.timer, l->animation.frame_duration);
// 标记动画开始
l->animation.running = true;
@ -570,8 +585,10 @@ bool layer_draw_frame(LayerSurface *l) {
}
if (animations && layer_animations && l->animation.running && !l->noanim) {
layer_animation_next_tick(l);
layer_draw_shadow(l);
if(!l->animation.nofirstframe) {
layer_animation_next_tick(l);
l->animation.nofirstframe = true;
}
} else {
layer_draw_shadow(l);
l->need_output_flush = false;

View file

@ -710,7 +710,7 @@ static void init_client_properties(Client *c);
static float *get_border_color(Client *c);
static void request_fresh_all_monitors(void);
static int get_fastest_output_refresh_ms(void);
static void destroy_animation_timer(Client *c);
static void client_destroy_animation_timer(Client *c);
#include "data/static_keymap.h"
#include "dispatch/bind_declare.h"
@ -5168,6 +5168,8 @@ void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
l->mapped = 0;
layer_destroy_animation_timer(l);
init_fadeout_layers(l);
wlr_scene_node_set_enabled(&l->scene->node, false);
@ -5187,7 +5189,7 @@ void unmapnotify(struct wl_listener *listener, void *data) {
Monitor *m = NULL;
c->iskilling = 1;
destroy_animation_timer(c);
client_destroy_animation_timer(c);
if (animations && !c->is_clip_to_hide && !c->isminied &&
(!c->mon || VISIBLEON(c, c->mon)))