From 76f51a949f55c865e3ea1c90965afd4d835baad9 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 1 Jun 2021 11:29:10 +0200 Subject: [PATCH] xdg-activation-v1: add token timeout There isn't always a good time to prune old tokens. Compositors which only implement a "give focus on activation" logic can prune tokens on focus change. However other compositors might want to implement other semantics, e.g. "mark urgent on activation". In this case a focus change shouldn't invalidate other tokens. Additionally, some tokens aren't necessarily tied to a seat. To avoid ending up with an ever-growing list of tokens, add a timeout. --- include/wlr/types/wlr_xdg_activation_v1.h | 2 ++ types/wlr_xdg_activation_v1.c | 25 ++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/include/wlr/types/wlr_xdg_activation_v1.h b/include/wlr/types/wlr_xdg_activation_v1.h index 121e66a1..04558a08 100644 --- a/include/wlr/types/wlr_xdg_activation_v1.h +++ b/include/wlr/types/wlr_xdg_activation_v1.h @@ -26,12 +26,14 @@ struct wlr_xdg_activation_token_v1 { char *token; struct wl_resource *resource; // can be NULL + struct wl_event_source *timeout; // can be NULL struct wl_listener seat_destroy; struct wl_listener surface_destroy; }; struct wlr_xdg_activation_v1 { + uint32_t token_timeout_msec; // token timeout in milliseconds (0 to disable) struct wl_list tokens; // wlr_xdg_activation_token_v1.link diff --git a/types/wlr_xdg_activation_v1.c b/types/wlr_xdg_activation_v1.c index 28cb8da3..7fcb50c3 100644 --- a/types/wlr_xdg_activation_v1.c +++ b/types/wlr_xdg_activation_v1.c @@ -28,6 +28,9 @@ static void token_destroy(struct wlr_xdg_activation_token_v1 *token) { if (token->resource != NULL) { wl_resource_set_user_data(token->resource, NULL); // make inert } + if (token->timeout != NULL) { + wl_event_source_remove(token->timeout); + } wl_list_remove(&token->link); wl_list_remove(&token->seat_destroy.link); wl_list_remove(&token->surface_destroy.link); @@ -36,6 +39,13 @@ static void token_destroy(struct wlr_xdg_activation_token_v1 *token) { free(token); } +static int token_handle_timeout(void *data) { + struct wlr_xdg_activation_token_v1 *token = data; + wlr_log(WLR_DEBUG, "Activation token '%s' has expired", token->token); + token_destroy(token); + return 0; +} + static void token_handle_resource_destroy(struct wl_resource *resource) { struct wlr_xdg_activation_token_v1 *token = token_from_resource(resource); token_destroy(token); @@ -91,12 +101,24 @@ static void token_handle_commit(struct wl_client *client, return; } + if (token->activation->token_timeout_msec > 0) { + struct wl_display *display = wl_client_get_display(client); + struct wl_event_loop *loop = wl_display_get_event_loop(display); + token->timeout = + wl_event_loop_add_timer(loop, token_handle_timeout, token); + if (token->timeout == NULL) { + wl_client_post_no_memory(client); + return; + } + wl_event_source_timer_update(token->timeout, + token->activation->token_timeout_msec); + } + assert(wl_list_empty(&token->link)); wl_list_insert(&token->activation->tokens, &token->link); xdg_activation_token_v1_send_done(token_resource, token_str); - // TODO: figure out when to discard the token // TODO: consider emitting a new_token event return; @@ -308,6 +330,7 @@ struct wlr_xdg_activation_v1 *wlr_xdg_activation_v1_create( return NULL; } + activation->token_timeout_msec = 30000; // 30s wl_list_init(&activation->tokens); wl_signal_init(&activation->events.destroy); wl_signal_init(&activation->events.request_activate);