From 3d953339f843fb290c55ba82c05c13d4be50086f Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 21 Jun 2026 16:55:02 +0200 Subject: [PATCH] wayland: fix XWayland titlebar actions and cursor - wl_pointer_focus.c: In view_surface_at(), check frame bounds for XWayland views before returning the surface. When pointer is over frame decorations (titlebar, buttons, resizebar), continue the loop so the frame_buf handles the event. Fixes titlebar buttons (close, iconify, shade) not responding for XWayland applications. - wl_xwayland.c: Set left_ptr cursor on the XWayland root window at startup via XDefineCursor. Fixes the default X cursor (big X) showing for X11 applications that do not set their own cursor. --- src/backend/wayland/wl_pointer_focus.c | 10 ++++++++++ src/backend/wayland/wl_xwayland.c | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/backend/wayland/wl_pointer_focus.c b/src/backend/wayland/wl_pointer_focus.c index 73f5b84..7e8ed48 100644 --- a/src/backend/wayland/wl_pointer_focus.c +++ b/src/backend/wayland/wl_pointer_focus.c @@ -80,6 +80,16 @@ view_surface_at(int px, int py, double *sx_out, double *sy_out, if (v->xw_surface && v->xw_surface->surface) { double sx = px - (double)v->x; double sy = py - (double)v->y; + /* If the XWayland view has a frame, only return the surface + * when the pointer is over the client content area. */ + if (v->frame_id) { + if (sx < v->frame_rel_x || sy < v->frame_rel_y || + sx >= v->frame_rel_x + v->xw_surface->width || + sy >= v->frame_rel_y + v->xw_surface->height) + continue; + sx -= v->frame_rel_x; + sy -= v->frame_rel_y; + } if (sx_out) *sx_out = sx; if (sy_out) *sy_out = sy; if (view_out) *view_out = v; diff --git a/src/backend/wayland/wl_xwayland.c b/src/backend/wayland/wl_xwayland.c index 41b77ec..1655721 100644 --- a/src/backend/wayland/wl_xwayland.c +++ b/src/backend/wayland/wl_xwayland.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "../../screen.h" #include "window.h" @@ -278,6 +279,15 @@ handle_xwayland_ready(struct wl_listener *listener, void *data) wwarning("wl_backend: XOpenDisplay(%s) failed — WM UI limited to native Wayland", wl_state.xwayland->display_name); + /* Set the default root cursor to left_ptr so XWayland clients that + * don't set their own cursor show an arrow instead of the X cursor. */ + if (wl_state.x_display) { + Cursor c = XCreateFontCursor(wl_state.x_display, XC_left_ptr); + XDefineCursor(wl_state.x_display, DefaultRootWindow(wl_state.x_display), c); + XFreeCursor(wl_state.x_display, c); + XFlush(wl_state.x_display); + } + wl_state.xwayland_ready = true; }