mirror of
https://github.com/brl/mutter.git
synced 2025-01-22 17:38:56 +00:00
MetaWaylandPointerConstraints: Handle delayed window surface association
For Xwayland, a newly created wl_surface and X11 Window pair may not be immediately associated, but Xwayland may still request a pointer constraint on some of its wl_surface's. Handle the situation by postponing maybe enabling the constraint until the window and surface has been associated. https://bugzilla.gnome.org/show_bug.cgi?id=771050
This commit is contained in:
parent
fccdd00f74
commit
262b52da50
@ -34,6 +34,7 @@
|
|||||||
#include "meta-wayland-pointer.h"
|
#include "meta-wayland-pointer.h"
|
||||||
#include "meta-wayland-surface.h"
|
#include "meta-wayland-surface.h"
|
||||||
#include "meta-wayland-region.h"
|
#include "meta-wayland-region.h"
|
||||||
|
#include "meta-xwayland.h"
|
||||||
#include "meta-pointer-lock-wayland.h"
|
#include "meta-pointer-lock-wayland.h"
|
||||||
#include "meta-pointer-confinement-wayland.h"
|
#include "meta-pointer-confinement-wayland.h"
|
||||||
#include "window-private.h"
|
#include "window-private.h"
|
||||||
@ -67,8 +68,13 @@ struct _MetaWaylandPointerConstraint
|
|||||||
|
|
||||||
typedef struct _MetaWaylandSurfacePointerConstraintsData
|
typedef struct _MetaWaylandSurfacePointerConstraintsData
|
||||||
{
|
{
|
||||||
|
MetaWaylandSurface *surface;
|
||||||
|
|
||||||
GList *pointer_constraints;
|
GList *pointer_constraints;
|
||||||
|
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
|
gulong window_associated_handler_id;
|
||||||
|
|
||||||
gulong appears_changed_handler_id;
|
gulong appears_changed_handler_id;
|
||||||
gulong raised_handler_id;
|
gulong raised_handler_id;
|
||||||
} MetaWaylandSurfacePointerConstraintsData;
|
} MetaWaylandSurfacePointerConstraintsData;
|
||||||
@ -96,6 +102,9 @@ static const MetaWaylandPointerGrabInterface confined_pointer_grab_interface;
|
|||||||
static void
|
static void
|
||||||
meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint);
|
meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint);
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *constraint);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window);
|
meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window);
|
||||||
|
|
||||||
@ -133,6 +142,34 @@ window_raised (MetaWindow *window)
|
|||||||
meta_wayland_pointer_constraint_maybe_enable_for_window (window);
|
meta_wayland_pointer_constraint_maybe_enable_for_window (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
connect_window (MetaWaylandSurfacePointerConstraintsData *data,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
data->window = window;
|
||||||
|
g_object_add_weak_pointer (G_OBJECT (data->window),
|
||||||
|
(gpointer *) &data->window);
|
||||||
|
data->appears_changed_handler_id =
|
||||||
|
g_signal_connect (data->window, "notify::appears-focused",
|
||||||
|
G_CALLBACK (appears_focused_changed), NULL);
|
||||||
|
data->raised_handler_id =
|
||||||
|
g_signal_connect (data->window, "raised",
|
||||||
|
G_CALLBACK (window_raised), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
window_associated (MetaWaylandSurfaceRole *surface_role,
|
||||||
|
MetaWaylandSurfacePointerConstraintsData *data)
|
||||||
|
{
|
||||||
|
MetaWaylandSurface *surface = data->surface;
|
||||||
|
|
||||||
|
connect_window (data, surface->window);
|
||||||
|
g_signal_handler_disconnect (surface, data->window_associated_handler_id);
|
||||||
|
data->window_associated_handler_id = 0;
|
||||||
|
|
||||||
|
meta_wayland_pointer_constraint_maybe_enable_for_window (surface->window);
|
||||||
|
}
|
||||||
|
|
||||||
static MetaWaylandSurfacePointerConstraintsData *
|
static MetaWaylandSurfacePointerConstraintsData *
|
||||||
surface_constraint_data_new (MetaWaylandSurface *surface)
|
surface_constraint_data_new (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
@ -140,17 +177,18 @@ surface_constraint_data_new (MetaWaylandSurface *surface)
|
|||||||
|
|
||||||
data = g_new0 (MetaWaylandSurfacePointerConstraintsData, 1);
|
data = g_new0 (MetaWaylandSurfacePointerConstraintsData, 1);
|
||||||
|
|
||||||
|
data->surface = surface;
|
||||||
|
|
||||||
if (surface->window)
|
if (surface->window)
|
||||||
{
|
{
|
||||||
data->window = surface->window;
|
connect_window (data, surface->window);
|
||||||
g_object_add_weak_pointer (G_OBJECT (data->window),
|
}
|
||||||
(gpointer *) &data->window);
|
else if (meta_xwayland_is_xwayland_surface (surface))
|
||||||
data->appears_changed_handler_id =
|
{
|
||||||
g_signal_connect (data->window, "notify::appears-focused",
|
data->window_associated_handler_id =
|
||||||
G_CALLBACK (appears_focused_changed), NULL);
|
g_signal_connect (surface->role, "window-associated",
|
||||||
data->raised_handler_id =
|
G_CALLBACK (window_associated),
|
||||||
g_signal_connect (data->window, "raised",
|
data);
|
||||||
G_CALLBACK (window_raised), NULL);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -173,12 +211,24 @@ surface_constraint_data_free (MetaWaylandSurfacePointerConstraintsData *data)
|
|||||||
g_object_remove_weak_pointer (G_OBJECT (data->window),
|
g_object_remove_weak_pointer (G_OBJECT (data->window),
|
||||||
(gpointer *) &data->window);
|
(gpointer *) &data->window);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (data->surface->role,
|
||||||
|
data->window_associated_handler_id);
|
||||||
|
}
|
||||||
|
|
||||||
g_list_free_full (data->pointer_constraints,
|
g_list_free_full (data->pointer_constraints,
|
||||||
(GDestroyNotify) meta_wayland_pointer_constraint_destroy);
|
(GDestroyNotify) meta_wayland_pointer_constraint_destroy);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
constrained_surface_destroyed (MetaWaylandSurface *surface,
|
||||||
|
MetaWaylandSurfacePointerConstraintsData *data)
|
||||||
|
{
|
||||||
|
surface_constraint_data_free (data);
|
||||||
|
}
|
||||||
|
|
||||||
static MetaWaylandSurfacePointerConstraintsData *
|
static MetaWaylandSurfacePointerConstraintsData *
|
||||||
ensure_surface_constraints_data (MetaWaylandSurface *surface)
|
ensure_surface_constraints_data (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
@ -188,10 +238,11 @@ ensure_surface_constraints_data (MetaWaylandSurface *surface)
|
|||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
data = surface_constraint_data_new (surface);
|
data = surface_constraint_data_new (surface);
|
||||||
g_object_set_qdata_full (G_OBJECT (surface),
|
g_object_set_qdata (G_OBJECT (surface),
|
||||||
quark_surface_pointer_constraints_data,
|
quark_surface_pointer_constraints_data,
|
||||||
data,
|
data);
|
||||||
(GDestroyNotify) surface_constraint_data_free);
|
g_signal_connect (surface, "destroy",
|
||||||
|
G_CALLBACK (constrained_surface_destroyed), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -387,7 +438,11 @@ meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *cons
|
|||||||
|
|
||||||
if (!constraint->surface->window)
|
if (!constraint->surface->window)
|
||||||
{
|
{
|
||||||
g_warn_if_reached ();
|
/*
|
||||||
|
* Locks from Xwayland may come before we have had the opportunity to
|
||||||
|
* associate the X11 Window with the wl_surface.
|
||||||
|
*/
|
||||||
|
g_warn_if_fail (meta_xwayland_is_xwayland_surface (constraint->surface));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,6 +509,12 @@ meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window)
|
|||||||
MetaWaylandSurfacePointerConstraintsData *surface_data;
|
MetaWaylandSurfacePointerConstraintsData *surface_data;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
|
if (!surface)
|
||||||
|
{
|
||||||
|
g_warn_if_fail (window->client_type == META_WINDOW_CLIENT_TYPE_X11);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
surface_data = get_surface_constraints_data (surface);
|
surface_data = get_surface_constraints_data (surface);
|
||||||
if (!surface_data)
|
if (!surface_data)
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user