[mutter] barriers: Make barriers fully part of the backend



commit 0debb24e12d7b2f60d489b31981019f5f7b9b508
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Mar 14 22:45:34 2022 +0100

    barriers: Make barriers fully part of the backend
    
    Prior to this commit, barriers were created with a MetaDisplay pointer,
    despite being entities related and owned by the backend. In the X11
    case, it was also not hooked up to the backend X11 connection, but the
    clutter one, meaning for example that the logic was active (but dormant)
    also for the Xwayland connection.
    
    Fix this by moving X11 barrier management and event processing fully to
    the backend. Also replace passing a display pointer with passing a
    backend pointer. Keep the display pointer around for a release, but mark
    it as deprecated.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2442>

 src/backends/meta-backend-private.h               |  8 ++
 src/backends/meta-backend-types.h                 |  3 +
 src/backends/meta-backend.c                       | 27 +++++++
 src/backends/meta-barrier-private.h               |  4 +-
 src/backends/meta-barrier.c                       | 69 +++++++++++++---
 src/backends/native/meta-backend-native.c         |  7 ++
 src/backends/native/meta-barrier-native.c         |  4 +-
 src/backends/x11/cm/meta-backend-x11-cm.c         | 16 ++++
 src/backends/x11/meta-backend-x11-types.h         | 28 +++++++
 src/backends/x11/meta-backend-x11.c               | 94 +++++++++++++++++-----
 src/backends/x11/meta-backend-x11.h               |  3 +
 src/backends/x11/meta-barrier-x11.c               | 97 ++++++++++++++---------
 src/backends/x11/meta-barrier-x11.h               |  8 ++
 src/backends/x11/nested/meta-backend-x11-nested.c |  7 ++
 src/core/display.c                                | 17 +---
 src/meta/display.h                                |  1 +
 src/meta/meta-backend.h                           |  9 +++
 src/x11/events.c                                  |  6 --
 src/x11/meta-x11-display-private.h                |  5 --
 src/x11/meta-x11-display.c                        | 16 +---
 20 files changed, 322 insertions(+), 107 deletions(-)
---
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index e9e94e044d..ce703dfa37 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -63,6 +63,8 @@ struct _MetaBackendClass
 
   void (* post_init) (MetaBackend *backend);
 
+  MetaBackendCapabilities (* get_capabilities) (MetaBackend *backend);
+
   MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
                                                    GError     **error);
   MetaCursorRenderer * (* get_cursor_renderer) (MetaBackend        *backend,
@@ -104,6 +106,9 @@ struct _MetaBackendClass
   void (* update_screen_size) (MetaBackend *backend, int width, int height);
   void (* select_stage_events) (MetaBackend *backend);
 
+  MetaBarrierImpl * (* create_barrier_impl) (MetaBackend *backend,
+                                             MetaBarrier *barrier);
+
   void (* set_pointer_constraint) (MetaBackend           *backend,
                                    MetaPointerConstraint *constraint);
 
@@ -162,6 +167,9 @@ xkb_layout_index_t meta_backend_get_keymap_layout_group (MetaBackend *backend);
 
 gboolean meta_backend_is_lid_closed (MetaBackend *backend);
 
+MetaBarrierImpl * meta_backend_create_barrier_impl (MetaBackend *backend,
+                                                    MetaBarrier *barrier);
+
 MetaPointerConstraint * meta_backend_get_client_pointer_constraint (MetaBackend *backend);
 void meta_backend_set_client_pointer_constraint (MetaBackend *backend,
                                                  MetaPointerConstraint *constraint);
diff --git a/src/backends/meta-backend-types.h b/src/backends/meta-backend-types.h
index 6febe4dfa3..9f4341bb0d 100644
--- a/src/backends/meta-backend-types.h
+++ b/src/backends/meta-backend-types.h
@@ -63,6 +63,9 @@ typedef struct _MetaVirtualMonitor MetaVirtualMonitor;
 typedef struct _MetaVirtualMonitorInfo MetaVirtualMonitorInfo;
 typedef struct _MetaVirtualModeInfo MetaVirtualModeInfo;
 
+typedef struct _MetaBarrier MetaBarrier;
+typedef struct _MetaBarrierImpl MetaBarrierImpl;
+
 typedef struct _MetaIdleManager MetaIdleManager;
 
 #ifdef HAVE_REMOTE_DESKTOP
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 84ea48442a..856b58e879 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -53,6 +53,7 @@
 
 #include <stdlib.h>
 
+#include "backends/meta-barrier-private.h"
 #include "backends/meta-cursor-renderer.h"
 #include "backends/meta-cursor-tracker-private.h"
 #include "backends/meta-idle-manager.h"
@@ -96,6 +97,7 @@ enum
   PROP_0,
 
   PROP_CONTEXT,
+  PROP_CAPABILITIES,
 
   N_PROPS
 };
