diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index e9e94e044..ce703dfa3 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 6febe4dfa..9f4341bb0 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 84ea48442..856b58e87 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -53,6 +53,7 @@ #include +#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 dd68c4f1d..16bfcdcd0 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 2f892f4e3..777287cc9 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 eb5687375..8c6658cc9 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 47463e4aa..63acb6a79 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 ed2b7bb8b..c6a8d6c0e 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 000000000..86818efbf --- /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 969b64ddd..da14cd73a 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 515cde91b..748ab3c11 100644 --- a/src/backends/x11/meta-backend-x11.h +++ b/src/backends/x11/meta-backend-x11.h @@ -29,6 +29,7 @@ #include #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 ebbf1dabb..8be0c9718 100644 --- a/src/backends/x11/meta-barrier-x11.c +++ b/src/backends/x11/meta-barrier-x11.c @@ -35,11 +35,17 @@ #include #include +#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 3562d106f..ae50fdcca 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 041b42860..0f38f4ad2 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 ee1c372bf..5bb34a65a 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 + MetaContext *context = meta_display_get_context (display); + MetaBackend *backend = meta_context_get_backend (context); - 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); - } - - 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 e59bd0393..206e08c0c 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 cfb042a72..05fb47234 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 2c574d575..c7caaf725 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 d53073e11..9158387d6 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 bb5f4bf50..3139246cc 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 |