xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Feb 2 12:59:19 UTC 2021


 hw/xwayland/xwayland-input.c |   30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

New commits:
commit c7730cfe5577ebde006d408f502766d8c3a73670
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed May 13 16:48:55 2020 +0200

    xwayland: Translate keyboard grabs on the root window
    
    When an X11 client issues an active grab on the keyboard, Xwayland
    forward this to the Wayland compositor using the Xwayland specific
    protocol "xwayland-keyboard-grab" if it can find the corresponding
    Xwayland window.
    
    Some X11 clients (typically older games) however try to issue the
    keyboard grab on the X11 root window, which has obviously no matching
    Xwayland window. In such a case, the grab is simply ignored and the game
    will not work as expected.
    
    To workaround that issue, if an X11 client issues a keyboard grab on the
    root window, Xwayland will search for a toplevel window belonging to the
    same X11 client that it can use as the grab window instead.
    
    This way, the grab can be forwarded to the Wayland compositor that can
    either grant or deny the request based on the window and its internal
    policies.
    
    The heuristic picks the first realized toplevel window belonging to the
    client so that the Wayland compositor will send it the keyboard events,
    and the Xserver grab mechanism will then take care of routing the events
    to the expected X11 window by itself.
    
    v2: Make the test more clear (Dor Askayo <dor.askayo at gmail.com>)
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    Acked-by: Jonas Ådahl <jadahl at gmail.com>
    See-also: https://gitlab.gnome.org/GNOME/mutter/-/issues/1249

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 12efbe169..8e57fda1d 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -1120,18 +1120,44 @@ set_grab(struct xwl_seat *xwl_seat, struct xwl_window *xwl_window)
                                                             xwl_seat->seat);
 }
 
+static void
+find_toplevel_callback(void *resource, XID id, void *user_data)
+{
+    WindowPtr window = resource;
+    WindowPtr *toplevel = user_data;
+
+    /* Pick the first realized toplevel we find */
+    if (*toplevel == NullWindow && window->realized && xwl_window_is_toplevel(window))
+        *toplevel = window;
+}
+
+static WindowPtr
+xwl_keyboard_search_window(ClientPtr client)
+{
+    WindowPtr window = NullWindow;
+
+    FindClientResourcesByType(client, RT_WINDOW, find_toplevel_callback, &window);
+
+    return window;
+}
+
 static void
 xwl_keyboard_activate_grab(DeviceIntPtr device, GrabPtr grab, TimeStamp time, Bool passive)
 {
     struct xwl_seat *xwl_seat = device->public.devicePrivate;
+    WindowPtr grab_window = grab->window;
 
     /* We are not interested in passive grabs */
     if (!passive) {
         /* If the device is the MASTER_KEYBOARD, we don't have an xwl_seat */
         if (xwl_seat == NULL)
             xwl_seat = find_matching_seat(device);
-        if (xwl_seat)
-            set_grab(xwl_seat, xwl_window_from_window(grab->window));
+        if (xwl_seat) {
+            if (grab_window == xwl_seat->xwl_screen->screen->root)
+                grab_window = xwl_keyboard_search_window(GetCurrentClient());
+            if (grab_window)
+                set_grab(xwl_seat, xwl_window_from_window(grab_window));
+        }
     }
 
     ActivateKeyboardGrab(device, grab, time, passive);


More information about the xorg-commit mailing list