From 5f132f39750f684c3732b4346dec810cd218d609 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Fri, 20 Oct 2017 10:47:24 +0200 Subject: [PATCH] xwayland: add _XWAYLAND_MAY_GRAB_KEYBOARD property Add a new client message "_XWAYLAND_MAY_GRAB_KEYBOARD" that X11 clients can use to tell mutter this is a well behaving X11 client so it may grant the keyboard grabs when requested. An X11 client wishing to be granted Xwayland grabs by gnome-shell/mutter must send a ClientMessage to the root window with: - message_type set to "_XWAYLAND_MAY_GRAB_KEYBOARD" - window set to the xid of the window on which the grab is to be issued - data.l[0] to a non-zero value Note: Sending this client message when running a plain native X11 environment would have no effect. https://bugzilla.gnome.org/show_bug.cgi?id=783342 --- src/wayland/meta-window-xwayland.c | 64 ++++++++++++++++++++++++++++++ src/wayland/meta-xwayland.h | 4 ++ src/x11/atomnames.h | 1 + src/x11/events.c | 7 ++++ 4 files changed, 76 insertions(+) diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c index 9f32500d4..6f073893a 100644 --- a/src/wayland/meta-window-xwayland.c +++ b/src/wayland/meta-window-xwayland.c @@ -23,9 +23,22 @@ #include "wayland/meta-window-xwayland.h" #include "wayland/meta-wayland.h" +enum +{ + PROP_0, + + PROP_XWAYLAND_MAY_GRAB_KEYBOARD, + + PROP_LAST +}; + +static GParamSpec *obj_props[PROP_LAST]; + struct _MetaWindowXwayland { MetaWindowX11 parent; + + gboolean xwayland_may_grab_keyboard; }; struct _MetaWindowXwaylandClass @@ -58,11 +71,62 @@ meta_window_xwayland_shortcuts_inhibited (MetaWindow *window, return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source); } +static void +meta_window_xwayland_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MetaWindowXwayland *window = META_WINDOW_XWAYLAND (object); + + switch (prop_id) + { + case PROP_XWAYLAND_MAY_GRAB_KEYBOARD: + g_value_set_boolean (value, window->xwayland_may_grab_keyboard); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +meta_window_xwayland_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MetaWindowXwayland *window = META_WINDOW_XWAYLAND (object); + + switch (prop_id) + { + case PROP_XWAYLAND_MAY_GRAB_KEYBOARD: + window->xwayland_may_grab_keyboard = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass) { MetaWindowClass *window_class = META_WINDOW_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts; window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited; + + gobject_class->get_property = meta_window_xwayland_get_property; + gobject_class->set_property = meta_window_xwayland_set_property; + + obj_props[PROP_XWAYLAND_MAY_GRAB_KEYBOARD] = + g_param_spec_boolean ("xwayland-may-grab-keyboard", + "Xwayland may use keyboard grabs", + "Whether the client may use Xwayland keyboard grabs on this window", + FALSE, + G_PARAM_READWRITE); + + g_object_class_install_properties (gobject_class, PROP_LAST, obj_props); } diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h index caaf5101e..5c404a921 100644 --- a/src/wayland/meta-xwayland.h +++ b/src/wayland/meta-xwayland.h @@ -37,4 +37,8 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window, gboolean meta_xwayland_is_xwayland_surface (MetaWaylandSurface *surface); +void +meta_xwayland_handle_xwayland_grab (MetaWindow *window, + gboolean allow); + #endif /* META_XWAYLAND_H */ diff --git a/src/x11/atomnames.h b/src/x11/atomnames.h index dcb1516b8..ed3c72a09 100644 --- a/src/x11/atomnames.h +++ b/src/x11/atomnames.h @@ -81,6 +81,7 @@ item(VERSION) item(ATOM_PAIR) item(_XKB_RULES_NAMES) item(WL_SURFACE_ID) +item(_XWAYLAND_MAY_GRAB_KEYBOARD) /* Oddities: These are used, and we need atoms for them, * but when we need all _NET_WM hints (i.e. when we're making diff --git a/src/x11/events.c b/src/x11/events.c index 49f2569f3..f60f650a6 100644 --- a/src/x11/events.c +++ b/src/x11/events.c @@ -1515,6 +1515,13 @@ handle_other_xevent (MetaDisplay *display, guint32 surface_id = event->xclient.data.l[0]; meta_xwayland_handle_wl_surface_id (window, surface_id); } + else if (event->xclient.message_type == display->atom__XWAYLAND_MAY_GRAB_KEYBOARD) + { + if (meta_is_wayland_compositor ()) + g_object_set (G_OBJECT (window), + "xwayland-may-grab-keyboard", (event->xclient.data.l[0] != 0), + NULL); + } else #endif if (!frame_was_receiver)