xwayland: Fix XYToWindow to return focused window

The Wayland protocol already tells us which window is focused,
so let's use that instead of trying to find a window at
the global pointer coordinates.

This solves the problem when a window receives wayland pointer
events but actual X11 Enter/Leave/Motion events are delivered
to another window at provided coordinates (the other window
might be above the focused window).
This commit is contained in:
Stanislav Aleksandrov 2025-12-22 13:09:23 +00:00
parent f83807647e
commit 2240cac022
3 changed files with 16 additions and 9 deletions

View file

@ -3279,14 +3279,23 @@ static WindowPtr
xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y)
{
struct xwl_screen *xwl_screen;
struct xwl_seat *seat;
WindowPtr ret;
xwl_screen = xwl_screen_get(screen);
screen->XYToWindow = xwl_screen->XYToWindow;
ret = screen->XYToWindow(screen, sprite, x, y);
xwl_screen->XYToWindow = screen->XYToWindow;
screen->XYToWindow = xwl_xy_to_window;
/* root window should be already there */
sprite->spriteTraceGood = 1;
ret = DeepestSpriteWin(sprite);
seat = xwl_screen_get_default_seat(xwl_screen);
if (seat && seat->focus_window) {
ret = seat->focus_window->toplevel;
sprite->spriteTrace[sprite->spriteTraceGood++] = ret;
/* Continue to look deeper to find a child window if any */
ret = miSpriteTrace(sprite, x, y);
}
/* If the device controlling the sprite has left the Wayland surface but
* the DIX still finds the pointer within the X11 window, it means that
@ -3658,7 +3667,6 @@ InitInput(int argc, char *argv[])
wl_registry_add_listener(xwl_screen->input_registry, &input_listener,
xwl_screen);
xwl_screen->XYToWindow = pScreen->XYToWindow;
pScreen->XYToWindow = xwl_xy_to_window;
xwl_screen_roundtrip(xwl_screen);

View file

@ -283,9 +283,8 @@ xwl_close_screen(ScreenPtr screen)
return screen->CloseScreen(screen);
}
static struct xwl_seat *
xwl_screen_get_default_seat(struct xwl_screen *xwl_screen)
{
struct xwl_seat *
xwl_screen_get_default_seat(struct xwl_screen *xwl_screen) {
if (xorg_list_is_empty(&xwl_screen->seat_list))
return NULL;

View file

@ -75,7 +75,6 @@ struct xwl_screen {
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
DestroyWindowProcPtr DestroyWindow;
XYToWindowProcPtr XYToWindow;
SetWindowPixmapProcPtr SetWindowPixmap;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ReparentWindowProcPtr ReparentWindow;
@ -183,5 +182,6 @@ int xwl_screen_get_next_output_serial(struct xwl_screen * xwl_screen);
void xwl_screen_lost_focus(struct xwl_screen *xwl_screen);
Bool xwl_screen_update_global_surface_scale(struct xwl_screen *xwl_screen);
Bool xwl_screen_should_use_fractional_scale(struct xwl_screen *xwl_screen);
struct xwl_seat *xwl_screen_get_default_seat(struct xwl_screen *xwl_screen);
#endif /* XWAYLAND_SCREEN_H */