diff --git a/src/animation/client.h b/src/animation/client.h index b151920..ce6356f 100644 --- a/src/animation/client.h +++ b/src/animation/client.h @@ -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); diff --git a/src/animation/common.h b/src/animation/common.h index edd39b0..4b361e5 100644 --- a/src/animation/common.h +++ b/src/animation/common.h @@ -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; + } } \ No newline at end of file diff --git a/src/common/util.c b/src/common/util.c index 272340c..6625d7f 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -4,6 +4,7 @@ #include #include #include +#include #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; +} diff --git a/src/common/util.h b/src/common/util.h index 2ebef43..3a0f6da 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -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); \ No newline at end of file diff --git a/src/mango.c b/src/mango.c index 0779e9f..c4d7011 100644 --- a/src/mango.c +++ b/src/mango.c @@ -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);