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>
This commit is contained in:
Jonas Ådahl 2022-03-14 22:45:34 +01:00 committed by Marge Bot
parent 877dc33545
commit 0debb24e12
20 changed files with 322 additions and 107 deletions

View File

@ -63,6 +63,8 @@ struct _MetaBackendClass
void (* post_init) (MetaBackend *backend); void (* post_init) (MetaBackend *backend);
MetaBackendCapabilities (* get_capabilities) (MetaBackend *backend);
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend, MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
GError **error); GError **error);
MetaCursorRenderer * (* get_cursor_renderer) (MetaBackend *backend, MetaCursorRenderer * (* get_cursor_renderer) (MetaBackend *backend,
@ -104,6 +106,9 @@ struct _MetaBackendClass
void (* update_screen_size) (MetaBackend *backend, int width, int height); void (* update_screen_size) (MetaBackend *backend, int width, int height);
void (* select_stage_events) (MetaBackend *backend); void (* select_stage_events) (MetaBackend *backend);
MetaBarrierImpl * (* create_barrier_impl) (MetaBackend *backend,
MetaBarrier *barrier);
void (* set_pointer_constraint) (MetaBackend *backend, void (* set_pointer_constraint) (MetaBackend *backend,
MetaPointerConstraint *constraint); 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); 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); MetaPointerConstraint * meta_backend_get_client_pointer_constraint (MetaBackend *backend);
void meta_backend_set_client_pointer_constraint (MetaBackend *backend, void meta_backend_set_client_pointer_constraint (MetaBackend *backend,
MetaPointerConstraint *constraint); MetaPointerConstraint *constraint);

View File

@ -63,6 +63,9 @@ typedef struct _MetaVirtualMonitor MetaVirtualMonitor;
typedef struct _MetaVirtualMonitorInfo MetaVirtualMonitorInfo; typedef struct _MetaVirtualMonitorInfo MetaVirtualMonitorInfo;
typedef struct _MetaVirtualModeInfo MetaVirtualModeInfo; typedef struct _MetaVirtualModeInfo MetaVirtualModeInfo;
typedef struct _MetaBarrier MetaBarrier;
typedef struct _MetaBarrierImpl MetaBarrierImpl;
typedef struct _MetaIdleManager MetaIdleManager; typedef struct _MetaIdleManager MetaIdleManager;
#ifdef HAVE_REMOTE_DESKTOP #ifdef HAVE_REMOTE_DESKTOP

View File

@ -53,6 +53,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "backends/meta-barrier-private.h"
#include "backends/meta-cursor-renderer.h" #include "backends/meta-cursor-renderer.h"
#include "backends/meta-cursor-tracker-private.h" #include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-idle-manager.h" #include "backends/meta-idle-manager.h"
@ -96,6 +97,7 @@ enum
PROP_0, PROP_0,
PROP_CONTEXT, PROP_CONTEXT,
PROP_CAPABILITIES,
N_PROPS N_PROPS
}; };
@ -845,6 +847,9 @@ meta_backend_get_property (GObject *object,
case PROP_CONTEXT: case PROP_CONTEXT:
g_value_set_object (value, priv->context); g_value_set_object (value, priv->context);
break; break;
case PROP_CAPABILITIES:
g_value_set_flags (value, meta_backend_get_capabilities (backend));
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -878,6 +883,14 @@ meta_backend_class_init (MetaBackendClass *klass)
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS); 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); g_object_class_install_properties (object_class, N_PROPS, obj_props);
signals[KEYMAP_CHANGED] = signals[KEYMAP_CHANGED] =
@ -1548,6 +1561,14 @@ meta_backend_set_client_pointer_constraint (MetaBackend *backend,
g_set_object (&priv->client_pointer_constraint, constraint); 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 * ClutterBackend *
meta_backend_get_clutter_backend (MetaBackend *backend) 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); 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: * meta_is_stage_views_enabled:
* *

View File