@@ -845,6 +847,9 @@ meta_backend_get_property (GObject    *object,
     case PROP_CONTEXT:
       g_value_set_object (value, priv->context);
       break;
+    case PROP_CAPABILITIES:
+      g_value_set_flags (value, meta_backend_get_capabilities (backend));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -878,6 +883,14 @@ meta_backend_class_init (MetaBackendClass *klass)
                          G_PARAM_READWRITE |
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_CAPABILITIES] =
+    g_param_spec_flags ("capabilities",
+                        "capabilities",
+                        "Backend capabilities",
+                        META_TYPE_BACKEND_CAPABILITIES,
+                        META_BACKEND_CAPABILITY_NONE,
+                        G_PARAM_READABLE |
+                        G_PARAM_STATIC_STRINGS);
   g_object_class_install_properties (object_class, N_PROPS, obj_props);
 
   signals[KEYMAP_CHANGED] =
@@ -1548,6 +1561,14 @@ meta_backend_set_client_pointer_constraint (MetaBackend           *backend,
   g_set_object (&priv->client_pointer_constraint, constraint);
 }
 
+MetaBarrierImpl *
+meta_backend_create_barrier_impl (MetaBackend *backend,
+                                  MetaBarrier *barrier)
+{
+  return META_BACKEND_GET_CLASS (backend)->create_barrier_impl (backend,
+                                                                barrier);
+}
+
 ClutterBackend *
 meta_backend_get_clutter_backend (MetaBackend *backend)
 {
@@ -1567,6 +1588,12 @@ meta_backend_prepare_shutdown (MetaBackend *backend)
   g_signal_emit (backend, signals[PREPARE_SHUTDOWN], 0);
 }
 
+MetaBackendCapabilities
+meta_backend_get_capabilities (MetaBackend *backend)
+{
+  return META_BACKEND_GET_CLASS (backend)->get_capabilities (backend);
+}
+
 /**
  * meta_is_stage_views_enabled:
  *
diff --git a/src/backends/meta-barrier-private.h b/src/backends/meta-barrier-private.h
index dd68c4f1df..16bfcdcd0d 100644
--- a/src/backends/meta-barrier-private.h
+++ b/src/backends/meta-barrier-private.h
@@ -54,11 +54,13 @@ void meta_barrier_emit_left_signal (MetaBarrier      *barrier,
 
 void meta_barrier_event_unref (MetaBarrierEvent *event);
 
+MetaBackend * meta_barrier_get_backend (MetaBarrier *barrier);
+
 G_END_DECLS
 
 struct _MetaBarrierPrivate
 {
-  MetaDisplay *display;
+  MetaBackend *backend;
   MetaBorder border;
   MetaBarrierImpl *impl;
 };
diff --git a/src/backends/meta-barrier.c b/src/backends/meta-barrier.c
index 2f892f4e3a..777287cc99 100644
--- a/src/backends/meta-barrier.c
+++ b/src/backends/meta-barrier.c
@@ -39,6 +39,7 @@ enum
 {
   PROP_0,
 
+  PROP_BACKEND,
   PROP_DISPLAY,
 
   PROP_X1,
@@ -62,6 +63,21 @@ enum
 
 static guint obj_signals[LAST_SIGNAL];
 
+static MetaBackend *
+backend_from_display (MetaDisplay *display)
+{
+  MetaContext *context = meta_display_get_context (display);
+
+  return meta_context_get_backend (context);
+}
+
+static MetaDisplay *
+display_from_backend (MetaBackend *backend)
+{
+  MetaContext *context = meta_backend_get_context (backend);
+
+  return meta_context_get_display (context);
+}
 
 static void
 meta_barrier_get_property (GObject    *object,
@@ -71,10 +87,14 @@ meta_barrier_get_property (GObject    *object,
 {
   MetaBarrier *barrier = META_BARRIER (object);
   MetaBarrierPrivate *priv = barrier->priv;
+
   switch (prop_id)
     {
+    case PROP_BACKEND:
+      g_value_set_object (value, priv->backend);
+      break;
     case PROP_DISPLAY:
-      g_value_set_object (value, priv->display);
+      g_value_set_object (value, display_from_backend (priv->backend));
       break;
     case PROP_X1:
       g_value_set_int (value, priv->border.line.a.x);
@@ -108,9 +128,18 @@ meta_barrier_set_property (GObject      *object,
   MetaBarrierPrivate *priv = barrier->priv;
   switch (prop_id)
     {
-    case PROP_DISPLAY:
-      priv->display = g_value_get_object (value);
+    case PROP_BACKEND:
+      priv->backend = g_value_get_object (value);
       break;
+    case PROP_DISPLAY:
+      {
+        MetaDisplay *display;
+
+        display = g_value_get_object (value);
+        if (display)
+          priv->backend = backend_from_display (g_value_get_object (value));
+        break;
+      }
     case PROP_X1:
       priv->border.line.a.x = g_value_get_int (value);
       break;
@@ -182,11 +211,11 @@ meta_barrier_release (MetaBarrier      *barrier,
 }
 
 static void
-meta_barrier_constructed (GObject *object)
+init_barrier_impl (MetaBarrier *barrier)
 {
-  MetaBarrier *barrier = META_BARRIER (object);
   MetaBarrierPrivate *priv = barrier->priv;
 
+  g_return_if_fail (priv->backend);
   g_return_if_fail (priv->border.line.a.x == priv->border.line.b.x ||
                     priv->border.line.a.y == priv->border.line.b.y);
   g_return_if_fail (priv->border.line.a.x >= 0);
@@ -195,15 +224,22 @@ meta_barrier_constructed (GObject *object)
   g_return_if_fail (priv->border.line.b.y >= 0);
 
 #if defined(HAVE_NATIVE_BACKEND)
-  if (META_IS_BACKEND_NATIVE (meta_get_backend ()))
+  if (META_IS_BACKEND_NATIVE (priv->backend))
     priv->impl = meta_barrier_impl_native_new (barrier);
 #endif
-  if (META_IS_BACKEND_X11 (meta_get_backend ()) &&
+  if (META_IS_BACKEND_X11 (priv->backend) &&
       !meta_is_wayland_compositor ())
     priv->impl = meta_barrier_impl_x11_new (barrier);
 
-  if (priv->impl == NULL)
-    g_warning ("Created a non-working barrier");
+  g_warn_if_fail (priv->impl);
+}
+
+static void
+meta_barrier_constructed (GObject *object)
+{
+  MetaBarrier *barrier = META_BARRIER (object);
+
+  init_barrier_impl (barrier);
 
   /* Take a ref that we'll release in destroy() so that the object stays
    * alive while active. */
