[mutter] MetaWaylandPointerConstraints: Handle delayed window surface association
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] MetaWaylandPointerConstraints: Handle delayed window surface association
- Date: Fri, 9 Sep 2016 03:10:48 +0000 (UTC)
commit 262b52da507b580c4a8cdf947dfde1ba96c5080a
Author: Jonas Ådahl <jadahl gmail com>
Date: Fri Apr 1 21:04:22 2016 +0800
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
src/wayland/meta-wayland-pointer-constraints.c | 89 ++++++++++++++++++++----
1 files changed, 75 insertions(+), 14 deletions(-)
---
diff --git a/src/wayland/meta-wayland-pointer-constraints.c b/src/wayland/meta-wayland-pointer-constraints.c
index 6477d41..46b471d 100644
--- a/src/wayland/meta-wayland-pointer-constraints.c
+++ b/src/wayland/meta-wayland-pointer-constraints.c
@@ -34,6 +34,7 @@
#include "meta-wayland-pointer.h"
#include "meta-wayland-surface.h"
#include "meta-wayland-region.h"
+#include "meta-xwayland.h"
#include "meta-pointer-lock-wayland.h"
#include "meta-pointer-confinement-wayland.h"
#include "window-private.h"
@@ -67,8 +68,13 @@ struct _MetaWaylandPointerConstraint
typedef struct _MetaWaylandSurfacePointerConstraintsData
{
+ MetaWaylandSurface *surface;
+
GList *pointer_constraints;
+
MetaWindow *window;
+ gulong window_associated_handler_id;
+
gulong appears_changed_handler_id;
gulong raised_handler_id;
} MetaWaylandSurfacePointerConstraintsData;
@@ -97,6 +103,9 @@ static void
meta_wayland_pointer_constraint_destroy (MetaWaylandPointerConstraint *constraint);
static void
+meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *constraint);
+
+static void
meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window);
static void
@@ -133,6 +142,34 @@ window_raised (MetaWindow *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 *
surface_constraint_data_new (MetaWaylandSurface *surface)
{
@@ -140,17 +177,18 @@ surface_constraint_data_new (MetaWaylandSurface *surface)
data = g_new0 (MetaWaylandSurfacePointerConstraintsData, 1);
+ data->surface = surface;
+
if (surface->window)
{
- data->window = surface->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);
+ connect_window (data, surface->window);
+ }
+ else if (meta_xwayland_is_xwayland_surface (surface))
+ {
+ data->window_associated_handler_id =
+ g_signal_connect (surface->role, "window-associated",
+ G_CALLBACK (window_associated),
+ data);
}
else
{
@@ -173,12 +211,24 @@ surface_constraint_data_free (MetaWaylandSurfacePointerConstraintsData *data)
g_object_remove_weak_pointer (G_OBJECT (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,
(GDestroyNotify) meta_wayland_pointer_constraint_destroy);
g_free (data);
}
+static void
+constrained_surface_destroyed (MetaWaylandSurface *surface,
+ MetaWaylandSurfacePointerConstraintsData *data)
+{
+ surface_constraint_data_free (data);
+}
+
static MetaWaylandSurfacePointerConstraintsData *
ensure_surface_constraints_data (MetaWaylandSurface *surface)
{
@@ -188,10 +238,11 @@ ensure_surface_constraints_data (MetaWaylandSurface *surface)
if (!data)
{
data = surface_constraint_data_new (surface);
- g_object_set_qdata_full (G_OBJECT (surface),
- quark_surface_pointer_constraints_data,
- data,
- (GDestroyNotify) surface_constraint_data_free);
+ g_object_set_qdata (G_OBJECT (surface),
+ quark_surface_pointer_constraints_data,
+ data);
+ g_signal_connect (surface, "destroy",
+ G_CALLBACK (constrained_surface_destroyed), data);
}
return data;
@@ -387,7 +438,11 @@ meta_wayland_pointer_constraint_maybe_enable (MetaWaylandPointerConstraint *cons
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;
}
@@ -454,6 +509,12 @@ meta_wayland_pointer_constraint_maybe_enable_for_window (MetaWindow *window)
MetaWaylandSurfacePointerConstraintsData *surface_data;
GList *l;
+ if (!surface)
+ {
+ g_warn_if_fail (window->client_type == META_WINDOW_CLIENT_TYPE_X11);
+ return;
+ }
+
surface_data = get_surface_constraints_data (surface);
if (!surface_data)
return;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]