xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 30 12:50:27 UTC 2024


 hw/xwayland/xwayland-screen.c |   29 +++++++++++++++++++++++++++++
 hw/xwayland/xwayland-screen.h |    1 +
 hw/xwayland/xwayland-window.c |   30 ++++++++++++++++++++++++++++++
 hw/xwayland/xwayland-window.h |    1 +
 4 files changed, 61 insertions(+)

New commits:
commit a4ed100c0cb8cb35a2e4dd837cd9eea80d2345f4
Author: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
Date:   Thu Apr 25 19:53:56 2024 +0300

    xwayland: Set wl_surface input region
    
    Some applications that use client side decorations usually set custom
    input shape in order to prevent drop shadows stealing pointer events
    from windows below. Currently, the only way to get it is to use some
    XFixes APIs.
    
    On the other hand, plenty of wayland compositors use solely the
    wl_surface input region to decide what view can receive pointer input,
    which results in some pointer input issues around client side drop
    shadows because Xwayland doesn't set wl_surface.input_region.
    
    See-also: https://bugs.kde.org/show_bug.cgi?id=448119
    Signed-off-by: Vlad Zahorodnii <vlad.zahorodnii at kde.org>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1510>

diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index a8db081eb..9f9cd6bc0 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -332,6 +332,32 @@ xwl_cursor_warped_to(DeviceIntPtr device,
     xwl_seat_emulate_pointer_warp(xwl_seat, xwl_window, sprite, x, y);
 }
 
+static void
+xwl_set_shape(WindowPtr window,
+              int kind)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    struct xwl_window *xwl_window;
+
+    xwl_screen = xwl_screen_get(screen);
+    xwl_window = xwl_window_from_window(window);
+
+    screen->SetShape = xwl_screen->SetShape;
+    (*screen->SetShape) (window, kind);
+    xwl_screen->SetShape = screen->SetShape;
+    screen->SetShape = xwl_set_shape;
+
+    if (!xwl_window)
+        return;
+
+    if (kind == ShapeInput) {
+        xwl_window_set_input_region(xwl_window, wInputShape(window));
+        if (xwl_window->allow_commits)
+            wl_surface_commit(xwl_window->surface);
+    }
+}
+
 static struct xwl_window *
 find_matching_input_output_window(struct xwl_screen *xwl_screen,
                                   WindowPtr window)
@@ -1125,6 +1151,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
     pScreen->SetWindowPixmap = xwl_window_set_window_pixmap;
 
+    xwl_screen->SetShape = pScreen->SetShape;
+    pScreen->SetShape = xwl_set_shape;
+
     pScreen->CursorWarpedTo = xwl_cursor_warped_to;
     pScreen->CursorConfinedTo = xwl_cursor_confined_to;
 
diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h
index f3949af0a..e05497a66 100644
--- a/hw/xwayland/xwayland-screen.h
+++ b/hw/xwayland/xwayland-screen.h
@@ -80,6 +80,7 @@ struct xwl_screen {
     ChangeWindowAttributesProcPtr ChangeWindowAttributes;
     MoveWindowProcPtr MoveWindow;
     SourceValidateProcPtr SourceValidate;
+    SetShapeProcPtr SetShape;
 
     int (*GrabServer) (ClientPtr client);
     int (*UngrabServer) (ClientPtr client);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index b111a1e4a..b8a2ddb18 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -1502,6 +1502,8 @@ ensure_surface_for_window(WindowPtr window)
             xwl_screen->tearing_control_manager, xwl_window->surface);
     }
 
+    xwl_window_set_input_region(xwl_window, wInputShape(window));
+
     return xwl_window;
 
 err:
@@ -1971,6 +1973,34 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
     DamageEmpty(window_get_damage(xwl_window->surface_window));
 }
 
+void
+xwl_window_set_input_region(struct xwl_window *xwl_window,
+                            RegionPtr input_shape)
+{
+    struct wl_region *region;
+    BoxPtr box;
+    int i;
+
+    if (!input_shape) {
+        wl_surface_set_input_region(xwl_window->surface, NULL);
+        return;
+    }
+
+    region = wl_compositor_create_region(xwl_window->xwl_screen->compositor);
+    box = RegionRects(input_shape);
+
+    for (i = 0; i < RegionNumRects(input_shape); ++i, ++box) {
+        wl_region_add(region,
+                      box->x1,
+                      box->y1,
+                      box->x2 - box->x1,
+                      box->y2 - box->y1);
+    }
+
+    wl_surface_set_input_region(xwl_window->surface, region);
+    wl_region_destroy(region);
+}
+
 Bool
 xwl_window_init(void)
 {
diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h
index 836f654a3..f73d05684 100644
--- a/hw/xwayland/xwayland-window.h
+++ b/hw/xwayland/xwayland-window.h
@@ -143,6 +143,7 @@ Bool xwl_destroy_window(WindowPtr window);
 void xwl_window_post_damage(struct xwl_window *xwl_window);
 void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
 void xwl_window_surface_do_destroy(struct xwl_wl_surface *xwl_wl_surface);
+void xwl_window_set_input_region(struct xwl_window *xwl_window, RegionPtr input_shape);
 
 Bool xwl_window_init(void);
 


More information about the xorg-commit mailing list