@@ -222,11 +258,20 @@ meta_barrier_class_init (MetaBarrierClass *klass)
   object_class->dispose = meta_barrier_dispose;
   object_class->constructed = meta_barrier_constructed;
 
+  obj_props[PROP_BACKEND] =
+    g_param_spec_object ("backend",
+                         "backend",
+                         "The backend",
+                         META_TYPE_BACKEND,
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
   obj_props[PROP_DISPLAY] =
     g_param_spec_object ("display",
                          "Display",
                          "The display to construct the pointer barrier on",
                          META_TYPE_DISPLAY,
+                         G_PARAM_DEPRECATED |
                          G_PARAM_READWRITE |
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_STRINGS);
@@ -347,6 +392,12 @@ meta_barrier_emit_left_signal (MetaBarrier      *barrier,
   g_signal_emit (barrier, obj_signals[LEFT], 0, event);
 }
 
+MetaBackend *
+meta_barrier_get_backend (MetaBarrier *barrier)
+{
+  return barrier->priv->backend;
+}
+
 static void
 meta_barrier_impl_class_init (MetaBarrierImplClass *klass)
 {
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index eb5687375c..8c6658cc91 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -251,6 +251,12 @@ meta_backend_native_post_init (MetaBackend *backend)
   update_viewports (backend);
 }
 
+static MetaBackendCapabilities
+meta_backend_native_get_capabilities (MetaBackend *backend)
+{
+  return META_BACKEND_CAPABILITY_BARRIERS;
+}
+
 static MetaMonitorManager *
 meta_backend_native_create_monitor_manager (MetaBackend *backend,
                                             GError     **error)
@@ -680,6 +686,7 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
   backend_class->create_default_seat = meta_backend_native_create_default_seat;
 
   backend_class->post_init = meta_backend_native_post_init;
+  backend_class->get_capabilities = meta_backend_native_get_capabilities;
 
   backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
   backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer;
diff --git a/src/backends/native/meta-barrier-native.c b/src/backends/native/meta-barrier-native.c
index 47463e4aa0..63acb6a796 100644
--- a/src/backends/native/meta-barrier-native.c
+++ b/src/backends/native/meta-barrier-native.c
@@ -606,10 +606,10 @@ meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
 MetaBarrierImpl *
 meta_barrier_impl_native_new (MetaBarrier *barrier)
 {
+  MetaBackend *backend = meta_barrier_get_backend (barrier);
+  ClutterSeat *seat = meta_backend_get_default_seat (backend);
   MetaBarrierImplNative *self;
   MetaBarrierManagerNative *manager;
-  ClutterBackend *backend = clutter_get_default_backend ();
-  ClutterSeat *seat = clutter_backend_get_default_seat (backend);
 
   self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
 
diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c
index ed2b7bb8bb..c6a8d6c0e9 100644
--- a/src/backends/x11/cm/meta-backend-x11-cm.c
+++ b/src/backends/x11/cm/meta-backend-x11-cm.c
@@ -28,6 +28,7 @@
 
 #include "backends/meta-backend-private.h"
 #include "backends/meta-dnd-private.h"
+#include "backends/x11/meta-barrier-x11.h"
 #include "backends/x11/meta-cursor-renderer-x11.h"
 #include "backends/x11/meta-cursor-tracker-x11.h"
 #include "backends/x11/meta-gpu-xrandr.h"
@@ -115,6 +116,20 @@ meta_backend_x11_cm_post_init (MetaBackend *backend)
   take_touch_grab (backend);
 }
 
+static MetaBackendCapabilities
+meta_backend_x11_cm_get_capabilities (MetaBackend *backend)
+{
+  MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
+  MetaBackendCapabilities capabilities = META_BACKEND_CAPABILITY_NONE;
+  MetaX11Barriers *barriers;
+
+  barriers = meta_backend_x11_get_barriers (backend_x11);
+  if (barriers)
+    capabilities |= META_BACKEND_CAPABILITY_BARRIERS;
+
+  return capabilities;
+}
+
 static MetaRenderer *
 meta_backend_x11_cm_create_renderer (MetaBackend *backend,
                                      GError     **error)
@@ -523,6 +538,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
   object_class->constructed = meta_backend_x11_cm_constructed;
 
   backend_class->post_init = meta_backend_x11_cm_post_init;
+  backend_class->get_capabilities = meta_backend_x11_cm_get_capabilities;
   backend_class->create_renderer = meta_backend_x11_cm_create_renderer;
   backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
   backend_class->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer;
diff --git a/src/backends/x11/meta-backend-x11-types.h b/src/backends/x11/meta-backend-x11-types.h
new file mode 100644
index 0000000000..86818efbfa
--- /dev/null
+++ b/src/backends/x11/meta-backend-x11-types.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2022 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#ifndef META_BACKEND_X11_TYPES_H
+#define META_BACKEND_X11_TYPES_H
+
+typedef struct _MetaBackendX11 MetaBackendX11;
+
+typedef struct _MetaX11Barriers MetaX11Barriers;
+
+#endif /* META_BACKEND_X11_TYPES_H */
diff --git a/src/backends/x11/meta-backend-x11.c b/src/backends/x11/meta-backend-x11.c
index 969b64dddb..da14cd73a2 100644
--- a/src/backends/x11/meta-backend-x11.c
+++ b/src/backends/x11/meta-backend-x11.c
@@ -45,6 +45,7 @@
 #include "backends/meta-idle-monitor-private.h"
 #include "backends/meta-keymap-utils.h"
 #include "backends/meta-stage-private.h"
+#include "backends/x11/meta-barrier-x11.h"
 #include "backends/x11/meta-clutter-backend-x11.h"
 #include "backends/x11/meta-event-x11.h"
 #include "backends/x11/meta-seat-x11.h"
@@ -79,6 +80,7 @@ struct _MetaBackendX11Private
   int xinput_event_base;
   int xinput_error_base;
   Time latest_evtime;
+  gboolean have_xinput_23;
 
   uint8_t xkb_event_base;
   uint8_t xkb_error_base;
@@ -89,6 +91,8 @@ struct _MetaBackendX11Private
   xkb_layout_index_t keymap_layout_group;
 
   MetaLogicalMonitor *cached_current_logical_monitor;
+
+  MetaX11Barriers *barriers;
 };
 typedef struct _MetaBackendX11Private MetaBackendX11Private;
 
