wayland/activation: Apply xdg-activation request when window gets mapped
If the window is not mapped yet and we get an activation request, we will wait for the window to get mapped or destroyed to try to fullfil the request. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3728>
This commit is contained in:
parent
77b115399c
commit
c166b3fc5b
1 changed files with 59 additions and 12 deletions
|
@ -37,6 +37,7 @@ struct _MetaWaylandActivation
|
|||
struct wl_list resource_list;
|
||||
struct wl_list token_list;
|
||||
GHashTable *tokens;
|
||||
GHashTable *pending_activations;
|
||||
};
|
||||
|
||||
struct _MetaXdgActivationToken
|
||||
|
@ -322,22 +323,20 @@ startup_sequence_is_recent (MetaDisplay *display,
|
|||
return seq_timestamp_ms >= last_user_time_ms;
|
||||
}
|
||||
|
||||
static void
|
||||
activation_activate (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *token_str,
|
||||
struct wl_resource *surface_resource)
|
||||
static gboolean
|
||||
maybe_activate (MetaWaylandActivation *activation,
|
||||
MetaWindow *window,
|
||||
const char *token_str)
|
||||
{
|
||||
MetaWaylandActivation *activation = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaDisplay *display = display_from_activation (activation);
|
||||
MetaXdgActivationToken *token;
|
||||
MetaStartupSequence *sequence;
|
||||
MetaWindow *window;
|
||||
|
||||
window = meta_wayland_surface_get_window (surface);
|
||||
if (!window)
|
||||
return;
|
||||
if (!window || window->unmanaging)
|
||||
return TRUE;
|
||||
|
||||
if (!window->mapped)
|
||||
return FALSE;
|
||||
|
||||
token = g_hash_table_lookup (activation->tokens, token_str);
|
||||
if (token)
|
||||
|
@ -351,7 +350,7 @@ activation_activate (struct wl_client *client,
|
|||
}
|
||||
|
||||
if (!sequence)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
if ((token && token_can_activate (token)) ||
|
||||
(!token && startup_sequence_is_recent (display, sequence)))
|
||||
|
@ -374,6 +373,50 @@ activation_activate (struct wl_client *client,
|
|||
}
|
||||
|
||||
meta_startup_sequence_complete (sequence);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
complete_pending_activate (MetaWaylandActivation *activation,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_autofree char *token_str = NULL;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (window, complete_pending_activate,
|
||||
activation);
|
||||
g_hash_table_steal_extended (activation->pending_activations, window,
|
||||
NULL, (gpointer *) &token_str);
|
||||
|
||||
maybe_activate (activation, window, token_str);
|
||||
}
|
||||
|
||||
static void
|
||||
activation_activate (struct wl_client *client,
|
||||
struct wl_resource *resource,
|
||||
const char *token_str,
|
||||
struct wl_resource *surface_resource)
|
||||
{
|
||||
MetaWaylandActivation *activation = wl_resource_get_user_data (resource);
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWindow *window = meta_wayland_surface_get_window (surface);
|
||||
|
||||
if (maybe_activate (activation, window, token_str))
|
||||
return;
|
||||
|
||||
g_assert (window != NULL);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (window,
|
||||
complete_pending_activate,
|
||||
activation);
|
||||
g_signal_connect_swapped (window, "notify::mapped",
|
||||
G_CALLBACK (complete_pending_activate),
|
||||
activation);
|
||||
g_signal_connect_swapped (window, "unmanaged",
|
||||
G_CALLBACK (complete_pending_activate),
|
||||
activation);
|
||||
g_hash_table_insert (activation->pending_activations,
|
||||
window, g_strdup (token_str));
|
||||
}
|
||||
|
||||
static const struct xdg_activation_v1_interface activation_interface = {
|
||||
|
@ -406,6 +449,7 @@ void
|
|||
meta_wayland_activation_finalize (MetaWaylandCompositor *compositor)
|
||||
{
|
||||
g_hash_table_destroy (compositor->activation->tokens);
|
||||
g_hash_table_destroy (compositor->activation->pending_activations);
|
||||
g_clear_pointer (&compositor->activation, g_free);
|
||||
}
|
||||
|
||||
|
@ -424,6 +468,9 @@ meta_wayland_activation_init (MetaWaylandCompositor *compositor)
|
|||
NULL,
|
||||
(GDestroyNotify) meta_xdg_activation_token_free);
|
||||
|
||||
activation->pending_activations =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||
|
||||
wl_global_create (compositor->wayland_display,
|
||||
&xdg_activation_v1_interface,
|
||||
META_XDG_ACTIVATION_V1_VERSION,
|
||||
|
|
Loading…
Add table
Reference in a new issue