added animation manager
This commit is contained in:
parent
d741e2415a
commit
e5587312a8
5 changed files with 45 additions and 44 deletions
|
@ -133,6 +133,9 @@ struct sway_server {
|
||||||
// Stores the nodes that have been marked as "dirty" and will be put into
|
// Stores the nodes that have been marked as "dirty" and will be put into
|
||||||
// the pending transaction.
|
// the pending transaction.
|
||||||
list_t *dirty_nodes;
|
list_t *dirty_nodes;
|
||||||
|
|
||||||
|
list_t *animated_containers;
|
||||||
|
struct wl_event_source *animation_tick;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct sway_server server;
|
extern struct sway_server server;
|
||||||
|
|
|
@ -125,8 +125,6 @@ struct sway_container {
|
||||||
float target_alpha;
|
float target_alpha;
|
||||||
float max_alpha;
|
float max_alpha;
|
||||||
|
|
||||||
struct wl_event_source *animation_present_timer;
|
|
||||||
|
|
||||||
int corner_radius;
|
int corner_radius;
|
||||||
|
|
||||||
float dim;
|
float dim;
|
||||||
|
|
|
@ -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
|
#define SWAY_XDG_SHELL_VERSION 2
|
||||||
|
|
||||||
bool server_init(struct sway_server *server) {
|
bool server_init(struct sway_server *server) {
|
||||||
|
@ -264,6 +297,10 @@ bool server_init(struct sway_server *server) {
|
||||||
server->input = input_manager_create(server);
|
server->input = input_manager_create(server);
|
||||||
input_manager_get_default_seat(); // create seat0
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,6 +312,8 @@ void server_fini(struct sway_server *server) {
|
||||||
wl_display_destroy_clients(server->wl_display);
|
wl_display_destroy_clients(server->wl_display);
|
||||||
wl_display_destroy(server->wl_display);
|
wl_display_destroy(server->wl_display);
|
||||||
list_free(server->dirty_nodes);
|
list_free(server->dirty_nodes);
|
||||||
|
list_free(server->animated_containers);
|
||||||
|
wl_event_source_remove(server->animation_tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool server_start(struct sway_server *server) {
|
bool server_start(struct sway_server *server) {
|
||||||
|
|
|
@ -30,36 +30,6 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "stringop.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 *container_create(struct sway_view *view) {
|
||||||
struct sway_container *c = calloc(1, sizeof(struct sway_container));
|
struct sway_container *c = calloc(1, sizeof(struct sway_container));
|
||||||
if (!c) {
|
if (!c) {
|
||||||
|
@ -87,12 +57,8 @@ struct sway_container *container_create(struct sway_view *view) {
|
||||||
|
|
||||||
wl_signal_init(&c->events.destroy);
|
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);
|
wl_signal_emit_mutable(&root->events.new_node, &c->node);
|
||||||
|
list_add(server.animated_containers, c);
|
||||||
|
|
||||||
return 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_urgent);
|
||||||
wlr_texture_destroy(con->marks_focused_tab_title);
|
wlr_texture_destroy(con->marks_focused_tab_title);
|
||||||
|
|
||||||
wl_event_source_remove(con->animation_present_timer);
|
|
||||||
|
|
||||||
if (con->view && con->view->container == con) {
|
if (con->view && con->view->container == con) {
|
||||||
con->view->container = NULL;
|
con->view->container = NULL;
|
||||||
if (con->view->destroying) {
|
if (con->view->destroying) {
|
||||||
|
|
|
@ -93,7 +93,6 @@ void view_remove_container(struct sway_view *view) {
|
||||||
arrange_workspace(ws);
|
arrange_workspace(ws);
|
||||||
workspace_detect_urgent(ws);
|
workspace_detect_urgent(ws);
|
||||||
}
|
}
|
||||||
transaction_commit_dirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_begin_destroy(struct sway_view *view) {
|
void view_begin_destroy(struct sway_view *view) {
|
||||||
|
@ -946,14 +945,12 @@ void view_unmap(struct sway_view *view) {
|
||||||
|
|
||||||
if (!config->animation_duration) {
|
if (!config->animation_duration) {
|
||||||
view_remove_container(view);
|
view_remove_container(view);
|
||||||
|
transaction_commit_dirty();
|
||||||
} else {
|
} else {
|
||||||
// unfocus the view
|
|
||||||
// look at handle_seat_node_destroy
|
|
||||||
|
|
||||||
wl_signal_emit_mutable(&view->container->node.events.destroy, &view->container->node);
|
wl_signal_emit_mutable(&view->container->node.events.destroy, &view->container->node);
|
||||||
view_save_buffer(view);
|
view_save_buffer(view);
|
||||||
view->container->target_alpha = 0;
|
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;
|
struct sway_seat *seat;
|
||||||
|
|
Loading…
Add table
Reference in a new issue