@@ -286,7 +290,7 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
     }
 }
 
-static void
+static gboolean
 handle_input_event (MetaBackendX11 *x11,
                     XEvent         *event)
 {
@@ -296,9 +300,17 @@ handle_input_event (MetaBackendX11 *x11,
       event->xcookie.extension == priv->xinput_opcode)
     {
       XIEvent *input_event = (XIEvent *) event->xcookie.data;
+      MetaX11Barriers *barriers;
+
+      barriers = meta_backend_x11_get_barriers (x11);
+      if (barriers &&
+          meta_x11_barriers_process_xevent (barriers, input_event))
+        return TRUE;
 
       maybe_spoof_event_as_stage_event (x11, input_event);
     }
+
+  return FALSE;
 }
 
 static void
@@ -401,10 +413,13 @@ handle_host_xevent (MetaBackend *backend,
 
   if (!bypass_clutter)
     {
-      handle_input_event (x11, event);
+      if (handle_input_event (x11, event))
+        goto done;
+
       meta_x11_handle_event (backend, event);
     }
 
+done:
   XFreeEventData (priv->xdisplay, &event->xcookie);
 }
 
@@ -518,7 +533,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
   ClutterSeat *seat;
   MetaInputSettings *input_settings;
   int major, minor;
-  gboolean has_xi = FALSE;
 
   priv->source = x_event_source_new (backend);
 
@@ -532,24 +546,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
 
   priv->user_active_alarm = xsync_user_active_alarm_set (priv);
 
-  if (XQueryExtension (priv->xdisplay,
-                       "XInputExtension",
-                       &priv->xinput_opcode,
-                       &priv->xinput_error_base,
-                       &priv->xinput_event_base))
-    {
-      major = 2; minor = 3;
-      if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
-        {
-          int version = (major * 10) + minor;
-          if (version >= 22)
-            has_xi = TRUE;
-        }
-    }
-
-  if (!has_xi)
-    meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer");
-
   if (!xkb_x11_setup_xkb_extension (priv->xcb,
                                     XKB_X11_MIN_MAJOR_XKB_VERSION,
                                     XKB_X11_MIN_MINOR_XKB_VERSION,
@@ -816,6 +812,47 @@ init_xkb_state (MetaBackendX11 *x11)
   xkb_state_unref (state);
 }
 
+static gboolean
+init_xinput (MetaBackendX11  *backend_x11,
+             GError         **error)
+{
+  MetaBackendX11Private *priv =
+    meta_backend_x11_get_instance_private (backend_x11);
+  gboolean has_xi = FALSE;
+
+  if (XQueryExtension (priv->xdisplay,
+                       "XInputExtension",
+                       &priv->xinput_opcode,
+                       &priv->xinput_error_base,
+                       &priv->xinput_event_base))
+    {
+      int major, minor;
+
+      major = 2; minor = 3;
+      if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
+        {
+          int version;
+
+          version = (major * 10) + minor;
+          if (version >= 22)
+            has_xi = TRUE;
+
+          if (version >= 23)
+            priv->have_xinput_23 = TRUE;
+        }
+    }
+
+  if (!has_xi)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "X server doesn't have the XInput extension, "
+                   "version 2.2 or newer");
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static gboolean
 meta_backend_x11_initable_init (GInitable    *initable,
                                 GCancellable *cancellable,
@@ -852,6 +889,12 @@ meta_backend_x11_initable_init (GInitable    *initable,
 
   init_xkb_state (x11);
 
+  if (!init_xinput (x11, error))
+    return FALSE;
+
+  if (priv->have_xinput_23)
+    priv->barriers = meta_x11_barriers_new (x11);
+
   return initable_parent_iface->init (initable, cancellable, error);
 }
 
@@ -992,3 +1035,12 @@ meta_backend_x11_sync_pointer (MetaBackendX11 *backend_x11)
   clutter_event_put (event);
   clutter_event_free (event);
 }
+
+MetaX11Barriers *
+meta_backend_x11_get_barriers (MetaBackendX11 *backend_x11)
+{
+  MetaBackendX11Private *priv =
+    meta_backend_x11_get_instance_private (backend_x11);
+
+  return priv->barriers;
+}
diff --git a/src/backends/x11/meta-backend-x11.h b/src/backends/x11/meta-backend-x11.h
index 515cde91b4..748ab3c119 100644
--- a/src/backends/x11/meta-backend-x11.h
+++ b/src/backends/x11/meta-backend-x11.h
@@ -29,6 +29,7 @@
 #include <X11/Xlib.h>
 
 #include "backends/meta-backend-private.h"
+#include "backends/x11/meta-backend-x11-types.h"
 #include "backends/x11/meta-clutter-backend-x11.h"
 
 #define META_TYPE_BACKEND_X11 (meta_backend_x11_get_type ())
@@ -64,4 +65,6 @@ void meta_backend_x11_reload_cursor (MetaBackendX11 *x11);
 
 void meta_backend_x11_sync_pointer (MetaBackendX11 *backend_x11);
 
+MetaX11Barriers * meta_backend_x11_get_barriers (MetaBackendX11 *backend_x11);
+
 #endif /* META_BACKEND_X11_H */
diff --git a/src/backends/x11/meta-barrier-x11.c b/src/backends/x11/meta-barrier-x11.c
index ebbf1dabb0..8be0c97188 100644
--- a/src/backends/x11/meta-barrier-x11.c
+++ b/src/backends/x11/meta-barrier-x11.c
@@ -35,11 +35,17 @@
 #include <X11/extensions/XInput2.h>
 #include <X11/extensions/Xfixes.h>
 
+#include "backends/x11/meta-backend-x11.h"
 #include "backends/x11/meta-barrier-x11.h"
 #include "core/display-private.h"
 #include "meta/barrier.h"
 #include "x11/meta-x11-display-private.h"
 
+struct _MetaX11Barriers
+{
+  GHashTable *barriers;
+};
+
 struct _MetaBarrierImplX11
 {
   MetaBarrierImpl parent;
@@ -65,34 +71,29 @@ meta_barrier_impl_x11_release (MetaBarrierImpl  *impl,
                                MetaBarrierEvent *event)
 {
   MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
-  MetaDisplay *display = self->barrier->priv->display;
-  Display *dpy = meta_x11_display_get_xdisplay (display->x11_display);
+  MetaBackend *backend = self->barrier->priv->backend;
+  MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
+  Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
 
-  if (META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display))
-    {
-      XIBarrierReleasePointer (dpy,
-                               META_VIRTUAL_CORE_POINTER_ID,
-                               self->xbarrier, event->event_id);
-    }
+  XIBarrierReleasePointer (xdisplay,
+                           META_VIRTUAL_CORE_POINTER_ID,
+                           self->xbarrier, event->event_id);
 }
 
 static void
 meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl)
 {
   MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
-  MetaDisplay *display = self->barrier->priv->display;
-  Display *dpy;
-
-  if (display == NULL)
-    return;
-
-  dpy = meta_x11_display_get_xdisplay (display->x11_display);
+  MetaBackend *backend = self->barrier->priv->backend;
+  MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
+  MetaX11Barriers *barriers = meta_backend_x11_get_barriers (backend_x11);
+  Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
 
   if (!meta_barrier_is_active (self->barrier))
     return;
 
-  XFixesDestroyPointerBarrier (dpy, self->xbarrier);
-  g_hash_table_remove (display->x11_display->xids, &self->xbarrier);
+  XFixesDestroyPointerBarrier (xdisplay, self->xbarrier);
+  g_hash_table_remove (barriers->barriers, &self->xbarrier);
   self->xbarrier = 0;
 }
 
