mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-20 07:00:03 +01:00
xwayland: prevent X11 get enter event when pointer is over Wayland client
In Wayland, mouse coordinates are not updated after all x11 clients have left, causing the mouse information to remain at the position left by the last x11 client. However, if CheckMotion is called at this point for other reasons (such as window mapped, reactive, etc.), xwayland might continue to send enter events to x11 clients, even if the mouse is actually on a Wayland client. This MR introduces and checks pointer_enter_count to determine if the mouse has left an x11 client and is now on a Wayland client. When it's confirmed that the mouse is no longer on an x11 client but on a Wayland client, returning TRUE in sprite_check_lost_focus causes XYToWindow to return to the root window, preventing further enter events from being sent to x11 clients. Closes: #1818
This commit is contained in:
parent
ac42c39145
commit
8c27e879ba
2 changed files with 10 additions and 3 deletions
|
|
@ -527,6 +527,7 @@ pointer_handle_enter(void *data, struct wl_pointer *pointer,
|
|||
int sx, sy;
|
||||
int dx, dy;
|
||||
ScreenPtr pScreen = xwl_screen->screen;
|
||||
xwl_seat->pointer_enter_count++;
|
||||
ValuatorMask mask;
|
||||
|
||||
/* There's a race here where if we create and then immediately
|
||||
|
|
@ -618,6 +619,9 @@ pointer_handle_leave(void *data, struct wl_pointer *pointer,
|
|||
Bool focus_lost = FALSE;
|
||||
|
||||
xwl_screen->serial = serial;
|
||||
BUG_WARN(xwl_seat->pointer_enter_count == 0);
|
||||
if (xwl_seat->pointer_enter_count > 0)
|
||||
xwl_seat->pointer_enter_count--;
|
||||
|
||||
/* The pointer has left a known xwindow, save it for a possible match
|
||||
* in sprite_check_lost_focus()
|
||||
|
|
@ -3223,6 +3227,7 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
|
|||
{
|
||||
DeviceIntPtr device, master;
|
||||
struct xwl_seat *xwl_seat;
|
||||
Bool pointer_crossing;
|
||||
|
||||
for (device = inputInfo.devices; device; device = device->next) {
|
||||
/* Ignore non-wayland devices */
|
||||
|
|
@ -3238,16 +3243,17 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
|
|||
if (!xwl_seat)
|
||||
return FALSE;
|
||||
|
||||
pointer_crossing = (xwl_seat->pointer_enter_count > 0);
|
||||
master = GetMaster(device, POINTER_OR_FLOAT);
|
||||
if (!master || !master->lastSlave)
|
||||
return FALSE;
|
||||
return !pointer_crossing;
|
||||
|
||||
/* We do want the last active slave, we only check on slave xwayland
|
||||
* devices so we can find out the xwl_seat, but those don't actually own
|
||||
* their sprite, so the match doesn't mean a lot.
|
||||
*/
|
||||
if (master->lastSlave != get_pointer_device(xwl_seat))
|
||||
return FALSE;
|
||||
return !pointer_crossing;
|
||||
|
||||
/* 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
|
||||
|
|
@ -3269,7 +3275,7 @@ sprite_check_lost_focus(SpritePtr sprite, WindowPtr window)
|
|||
IsParent(xwl_seat->last_focus_window->toplevel, window)))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
return !pointer_crossing;
|
||||
}
|
||||
|
||||
static WindowPtr
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ struct xwl_seat {
|
|||
struct xwl_window *tablet_focus_window;
|
||||
uint32_t id;
|
||||
uint32_t pointer_enter_serial;
|
||||
uint8_t pointer_enter_count;
|
||||
struct xorg_list link;
|
||||
CursorPtr x_cursor;
|
||||
OsTimerPtr x_cursor_timer;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue