From d7745cca00bbd5a10664a1e2dcabbd0ee2fb1934 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Wed, 28 May 2025 17:10:41 +0200 Subject: [PATCH] xwayland: Do not pretend leaving the X11 surface if buttons are down Xwayland has its own XYToWindow() handler to account for the case when the pointer leaves an X11 surface to enter another Wayland native window. When that occurs, Xwayland will treat it as if the pointer had entered the root window so that the X11 clients receive an appropriate leave event. When the pointer leaves the X11 surface, Xwayland will call CheckMotion() to update the sprite coordinates and possibly the cursor. However, if we left the surface with a button down, it means the wayland compositor has grabbed the pointer so we will not get button release events from the compositor. Once the button is released, Xwayland will get a pointer enter event from the compositor, and Xwayland will clear up the buttons pressed. But that might confuse Xwayland in thinking the pointer has crossed the windows and leave the wrong cursor showing in the X11 surface. To avoid the issue, if buttons are down, do not pretend the cursor has left the X11 surface for the root window. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1811 Signed-off-by: Olivier Fourdan (cherry picked from commit 8cb078f8b6be8f53d3ad53b74325b5369b90c704) (cherry picked from commit 3c80595c7e3415f4fc33fa5a481287fea3cc78b7) Part-of: --- hw/xwayland/xwayland-input.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 766f11ff9..78ff605e2 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -3209,6 +3209,15 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window) if (master->lastSlave != get_pointer_device(xwl_seat)) return FALSE; + /* If we left the surface with a button down, it means the wayland compositor + * has grabbed the pointer so we will not get button release events from the + * compositor, so leave the window processing untouched, so that we do not + * end up with the wrong cursor, for example, when processing events once + * the pointer enters the X11 surface again. + */ + if (master->button->buttonsDown) + return FALSE; + if (xwl_seat->focus_window != NULL && xwl_seat->cursor_confinement_window != NULL && xwl_seat->focus_window != xwl_seat->cursor_confinement_window)