初步完成动画

This commit is contained in:
DreamMaoMao 2025-11-04 11:31:04 +08:00
parent 70eb70ef0d
commit a6571c07e3
5 changed files with 81 additions and 11 deletions

View file

@ -672,11 +672,18 @@ void fadeout_client_animation_next_tick(Client *c) {
}
}
void client_animation_next_tick(Client *c) {
double animation_passed =
c->animation.total_frames
? (double)c->animation.passed_frames / c->animation.total_frames
: 1.0;
int client_animation_next_tick(void *data) {
Client *c = (Client *)data;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint32_t passed_time = timespec_to_ms(&now) - c->animation.time_started;
double animation_passed = (double)passed_time / (double)c->animation.duration;
wlr_log(WLR_ERROR,"passed_time:%d",passed_time);
wlr_log(WLR_ERROR,"animation_passed:%f",animation_passed);
wlr_log(WLR_ERROR,"duration:%d",c->animation.duration);
int type = c->animation.action == NONE ? MOVE : c->animation.action;
double factor = find_animation_curve_at(animation_passed, type);
@ -707,7 +714,7 @@ void client_animation_next_tick(Client *c) {
c->is_pending_open_animation = false;
if (animation_passed == 1.0) {
if (animation_passed >= 1.0) {
// clear the open action state
// To prevent him from being mistaken that
@ -735,11 +742,18 @@ void client_animation_next_tick(Client *c) {
// end flush in next frame, not the current frame
c->need_output_flush = false;
destroy_animation_timer(c);
} else {
c->animation.passed_frames++;
wl_event_source_timer_update(c->animation.timer, c->animation.frame_duration);
}
client_apply_clip(c, factor);
if(c->animation.running) {
return 1;
} else {
return 0;
}
}
void init_fadeout_client(Client *c) {
@ -840,9 +854,14 @@ void client_commit(Client *c) {
c->animation.initial = c->animainit_geom;
// 设置动画速度
c->animation.passed_frames = 0;
c->animation.total_frames =
c->animation.duration / all_output_frame_duration_ms();
c->animation.time_started = get_now_in_ms();
c->animation.frame_duration = get_fastest_output_refresh_ms();
wlr_log(WLR_ERROR,"time_started:%d",c->animation.time_started);
wlr_log(WLR_ERROR,"frame_duration:%d",c->animation.frame_duration);
if(!c->animation.running)
c->animation.timer =
wl_event_loop_add_timer(wl_display_get_event_loop(dpy), client_animation_next_tick, c);
wl_event_source_timer_update(c->animation.timer, c->animation.frame_duration);
// 标记动画开始
c->animation.running = true;
@ -1085,6 +1104,7 @@ void cleint_set_unfocused_opacity_animation(Client *c) {
}
bool client_apply_focus_opacity(Client *c) {
return false;
// Animate focus transitions (opacity + border color)
float *border_color = get_border_color(c);
if (c->isfullscreen) {
@ -1160,7 +1180,7 @@ bool client_draw_frame(Client *c) {
}
if (animations && c->animation.running) {
client_animation_next_tick(c);
// client_animation_next_tick(c);
} else {
wlr_scene_node_set_position(&c->scene->node, c->pending.x,
c->pending.y);

View file

@ -86,6 +86,26 @@ double find_animation_curve_at(double t, int type) {
return baked_points[up].y;
}
int get_fastest_output_refresh_ms(void) {
Monitor *m;
int max = 0;
wl_list_for_each(m, &mons, link) {
if(!m->wlr_output->enabled) {
continue;
}
if(m->wlr_output->refresh > max) {
max = m->wlr_output->refresh;
}
}
// we default to 60 fps
if(max == 0) {
max = 60000;
}
return 1000000.0 / max;
}
double all_output_frame_duration_ms() {
int32_t refresh_total = 0;
Monitor *m = NULL;
@ -254,4 +274,11 @@ void request_fresh_all_monitors(void) {
}
wlr_output_schedule_frame(m->wlr_output);
}
}
void destroy_animation_timer(Client *c) {
if(c->animation.timer) {
wl_event_source_remove(c->animation.timer);
c->animation.timer = NULL;
}
}

View file

@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "util.h"
@ -80,3 +81,16 @@ int regex_match(const char *pattern, const char *str) {
void wl_list_append(struct wl_list *list, struct wl_list *object) {
wl_list_insert(list->prev, object);
}
unsigned int get_now_in_ms(void) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return timespec_to_ms(&now);
}
unsigned int
timespec_to_ms(struct timespec *ts) {
return (unsigned int)ts->tv_sec * 1000 + (unsigned int)ts->tv_nsec / 1000000;
}

View file

@ -6,3 +6,5 @@ void *ecalloc(size_t nmemb, size_t size);
int fd_set_nonblock(int fd);
int regex_match(const char *pattern_mb, const char *str_mb);
void wl_list_append(struct wl_list *list, struct wl_list *object);
unsigned int get_now_in_ms(void);
unsigned int timespec_to_ms(struct timespec *ts);

View file

@ -231,6 +231,9 @@ struct dwl_animation {
bool tagouting;
bool begin_fade_in;
bool tag_from_rule;
unsigned int time_started;
int frame_duration;
struct wl_event_source *timer;
unsigned int total_frames;
unsigned int passed_frames;
unsigned int duration;
@ -705,6 +708,8 @@ static void refresh_monitors_workspaces_status(Monitor *m);
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);
#include "data/static_keymap.h"
#include "dispatch/bind_declare.h"
@ -5188,6 +5193,8 @@ void unmapnotify(struct wl_listener *listener, void *data) {
Monitor *m = NULL;
c->iskilling = 1;
destroy_animation_timer(c);
if (animations && !c->is_clip_to_hide && !c->isminied &&
(!c->mon || VISIBLEON(c, c->mon)))
init_fadeout_client(c);