From e5587312a80591a30ee8e001a98b00093ca802df Mon Sep 17 00:00:00 2001 From: William McKinnon Date: Sat, 24 Feb 2024 22:22:07 -0500 Subject: [PATCH] added animation manager --- include/sway/server.h | 3 +++ include/sway/tree/container.h | 2 -- sway/server.c | 39 +++++++++++++++++++++++++++++++++++ sway/tree/container.c | 38 +--------------------------------- sway/tree/view.c | 7 ++----- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/include/sway/server.h b/include/sway/server.h index 96c3623f..c002990a 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -133,6 +133,9 @@ struct sway_server { // Stores the nodes that have been marked as "dirty" and will be put into // the pending transaction. list_t *dirty_nodes; + + list_t *animated_containers; + struct wl_event_source *animation_tick; }; extern struct sway_server server; diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 715eae19..c2026fa1 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -125,8 +125,6 @@ struct sway_container { float target_alpha; float max_alpha; - struct wl_event_source *animation_present_timer; - int corner_radius; float dim; diff --git a/sway/server.c b/sway/server.c index 262b7788..ef7e4f5b 100644 --- a/sway/server.c +++ b/sway/server.c @@ -63,6 +63,39 @@ static void handle_drm_lease_request(struct wl_listener *listener, void *data) { } } +static int animation_timer(void *data) { + struct sway_server *server = data; + float fastest_output_refresh_s = 1.0 / 60.0; // fallback to 60 Hz + + for (int i = 0; i < server->animated_containers->length; i++) { + struct sway_container *con = server->animated_containers->items[i]; + bool is_closing = con->alpha > con->target_alpha; + + for (int i = 0; i < con->outputs->length; ++i) { + struct sway_output *output = root->outputs->items[i]; + fastest_output_refresh_s = MIN(fastest_output_refresh_s, output->refresh_sec); + float alpha_step = config->animation_duration ? + (con->max_alpha * output->refresh_sec) / config->animation_duration : con->max_alpha; + con->alpha = is_closing ? MAX(con->alpha - alpha_step, con->target_alpha) : + MIN(con->alpha + alpha_step, con->target_alpha); + } + + if (con->alpha == con->target_alpha) { + list_del(server->animated_containers, i); + if (is_closing) { + printf("done animation; clean up view\n"); + view_remove_container(con->view); + continue; + } + } + + container_damage_whole(con); + } + + wl_event_source_timer_update(server->animation_tick, fastest_output_refresh_s * 1000); + return 1; +} + #define SWAY_XDG_SHELL_VERSION 2 bool server_init(struct sway_server *server) { @@ -264,6 +297,10 @@ bool server_init(struct sway_server *server) { server->input = input_manager_create(server); input_manager_get_default_seat(); // create seat0 + server->animated_containers = create_list(); + server->animation_tick = wl_event_loop_add_timer(server->wl_event_loop, animation_timer, server); + wl_event_source_timer_update(server->animation_tick, 1); + return true; } @@ -275,6 +312,8 @@ void server_fini(struct sway_server *server) { wl_display_destroy_clients(server->wl_display); wl_display_destroy(server->wl_display); list_free(server->dirty_nodes); + list_free(server->animated_containers); + wl_event_source_remove(server->animation_tick); } bool server_start(struct sway_server *server) { diff --git a/sway/tree/container.c b/sway/tree/container.c index 5f1e0cf6..41b8fabd 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -30,36 +30,6 @@ #include "log.h" #include "stringop.h" -// TODO signal instead of timer? -// TODO determine return val -// TODO no longer need output->refresh_sec? -// TODO better timing -static int animation_timer(void *data) { - struct sway_container *con = data; - float fastest_output_refresh_s = 0; - bool is_closing = con->alpha > con->target_alpha; - - for (int i = 0; i < con->outputs->length; ++i) { - struct sway_output *output = root->outputs->items[i]; - fastest_output_refresh_s = MAX(fastest_output_refresh_s, output->refresh_sec); - float alpha_step = config->animation_duration ? - (con->max_alpha * output->refresh_sec) / config->animation_duration : con->max_alpha; - con->alpha = is_closing ? MAX(con->alpha - alpha_step, con->target_alpha) : - MIN(con->alpha + alpha_step, con->target_alpha); - } - - if (con->alpha != con->target_alpha) { - wl_event_source_timer_update(con->animation_present_timer, fastest_output_refresh_s * 1000); - } else if (is_closing) { // equal to target and closing - printf("done animation; clean up view\n"); - view_remove_container(con->view); - return 1; - } - - container_damage_whole(con); - return 1; -} - struct sway_container *container_create(struct sway_view *view) { struct sway_container *c = calloc(1, sizeof(struct sway_container)); if (!c) { @@ -87,12 +57,8 @@ struct sway_container *container_create(struct sway_view *view) { wl_signal_init(&c->events.destroy); - c->animation_present_timer = wl_event_loop_add_timer(server.wl_event_loop, - animation_timer, c); - // TODO: WON'T SPAWN IF LESS THAN 50, get optimal time (or use a signal?) - wl_event_source_timer_update(c->animation_present_timer, 200); - wl_signal_emit_mutable(&root->events.new_node, &c->node); + list_add(server.animated_containers, c); return c; } @@ -125,8 +91,6 @@ void container_destroy(struct sway_container *con) { wlr_texture_destroy(con->marks_urgent); wlr_texture_destroy(con->marks_focused_tab_title); - wl_event_source_remove(con->animation_present_timer); - if (con->view && con->view->container == con) { con->view->container = NULL; if (con->view->destroying) { diff --git a/sway/tree/view.c b/sway/tree/view.c index 6ba34069..f3426f5b 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -93,7 +93,6 @@ void view_remove_container(struct sway_view *view) { arrange_workspace(ws); workspace_detect_urgent(ws); } - transaction_commit_dirty(); } void view_begin_destroy(struct sway_view *view) { @@ -946,14 +945,12 @@ void view_unmap(struct sway_view *view) { if (!config->animation_duration) { view_remove_container(view); + transaction_commit_dirty(); } else { - // unfocus the view - // look at handle_seat_node_destroy - wl_signal_emit_mutable(&view->container->node.events.destroy, &view->container->node); view_save_buffer(view); view->container->target_alpha = 0; - wl_event_source_timer_update(view->container->animation_present_timer, 50); + list_add(server.animated_containers, view->container); } struct sway_seat *seat;