@ -54,11 +54,13 @@ void meta_barrier_emit_left_signal (MetaBarrier *barrier,
void meta_barrier_event_unref (MetaBarrierEvent *event); void meta_barrier_event_unref (MetaBarrierEvent *event);
MetaBackend * meta_barrier_get_backend (MetaBarrier *barrier);
G_END_DECLS G_END_DECLS
struct _MetaBarrierPrivate struct _MetaBarrierPrivate
{ {
MetaDisplay *display; MetaBackend *backend;
MetaBorder border; MetaBorder border;
MetaBarrierImpl *impl; MetaBarrierImpl *impl;
}; };

View File

@ -39,6 +39,7 @@ enum
{ {
PROP_0, PROP_0,
PROP_BACKEND,
PROP_DISPLAY, PROP_DISPLAY,
PROP_X1, PROP_X1,
@ -62,6 +63,21 @@ enum
static guint obj_signals[LAST_SIGNAL]; 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 static void
meta_barrier_get_property (GObject *object, meta_barrier_get_property (GObject *object,
@ -71,10 +87,14 @@ meta_barrier_get_property (GObject *object,
{ {
MetaBarrier *barrier = META_BARRIER (object); MetaBarrier *barrier = META_BARRIER (object);
MetaBarrierPrivate *priv = barrier->priv; MetaBarrierPrivate *priv = barrier->priv;
switch (prop_id) switch (prop_id)
{ {
case PROP_BACKEND:
g_value_set_object (value, priv->backend);
break;
case PROP_DISPLAY: case PROP_DISPLAY:
g_value_set_object (value, priv->display); g_value_set_object (value, display_from_backend (priv->backend));
break; break;
case PROP_X1: case PROP_X1:
g_value_set_int (value, priv->border.line.a.x); g_value_set_int (value, priv->border.line.a.x);
@ -108,9 +128,18 @@ meta_barrier_set_property (GObject *object,
MetaBarrierPrivate *priv = barrier->priv; MetaBarrierPrivate *priv = barrier->priv;
switch (prop_id) switch (prop_id)
{ {
case PROP_DISPLAY: case PROP_BACKEND:
priv->display = g_value_get_object (value); priv->backend = g_value_get_object (value);
break; 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: case PROP_X1:
priv->border.line.a.x = g_value_get_int (value); priv->border.line.a.x = g_value_get_int (value);
break; break;
@ -182,11 +211,11 @@ meta_barrier_release (MetaBarrier *barrier,
} }
static void static void
meta_barrier_constructed (GObject *object) init_barrier_impl (MetaBarrier *barrier)
{ {
MetaBarrier *barrier = META_BARRIER (object);
MetaBarrierPrivate *priv = barrier->priv; MetaBarrierPrivate *priv = barrier->priv;
g_return_if_fail (priv->backend);
g_return_if_fail (priv->border.line.a.x == priv->border.line.b.x || g_return_if_fail (priv->border.line.a.x == priv->border.line.b.x ||
priv->border.line.a.y == priv->border.line.b.y); priv->border.line.a.y == priv->border.line.b.y);
g_return_if_fail (priv->border.line.a.x >= 0); 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); g_return_if_fail (priv->border.line.b.y >= 0);
#if defined(HAVE_NATIVE_BACKEND) #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); priv->impl = meta_barrier_impl_native_new (barrier);
#endif #endif
if (META_IS_BACKEND_X11 (meta_get_backend ()) && if (META_IS_BACKEND_X11 (priv->backend) &&
!meta_is_wayland_compositor ()) !meta_is_wayland_compositor ())
priv->impl = meta_barrier_impl_x11_new (barrier); priv->impl = meta_barrier_impl_x11_new (barrier);
if (priv->impl == NULL) g_warn_if_fail (priv->impl);
g_warning ("Created a non-working barrier"); }
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 /* Take a ref that we'll release in destroy() so that the object stays
* alive while active. */ * alive while active. */
@ -222,11 +258,20 @@ meta_barrier_class_init (MetaBarrierClass *klass)
object_class->dispose = meta_barrier_dispose; object_class->dispose = meta_barrier_dispose;
object_class->constructed = meta_barrier_constructed; 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] = obj_props[PROP_DISPLAY] =
g_param_spec_object ("display", g_param_spec_object ("display",
"Display", "Display",
"The display to construct the pointer barrier on", "The display to construct the pointer barrier on",
META_TYPE_DISPLAY, META_TYPE_DISPLAY,
G_PARAM_DEPRECATED |
G_PARAM_READWRITE | G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS); G_PARAM_STATIC_STRINGS);
@ -347,6 +392,12 @@ meta_barrier_emit_left_signal (MetaBarrier *barrier,
g_signal_emit (barrier, obj_signals[LEFT], 0, event); g_signal_emit (barrier, obj_signals[LEFT], 0, event);
} }
MetaBackend *
meta_barrier_get_backend (MetaBarrier *barrier)
{
return barrier->priv->backend;
}
static void static void
meta_barrier_impl_class_init (MetaBarrierImplClass *klass) meta_barrier_impl_class_init (MetaBarrierImplClass *klass)
{ {

View File

@ -251,6 +251,12 @@ meta_backend_native_post_init (MetaBackend *backend)
update_viewports (backend); update_viewports (backend);
} }
static MetaBackendCapabilities
meta_backend_native_get_capabilities (MetaBackend *backend)
{
return META_BACKEND_CAPABILITY_BARRIERS;
}
static MetaMonitorManager * static MetaMonitorManager *
meta_backend_native_create_monitor_manager (MetaBackend *backend, meta_backend_native_create_monitor_manager (MetaBackend *backend,
GError **error) 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->create_default_seat = meta_backend_native_create_default_seat;
backend_class->post_init = meta_backend_native_post_init; 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->create_monitor_manager = meta_backend_native_create_monitor_manager;
backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer; backend_class->get_cursor_renderer = meta_backend_native_get_cursor_renderer;

View File

@ -606,10 +606,10 @@ meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
MetaBarrierImpl * MetaBarrierImpl *
meta_barrier_impl_native_new (MetaBarrier *barrier) meta_barrier_impl_native_new (MetaBarrier *barrier)
{ {
MetaBackend *backend = meta_barrier_get_backend (barrier);
ClutterSeat *seat = meta_backend_get_default_seat (backend);
MetaBarrierImplNative *self; MetaBarrierImplNative *self;
MetaBarrierManagerNative *manager; 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); self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);

View File

@ -28,6 +28,7 @@
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-dnd-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-renderer-x11.h"
#include "backends/x11/meta-cursor-tracker-x11.h" #include "backends/x11/meta-cursor-tracker-x11.h"
#include "backends/x11/meta-gpu-xrandr.h" #include "backends/x11/meta-gpu-xrandr.h"
@ -115,6 +116,20 @@ meta_backend_x11_cm_post_init (MetaBackend *backend)
take_touch_grab (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 * static MetaRenderer *
meta_backend_x11_cm_create_renderer (MetaBackend *backend, meta_backend_x11_cm_create_renderer (MetaBackend *backend,
GError **error) GError **error)
@ -523,6 +538,7 @@ meta_backend_x11_cm_class_init (MetaBackendX11CmClass *klass)
object_class->constructed = meta_backend_x11_cm_constructed; object_class->constructed = meta_backend_x11_cm_constructed;
backend_class->post_init = meta_backend_x11_cm_post_init; 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_renderer = meta_backend_x11_cm_create_renderer;
backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager; backend_class->create_monitor_manager = meta_backend_x11_cm_create_monitor_manager;
backend_class->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer; backend_class->get_cursor_renderer = meta_backend_x11_cm_get_cursor_renderer;

View File

@ -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 */

View File

@ -45,6 +45,7 @@
#include "backends/meta-idle-monitor-private.h" #include "backends/meta-idle-monitor-private.h"
#include "backends/meta-keymap-utils.h" #include "backends/meta-keymap-utils.h"
#include "backends/meta-stage-private.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-clutter-backend-x11.h"
#include "backends/x11/meta-event-x11.h" #include "backends/x11/meta-event-x11.h"
#include "backends/x11/meta-seat-x11.h" #include "backends/x11/meta-seat-x11.h"
@ -79,6 +80,7 @@ struct _MetaBackendX11Private
int xinput_event_base; int xinput_event_base;
int xinput_error_base; int xinput_error_base;
Time latest_evtime; Time latest_evtime;
gboolean have_xinput_23;
uint8_t xkb_event_base; uint8_t xkb_event_base;
uint8_t xkb_error_base; uint8_t xkb_error_base;
@ -89,6 +91,8 @@ struct _MetaBackendX11Private
xkb_layout_index_t keymap_layout_group; xkb_layout_index_t keymap_layout_group;
MetaLogicalMonitor *cached_current_logical_monitor; MetaLogicalMonitor *cached_current_logical_monitor;
MetaX11Barriers *barriers;
}; };
typedef struct _MetaBackendX11Private MetaBackendX11Private; 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, handle_input_event (MetaBackendX11 *x11,
XEvent *event) XEvent *event)
{ {
@ -296,9 +300,17 @@ handle_input_event (MetaBackendX11 *x11,
event->xcookie.extension == priv->xinput_opcode) event->xcookie.extension == priv->xinput_opcode)
{ {
XIEvent *input_event = (XIEvent *) event->xcookie.data; 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); maybe_spoof_event_as_stage_event (x11, input_event);
} }
return FALSE;
} }
static void static void
@ -401,10 +413,13 @@ handle_host_xevent (MetaBackend *backend,
if (!bypass_clutter) if (!bypass_clutter)
{ {
handle_input_event (x11, event); if (handle_input_event (x11, event))
goto done;
meta_x11_handle_event (backend, event); meta_x11_handle_event (backend, event);
} }
done:
XFreeEventData (priv->xdisplay, &event->xcookie); XFreeEventData (priv->xdisplay, &event->xcookie);
} }
@ -518,7 +533,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
ClutterSeat *seat; ClutterSeat *seat;
MetaInputSettings *input_settings; MetaInputSettings *input_settings;
int major, minor; int major, minor;
gboolean has_xi = FALSE;
priv->source = x_event_source_new (backend); 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); 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, if (!xkb_x11_setup_xkb_extension (priv->xcb,
XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MAJOR_XKB_VERSION,
XKB_X11_MIN_MINOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION,
@ -816,6 +812,47 @@ init_xkb_state (MetaBackendX11 *x11)
xkb_state_unref (state); 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 static gboolean
meta_backend_x11_initable_init (GInitable *initable, meta_backend_x11_initable_init (GInitable *initable,
GCancellable *cancellable, GCancellable *cancellable,
@ -852,6 +889,12 @@ meta_backend_x11_initable_init (GInitable *initable,
init_xkb_state (x11); 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); 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_put (event);
clutter_event_free (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;
}

View File

@ -29,6 +29,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/x11/meta-backend-x11-types.h"
#include "backends/x11/meta-clutter-backend-x11.h" #include "backends/x11/meta-clutter-backend-x11.h"
#define META_TYPE_BACKEND_X11 (meta_backend_x11_get_type ()) #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); void meta_backend_x11_sync_pointer (MetaBackendX11 *backend_x11);
MetaX11Barriers * meta_backend_x11_get_barriers (MetaBackendX11 *backend_x11);
#endif /* META_BACKEND_X11_H */ #endif /* META_BACKEND_X11_H */

View File

@ -35,11 +35,17 @@
#include <X11/extensions/XInput2.h> #include <X11/extensions/XInput2.h>
#include <X11/extensions/Xfixes.h> #include <X11/extensions/Xfixes.h>
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-barrier-x11.h" #include "backends/x11/meta-barrier-x11.h"
#include "core/display-private.h" #include "core/display-private.h"
#include "meta/barrier.h" #include "meta/barrier.h"
#include "x11/meta-x11-display-private.h" #include "x11/meta-x11-display-private.h"
struct _MetaX11Barriers
{
GHashTable *barriers;
};
struct _MetaBarrierImplX11 struct _MetaBarrierImplX11
{ {
MetaBarrierImpl parent; MetaBarrierImpl parent;
@ -65,34 +71,29 @@ meta_barrier_impl_x11_release (MetaBarrierImpl *impl,
MetaBarrierEvent *event) MetaBarrierEvent *event)
{ {
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl); MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
MetaDisplay *display = self->barrier->priv->display; MetaBackend *backend = self->barrier->priv->backend;
Display *dpy = meta_x11_display_get_xdisplay (display->x11_display); 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 (xdisplay,
{ META_VIRTUAL_CORE_POINTER_ID,
XIBarrierReleasePointer (dpy, self->xbarrier, event->event_id);
META_VIRTUAL_CORE_POINTER_ID,
self->xbarrier, event->event_id);
}
} }
static void static void
meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl) meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl)
{ {
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl); MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
MetaDisplay *display = self->barrier->priv->display; MetaBackend *backend = self->barrier->priv->backend;
Display *dpy; MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
MetaX11Barriers *barriers = meta_backend_x11_get_barriers (backend_x11);
if (display == NULL) Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
return;
dpy = meta_x11_display_get_xdisplay (display->x11_display);
if (!meta_barrier_is_active (self->barrier)) if (!meta_barrier_is_active (self->barrier))
return; return;
XFixesDestroyPointerBarrier (dpy, self->xbarrier); XFixesDestroyPointerBarrier (xdisplay, self->xbarrier);
g_hash_table_remove (display->x11_display->xids, &self->xbarrier); g_hash_table_remove (barriers->barriers, &self->xbarrier);
self->xbarrier = 0; self->xbarrier = 0;
} }
@ -100,26 +101,24 @@ MetaBarrierImpl *
meta_barrier_impl_x11_new (MetaBarrier *barrier) meta_barrier_impl_x11_new (MetaBarrier *barrier)
{ {
MetaBarrierImplX11 *self; MetaBarrierImplX11 *self;
MetaDisplay *display = barrier->priv->display; MetaBackend *backend;
Display *dpy; MetaBackendX11 *backend_x11;
MetaX11Barriers *barriers;
Display *xdisplay;
Window root; Window root;
unsigned int allowed_motion_dirs; 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 = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL);
self->barrier = barrier; self->barrier = barrier;
dpy = meta_x11_display_get_xdisplay (display->x11_display); backend = self->barrier->priv->backend;
root = DefaultRootWindow (dpy); backend_x11 = META_BACKEND_X11 (backend);
xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
root = DefaultRootWindow (xdisplay);
allowed_motion_dirs = allowed_motion_dirs =
meta_border_get_allows_directions (&barrier->priv->border); 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.x,
barrier->priv->border.line.a.y, barrier->priv->border.line.a.y,
barrier->priv->border.line.b.x, barrier->priv->border.line.b.x,
@ -127,7 +126,8 @@ meta_barrier_impl_x11_new (MetaBarrier *barrier)
allowed_motion_dirs, allowed_motion_dirs,
0, NULL); 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); return META_BARRIER_IMPL (self);
} }
@ -167,15 +167,12 @@ meta_barrier_fire_xevent (MetaBarrier *barrier,
} }
gboolean gboolean
meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display, meta_x11_barriers_process_xevent (MetaX11Barriers *barriers,
XIEvent *event) XIEvent *event)
{ {
MetaBarrier *barrier; MetaBarrier *barrier;
XIBarrierEvent *xev; XIBarrierEvent *xev;
if (event == NULL)
return FALSE;
switch (event->evtype) switch (event->evtype)
{ {
case XI_BarrierHit: case XI_BarrierHit:
@ -186,8 +183,8 @@ meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display,
} }
xev = (XIBarrierEvent *) event; xev = (XIBarrierEvent *) event;
barrier = g_hash_table_lookup (x11_display->xids, &xev->barrier); barrier = g_hash_table_lookup (barriers->barriers, &xev->barrier);
if (barrier != NULL) if (barrier)
{ {
meta_barrier_fire_xevent (barrier, xev); meta_barrier_fire_xevent (barrier, xev);
return TRUE; return TRUE;
@ -210,3 +207,31 @@ static void
meta_barrier_impl_x11_init (MetaBarrierImplX11 *self) 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);
}

View File

@ -26,6 +26,7 @@
#define META_BARRIER_X11_H #define META_BARRIER_X11_H
#include "backends/meta-barrier-private.h" #include "backends/meta-barrier-private.h"
#include "backends/x11/meta-backend-x11-types.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -37,6 +38,13 @@ G_DECLARE_FINAL_TYPE (MetaBarrierImplX11,
MetaBarrierImpl *meta_barrier_impl_x11_new (MetaBarrier *barrier); 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 G_END_DECLS
#endif /* META_BARRIER_X11_H1 */ #endif /* META_BARRIER_X11_H1 */

View File

@ -245,6 +245,12 @@ meta_backend_x11_nested_post_init (MetaBackend *backend)
backend_class->post_init (backend); backend_class->post_init (backend);
} }
static MetaBackendCapabilities
meta_backend_x11_nested_get_capabilities (MetaBackend *backend)
{
return META_BACKEND_CAPABILITY_NONE;
}
static gboolean static gboolean
meta_backend_x11_nested_initable_init (GInitable *initable, meta_backend_x11_nested_initable_init (GInitable *initable,
GCancellable *cancellable, GCancellable *cancellable,
@ -303,6 +309,7 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
object_class->dispose = meta_backend_x11_nested_dispose; object_class->dispose = meta_backend_x11_nested_dispose;
backend_class->post_init = meta_backend_x11_nested_post_init; 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_renderer = meta_backend_x11_nested_create_renderer;
backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager; backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
backend_class->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer; backend_class->get_cursor_renderer = meta_backend_x11_nested_get_cursor_renderer;

View File

@ -2826,20 +2826,11 @@ meta_display_modifiers_accelerator_activate (MetaDisplay *display)
gboolean gboolean
meta_display_supports_extended_barriers (MetaDisplay *display) meta_display_supports_extended_barriers (MetaDisplay *display)
{ {
#ifdef HAVE_NATIVE_BACKEND MetaContext *context = meta_display_get_context (display);
if (META_IS_BACKEND_NATIVE (meta_get_backend ())) MetaBackend *backend = meta_context_get_backend (context);
return TRUE;
#endif
if (META_IS_BACKEND_X11_CM (meta_get_backend ())) return !!(meta_backend_get_capabilities (backend) &
{ META_BACKEND_CAPABILITY_BARRIERS);
if (meta_is_wayland_compositor())
return FALSE;
return META_X11_DISPLAY_HAS_XINPUT_23 (display->x11_display);
}
return FALSE;
} }
/** /**

View File

@ -78,6 +78,7 @@ GType meta_display_get_type (void) G_GNUC_CONST;
#define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0) #define meta_XFree(p) do { if ((p)) XFree ((p)); } while (0)
META_EXPORT META_EXPORT
G_DEPRECATED_FOR (meta_backend_get_capabilities)
gboolean meta_display_supports_extended_barriers (MetaDisplay *display); gboolean meta_display_supports_extended_barriers (MetaDisplay *display);
META_EXPORT META_EXPORT

View File

@ -33,6 +33,12 @@
#include "meta/meta-monitor-manager.h" #include "meta/meta-monitor-manager.h"
#include "meta/meta-remote-access-controller.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 ()) #define META_TYPE_BACKEND (meta_backend_get_type ())
META_EXPORT META_EXPORT
G_DECLARE_DERIVABLE_TYPE (MetaBackend, meta_backend, META, BACKEND, GObject) 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 META_EXPORT
gboolean meta_backend_is_headless (MetaBackend *backend); gboolean meta_backend_is_headless (MetaBackend *backend);
META_EXPORT
MetaBackendCapabilities meta_backend_get_capabilities (MetaBackend *backend);
META_EXPORT META_EXPORT
void meta_clutter_init (void); void meta_clutter_init (void);

View File

@ -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)) if (handle_input_xevent (x11_display, input_event, event->xany.serial))
{ {
bypass_gtk = bypass_compositor = TRUE; bypass_gtk = bypass_compositor = TRUE;

View File

@ -175,8 +175,6 @@ struct _MetaX11Display
unsigned int have_damage : 1; unsigned int have_damage : 1;
#define META_X11_DISPLAY_HAS_COMPOSITE(x11_display) ((x11_display)->have_composite) #define META_X11_DISPLAY_HAS_COMPOSITE(x11_display) ((x11_display)->have_composite)
#define META_X11_DISPLAY_HAS_DAMAGE(x11_display) ((x11_display)->have_damage) #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; MetaX11StartupNotification *startup_notification;
MetaX11Stack *x11_stack; 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, void meta_x11_display_unregister_sync_alarm (MetaX11Display *x11_display,
XSyncAlarm alarm); XSyncAlarm alarm);
gboolean meta_x11_display_process_barrier_xevent (MetaX11Display *x11_display,
XIEvent *event);
META_EXPORT META_EXPORT
void meta_x11_display_set_alarm_filter (MetaX11Display *x11_display, void meta_x11_display_set_alarm_filter (MetaX11Display *x11_display,
MetaAlarmFilter filter, MetaAlarmFilter filter,

View File

@ -429,15 +429,8 @@ query_xi_extension (MetaX11Display *x11_display)
&x11_display->xinput_error_base, &x11_display->xinput_error_base,
&x11_display->xinput_event_base)) &x11_display->xinput_event_base))
{ {
if (XIQueryVersion (x11_display->xdisplay, &major, &minor) == Success) if (XIQueryVersion (x11_display->xdisplay, &major, &minor) == Success)
{ has_xi = TRUE;
int version = (major * 10) + minor;
if (version >= 22)
has_xi = TRUE;
if (version >= 23)
x11_display->have_xinput_23 = TRUE;
}
} }
if (!has_xi) if (!has_xi)
@ -792,11 +785,6 @@ init_event_masks (MetaX11Display *x11_display)
XISetMask (mask.mask, XI_Leave); XISetMask (mask.mask, XI_Leave);
XISetMask (mask.mask, XI_FocusIn); XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut); 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); XISelectEvents (x11_display->xdisplay, x11_display->xroot, &mask, 1);
event_mask = (SubstructureRedirectMask | SubstructureNotifyMask | event_mask = (SubstructureRedirectMask | SubstructureNotifyMask |