diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 653df44d..8605a1f5 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -311,7 +311,7 @@ void view_for_each_popup_surface(struct sway_view *view, void view_init(struct sway_view *view, enum sway_view_type type, const struct sway_view_impl *impl); -void view_remove_container(struct sway_view *view); +void view_remove_container(struct sway_container *container); void view_destroy(struct sway_view *view); diff --git a/sway/server.c b/sway/server.c index 78be989b..25b93a49 100644 --- a/sway/server.c +++ b/sway/server.c @@ -43,6 +43,7 @@ #include "sway/config.h" #include "sway/desktop/fx_renderer/fx_renderer.h" #include "sway/desktop/idle_inhibit_v1.h" +#include "sway/desktop/transaction.h" #include "sway/input/input-manager.h" #include "sway/output.h" #include "sway/server.h" @@ -74,33 +75,56 @@ float get_fastest_output_refresh_s() { return fastest_output_refresh_s; } - +// TODO: animation struct with callback on completion static int animation_timer(void *data) { struct sway_server *server = data; float fastest_output_refresh_s = get_fastest_output_refresh_s(); + wl_event_source_timer_update(server->animation_tick, fastest_output_refresh_s * 1000); - for (int i = 0; i < server->animated_containers->length; i++) { + int num_containers; + memcpy(&num_containers, &server->animated_containers->length, sizeof(int)); + int num_animations_complete = 0; + int completed_animation_indexes[100]; // TODO: this can be better + bool should_commit_transaction = false; + + // update state + for (int i = 0; i < num_containers; i++) { struct sway_container *con = server->animated_containers->items[i]; bool is_closing = con->alpha > con->target_alpha; - float alpha_step = config->animation_duration ? (con->max_alpha * fastest_output_refresh_s) / 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; + completed_animation_indexes[num_animations_complete] = i; + num_animations_complete++; + if (con->alpha == 0) { + view_remove_container(con); + should_commit_transaction = true; } } - - container_damage_whole(con); } - wl_event_source_timer_update(server->animation_tick, fastest_output_refresh_s * 1000); + // damage track + if (should_commit_transaction) { + transaction_commit_dirty(); + } else { + for (int i = 0; i < num_containers; i++) { + struct sway_container *con = server->animated_containers->items[i]; + if (view_is_visible(con->view)) { + container_damage_whole(con); + } + } + } + + // clean up list + for (int i = 0; i < num_animations_complete; i++) { + int container_index = completed_animation_indexes[i]; + list_del(server->animated_containers, container_index); + } + return 1; } diff --git a/sway/tree/view.c b/sway/tree/view.c index f3426f5b..0ab227f1 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -76,10 +76,10 @@ void view_destroy(struct sway_view *view) { } } -void view_remove_container(struct sway_view *view) { - struct sway_container *parent = view->container->pending.parent; - struct sway_workspace *ws = view->container->pending.workspace; - container_begin_destroy(view->container); +void view_remove_container(struct sway_container *container) { + struct sway_container *parent = container->pending.parent; + struct sway_workspace *ws = container->pending.workspace; + container_begin_destroy(container); if (parent) { container_reap_empty(parent); } else if (ws) { @@ -943,15 +943,16 @@ void view_unmap(struct sway_view *view) { view->foreign_toplevel = NULL; } + /* if (!config->animation_duration) { view_remove_container(view); transaction_commit_dirty(); - } else { + } else {*/ wl_signal_emit_mutable(&view->container->node.events.destroy, &view->container->node); view_save_buffer(view); view->container->target_alpha = 0; list_add(server.animated_containers, view->container); - } + //} struct sway_seat *seat; wl_list_for_each(seat, &server.input->seats, link) {