@@ -100,26 +101,24 @@ MetaBarrierImpl *
 meta_barrier_impl_x11_new (MetaBarrier *barrier)
 {
   MetaBarrierImplX11 *self;
-  MetaDisplay *display = barrier->priv->display;
-  Display *dpy;
+  MetaBackend *backend;
+  MetaBackendX11 *backend_x11;
+  MetaX11Barriers *barriers;
+  Display *xdisplay;
   Window root;
   unsigned int allowed_motion_dirs;
 
-  if (display == NULL)
-    {
-      g_warning ("A display must be provided when constructing a barrier.");
-      return NULL;
-    }
-
   self = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL);
   self->barrier = barrier;
 
-  dpy = meta_x11_display_get_xdisplay (display->x11_display);
-  root = DefaultRootWindow (dpy);
+  backend = self->barrier->priv->backend;
+  backend_x11 = META_BACKEND_X11 (backend);
+  xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
+  root = DefaultRootWindow (xdisplay);
 
   allowed_motion_dirs =
     meta_border_get_allows_directions (&barrier->priv->border);
-  self->xbarrier = XFixesCreatePointerBarrier (dpy, root,
+  self->xbarrier = XFixesCreatePointerBarrier (xdisplay, root,
                                                barrier->priv->border.line.a.x,
                                                barrier->priv->border.line.a.y,
                                                barrier->priv->border.line.b.x,
@@ -127,7 +126,8 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
                                                allowed_motion_dirs,
                                                0, NULL);
 
-  g_hash_table_insert (display->x11_display->xids, &self->xbarrier, barrier);
+  barriers = meta_backend_x11_get_barriers (backend_x11);
+  g_hash_table_insert (barriers->barriers, &self->xbarrier, barrier);
 
   return META_BARRIER_IMPL (self);
 }
@@ -167,15 +167,12 @@ meta_barrier_fire_xevent (MetaBarrier    *barrier,
 }
 
 gboolean
-meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display,
-                                         XIEvent        *event)
+meta_x11_barriers_process_xevent (MetaX11Barriers *barriers,
+                                  XIEvent         *event)
 {
   MetaBarrier *barrier;
   XIBarrierEvent *xev;
 
-  if (event == NULL)
-    return FALSE;
-
   switch (event->evtype)
     {
     case XI_BarrierHit:
@@ -186,8 +183,8 @@ meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display,
     }
 
   xev = (XIBarrierEvent *) event;
-  barrier = g_hash_table_lookup (x11_display->xids, &xev->barrier);
-  if (barrier != NULL)
+  barrier = g_hash_table_lookup (barriers->barriers, &xev->barrier);
+  if (barrier)
     {
       meta_barrier_fire_xevent (barrier, xev);
       return TRUE;
@@ -210,3 +207,31 @@ static void
 meta_barrier_impl_x11_init (MetaBarrierImplX11 *self)
 {
 }
+
+MetaX11Barriers *
+meta_x11_barriers_new (MetaBackendX11 *backend_x11)
+{
+  Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
+  Window root = meta_backend_x11_get_root_xwindow (backend_x11);
+  MetaX11Barriers *x11_barriers;
+  unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = {};
+  XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
+
+  x11_barriers = g_new0 (MetaX11Barriers, 1);
+  x11_barriers->barriers = g_hash_table_new (meta_unsigned_long_hash,
+                                             meta_unsigned_long_equal);
+
+  XISetMask (mask.mask, XI_BarrierHit);
+  XISetMask (mask.mask, XI_BarrierLeave);
+  XISelectEvents (xdisplay, root, &mask, 1);
+
+  return x11_barriers;
+}
+
+void
+meta_x11_barriers_free (MetaX11Barriers *x11_barriers)
+{
+  g_assert (g_hash_table_size (x11_barriers->barriers) == 0);
+  g_hash_table_unref (x11_barriers->barriers);
+  g_free (x11_barriers);
+}
diff --git a/src/backends/x11/meta-barrier-x11.h b/src/backends/x11/meta-barrier-x11.h
index 3562d106f5..ae50fdccab 100644
--- a/src/backends/x11/meta-barrier-x11.h
+++ b/src/backends/x11/meta-barrier-x11.h
@@ -26,6 +26,7 @@
 #define META_BARRIER_X11_H
 
 #include "backends/meta-barrier-private.h"
+#include "backends/x11/meta-backend-x11-types.h"
 
 G_BEGIN_DECLS
 
@@ -37,6 +38,13 @@ G_DECLARE_FINAL_TYPE (MetaBarrierImplX11,
 
 MetaBarrierImpl *meta_barrier_impl_x11_new (MetaBarrier *barrier);
 
+MetaX11Barriers * meta_x11_barriers_new (MetaBackendX11 *backend_x11);
+
+void meta_x11_barriers_free (MetaX11Barriers *x11_barriers);
+
+gboolean meta_x11_barriers_process_xevent (MetaX11Barriers *barriers,
+                                           XIEvent         *event);
+
 G_END_DECLS
 
 #endif /* META_BARRIER_X11_H1 */
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c 
b/src/backends/x11/nested/meta-backend-x11-nested.c
index 041b42860b..0f38f4ad21 100644
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
@@ -245,6 +245,12 @@ meta_backend_x11_nested_post_init (MetaBackend *backend)
   backend_class->post_init (backend);
 }
 
+static MetaBackendCapabilities
+meta_backend_x11_nested_get_capabilities (MetaBackend *backend)
+{
+  return META_BACKEND_CAPABILITY_NONE;
+}
+
 static gboolean
 meta_backend_x11_nested_initable_init (GInitable     *initable,
                                        GCancellable  *cancellable,
@@ -303,6 +309,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
   object_class->dispose = meta_backend_x11_nested_dispose;
 
   backend_class->post_init = meta_backend_x11_nested_post_init;
+  backend_class->get_capabilities = meta_backend_x11_nested_get_capabilities;
   backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
   backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
   backend_class->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer;
diff --git a/src/core/display.c b/src/core/display.c
index ee1c372bf8..5bb34a65ab 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2826,20 +2826,11 @@ meta_display_modifiers_accelerator_activate (MetaDisplay *display)
 gboolean
 meta_display_supports_extended_barriers (MetaDisplay *display)
 {
-#ifdef HAVE_NATIVE_BACKEND
-  if (META_IS_BACKEND_NATIVE (meta_get_backend ()))
-    return TRUE;
-#endif
-
-  if (META_IS_BACKEND_X11_CM (meta_get_backend ()))
-    {
-      if (meta_is_wayland_compositor())
-        return FALSE;
-
-      return META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display);
-    }
+  MetaContext *context = meta_display_get_context (display);
+  MetaBackend *backend = meta_context_get_backend (context);
 
-  return FALSE;
+  return !!(meta_backend_get_capabilities (backend) &
+            META_BACKEND_CAPABILITY_BARRIERS);
 }
 
 /**
diff --git a/src/meta/display.h b/src/meta/display.h
index e59bd03939..206e08c0c0 100644
--- a/src/meta/display.h
+++ b/src/meta/display.h
@@ -78,6 +78,7 @@ GType meta_display_get_type (void) G_GNUC_CONST;
 #define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
 
 META_EXPORT
+G_DEPRECATED_FOR (meta_backend_get_capabilities)
 gboolean meta_display_supports_extended_barriers (MetaDisplay *display);
 
 META_EXPORT
diff --git a/src/meta/meta-backend.h b/src/meta/meta-backend.h
index cfb042a726..05fb47234f 100644
--- a/src/meta/meta-backend.h
+++ b/src/meta/meta-backend.h
@@ -33,6 +33,12 @@
 #include "meta/meta-monitor-manager.h"
 #include "meta/meta-remote-access-controller.h"
 
+typedef enum _MetaBackendCapabilities
+{
+  META_BACKEND_CAPABILITY_NONE = 0,
+  META_BACKEND_CAPABILITY_BARRIERS = 1 << 0,
+} MetaBackendCapabilities;
+
 #define META_TYPE_BACKEND (meta_backend_get_type ())
 META_EXPORT
 G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject)
@@ -77,6 +83,9 @@ gboolean meta_backend_is_rendering_hardware_accelerated (MetaBackend *backend);
 META_EXPORT
 gboolean meta_backend_is_headless (MetaBackend *backend);
 
+META_EXPORT
+MetaBackendCapabilities meta_backend_get_capabilities (MetaBackend *backend);
+
 META_EXPORT
 void meta_clutter_init (void);
 
diff --git a/src/x11/events.c b/src/x11/events.c
index 2c574d5755..c7caaf725d 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -1964,12 +1964,6 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
         }
     }
 
-  if (meta_x11_display_process_barrier_xevent (x11_display, input_event))
-    {
-      bypass_gtk = bypass_compositor = TRUE;
-      goto out;
-    }
-
   if (handle_input_xevent (x11_display, input_event, event->xany.serial))
     {
       bypass_gtk = bypass_compositor = TRUE;
diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h
index d53073e111..9158387d69 100644
--- a/src/x11/meta-x11-display-private.h
+++ b/src/x11/meta-x11-display-private.h
@@ -175,8 +175,6 @@ struct _MetaX11Display
   unsigned int have_damage : 1;
 #define META_X11_DISPLAY_HAS_COMPOSITE(x11_display) ((x11_display)->have_composite)
 #define META_X11_DISPLAY_HAS_DAMAGE(x11_display) ((x11_display)->have_damage)
-  gboolean have_xinput_23 : 1;
-#define META_X11_DISPLAY_HAS_XINPUT_23(x11_display) ((x11_display)->have_xinput_23)
 
   MetaX11StartupNotification *startup_notification;
   MetaX11Stack *x11_stack;
@@ -213,9 +211,6 @@ void        meta_x11_display_register_sync_alarm   (MetaX11Display *x11_display,
 void        meta_x11_display_unregister_sync_alarm (MetaX11Display *x11_display,
                                                     XSyncAlarm      alarm);
 
-gboolean meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display,
-                                                  XIEvent        *event);
-
 META_EXPORT
 void meta_x11_display_set_alarm_filter (MetaX11Display *x11_display,
                                         MetaAlarmFilter filter,
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index bb5f4bf50b..3139246ccf 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -429,15 +429,8 @@ query_xi_extension (MetaX11Display *x11_display)
                        &x11_display->xinput_error_base,
                        &x11_display->xinput_event_base))
     {
-        if (XIQueryVersion (x11_display->xdisplay, &major, &minor) == Success)
-        {
-          int version = (major * 10) + minor;
-          if (version >= 22)
-            has_xi = TRUE;
-
-          if (version >= 23)
-            x11_display->have_xinput_23 = TRUE;
-        }
+      if (XIQueryVersion (x11_display->xdisplay, &major, &minor) == Success)
+        has_xi = TRUE;
     }
 
   if (!has_xi)
@@ -792,11 +785,6 @@ init_event_masks (MetaX11Display *x11_display)
   XISetMask (mask.mask, XI_Leave);
   XISetMask (mask.mask, XI_FocusIn);
   XISetMask (mask.mask, XI_FocusOut);
-  if (META_X11_DISPLAY_HAS_XINPUT_23 (x11_display))
-    {
-      XISetMask (mask.mask, XI_BarrierHit);
-      XISetMask (mask.mask, XI_BarrierLeave);
-    }
   XISelectEvents (x11_display->xdisplay, x11_display->xroot, &mask, 1);
 
   event_mask = (SubstructureRedirectMask | SubstructureNotifyMask |


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]