From 067c59e5266e155b534c05702cbe2322add5c110 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Mon, 10 Jun 2024 00:01:54 +0200 Subject: [PATCH] xwayland: reset cursor image on cursor theme reload As wlr_xwayland caches the pixel data when not yet started up due to the delayed lazy startup approach, we do have to re-set the xwayland cursor image when reloading the cursor theme. Otherwise the first X11 client connected will cause the xwayland server to use the cached (and destroyed) pixel data. To reproduce: - Compile with b_sanitize=address,undefined - Start labwc (nothing in autostart that could create a X11 connection, e.g. no GTK or X11 application) - Reconfigure - Start some X11 client --- include/xwayland.h | 2 ++ src/input/cursor.c | 4 ++++ src/xwayland.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/include/xwayland.h b/include/xwayland.h index 0072106e..99867e3e 100644 --- a/include/xwayland.h +++ b/include/xwayland.h @@ -95,5 +95,7 @@ void xwayland_adjust_usable_area(struct view *view, void xwayland_update_workarea(struct server *server); +void xwayland_reset_cursor(struct server *server); + #endif /* HAVE_XWAYLAND */ #endif /* LABWC_XWAYLAND_H */ diff --git a/src/input/cursor.c b/src/input/cursor.c index 975a295e..3e3c0003 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -26,6 +26,7 @@ #include "resistance.h" #include "ssd.h" #include "view.h" +#include "xwayland.h" #define LAB_CURSOR_SHAPE_V1_VERSION 1 @@ -1403,6 +1404,9 @@ void cursor_reload(struct seat *seat) { cursor_load(seat); +#if HAVE_XWAYLAND + xwayland_reset_cursor(seat->server); +#endif cursor_update_image(seat); } diff --git a/src/xwayland.c b/src/xwayland.c index 2e537038..d4eff83d 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1128,6 +1128,56 @@ xwayland_adjust_stacking_order(struct server *server) wl_array_release(&views); } +void +xwayland_reset_cursor(struct server *server) +{ + /* + * As xwayland caches the pixel data when not yet started up + * due to the delayed lazy startup approach, we do have to + * re-set the xwayland cursor image. Otherwise the first X11 + * client connected will cause the xwayland server to use + * the cached (and potentially destroyed) pixel data. + * + * Calling this function after reloading the cursor theme + * ensures that the cached pixel data keeps being valid. + * + * To reproduce: + * - Compile with b_sanitize=address,undefined + * - Start labwc (nothing in autostart that could create + * a X11 connection, e.g. no GTK or X11 application) + * - Reconfigure + * - Start some X11 client + */ + + if (!server->xwayland) { + return; + } + + struct wlr_xcursor *xcursor = wlr_xcursor_manager_get_xcursor( + server->seat.xcursor_manager, XCURSOR_DEFAULT, 1); + + if (xcursor && !server->xwayland->xwm) { + /* Prevents setting the cursor on an active xwayland server */ + struct wlr_xcursor_image *image = xcursor->images[0]; + wlr_xwayland_set_cursor(server->xwayland, image->buffer, + image->width * 4, image->width, + image->height, image->hotspot_x, + image->hotspot_y); + return; + } + + if (server->xwayland->cursor) { + /* + * The previous configured theme has set the + * default cursor or the xwayland server is + * currently running but still has a cached + * xcursor set that will be used on the next + * xwayland destroy -> lazy startup cycle. + */ + zfree(server->xwayland->cursor); + } +} + void xwayland_server_finish(struct server *server) {