wayland: Add destruction listener to activation token surface
In the timespan between an activation token being created and the token being used by the activated application, the surface that started the activation request may end up destroyed/disposed. In that case, the token would be left with a stale surface pointer, maybe causing crashes later on. Set up a destroy notification listener so that we do know to unset the token surface if that situation arises, this will result in Mutter not considering the token activatable, thus maybe issuing the "Application needs attention" notification if the activated surface did not immediately get focus. In any case this is better than a compositor crash. A typical situation where this may happen is "Open With..." dialogs, since those don't live long after launching the application. Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2390 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2592>
This commit is contained in:
parent
9c402bd091
commit
ed516dde89
@ -47,6 +47,7 @@ struct _MetaXdgActivationToken
|
|||||||
MetaWaylandSeat *seat;
|
MetaWaylandSeat *seat;
|
||||||
MetaWaylandActivation *activation;
|
MetaWaylandActivation *activation;
|
||||||
MetaStartupSequence *sequence;
|
MetaStartupSequence *sequence;
|
||||||
|
struct wl_listener surface_listener;
|
||||||
char *app_id;
|
char *app_id;
|
||||||
char *token;
|
char *token;
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
@ -94,6 +95,8 @@ token_set_surface (struct wl_client *client,
|
|||||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||||
|
|
||||||
token->surface = surface;
|
token->surface = surface;
|
||||||
|
wl_resource_add_destroy_listener (surface_resource,
|
||||||
|
&token->surface_listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -216,6 +219,17 @@ meta_xdg_activation_token_free (MetaXdgActivationToken *token)
|
|||||||
g_free (token);
|
g_free (token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
token_handle_surface_destroy (struct wl_listener *listener,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
MetaXdgActivationToken *token = wl_container_of (listener, token,
|
||||||
|
surface_listener);
|
||||||
|
|
||||||
|
token->surface = NULL;
|
||||||
|
wl_list_remove (&token->surface_listener.link);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_activation_token_create_new_resource (MetaWaylandActivation *activation,
|
meta_wayland_activation_token_create_new_resource (MetaWaylandActivation *activation,
|
||||||
struct wl_client *client,
|
struct wl_client *client,
|
||||||
@ -237,6 +251,7 @@ meta_wayland_activation_token_create_new_resource (MetaWaylandActivation *activa
|
|||||||
wl_resource_set_user_data (token_resource, token);
|
wl_resource_set_user_data (token_resource, token);
|
||||||
wl_list_insert (&activation->token_list,
|
wl_list_insert (&activation->token_list,
|
||||||
wl_resource_get_link (token_resource));
|
wl_resource_get_link (token_resource));
|
||||||
|
token->surface_listener.notify = token_handle_surface_destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user