From 6bb5f5d59d37ac4badd36e661bd3fc10a8cdaa52 Mon Sep 17 00:00:00 2001 From: Waris Boonyasiriwat Date: Wed, 12 May 2021 00:30:14 -0700 Subject: [PATCH] Wayland: Fix cursor offset when shape changes The Wayland protocol spec[1] states that set_cursor must be called with the serial number of the enter event. However, GLFW is passing in the serial number of the latest received event, which does not meet the protocol spec. [1] https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_pointer As a result, set_cursor calls were simply ignored by the compositor. This fix complies with the protocol more closely by specifically caching the enter event serial, and using it for all set_cursor calls. Fixes #1706 Closes #1899 (cherry picked from commit e7758c506dfcf258566f866c761c1b6bd7d98011) --- README.md | 4 +++- src/wl_init.c | 3 ++- src/wl_platform.h | 1 + src/wl_window.c | 6 +++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 40dce879..5cb6d958 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ information on what to include when reporting a bug. related events were emitted - [X11] Bugfix: Changing `GLFW_FLOATING` could leak memory - [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908) + - [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899) - [NSGL] Bugfix: Defining `GL_SILENCE_DEPRECATION` externally caused a duplicate definition warning (#1840) - [EGL] Bugfix: The `GLFW_DOUBLEBUFFER` context attribute was ignored (#1843) @@ -170,6 +171,7 @@ skills. - Denis Bernard - Doug Binks - blanco + - Waris Boonyasiriwat - Kyle Brenneman - Rok Breulj - Kai Burjack @@ -178,6 +180,7 @@ skills. - David Carlier - Arturo Castro - Chi-kwan Chan + - Joseph Chua - Ian Clarkson - Michał Cichoń - Lambert Clara @@ -349,7 +352,6 @@ skills. - Torsten Walluhn - Patrick Walton - Xo Wang - - Waris - Jay Weisskopf - Frank Wille - Richard A. Wilkes diff --git a/src/wl_init.c b/src/wl_init.c index 08ceeada..0ce45a30 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -104,6 +104,7 @@ static void pointerHandleEnter(void* data, window->wl.decorations.focus = focus; _glfw.wl.serial = serial; + _glfw.wl.pointerEnterSerial = serial; _glfw.wl.pointerFocus = window; window->wl.hovered = GLFW_TRUE; @@ -163,7 +164,7 @@ static void setCursor(_GLFWwindow* window, const char* name) buffer = wl_cursor_image_get_buffer(image); if (!buffer) return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, surface, image->hotspot_x / scale, image->hotspot_y / scale); diff --git a/src/wl_platform.h b/src/wl_platform.h index 41a7fdfa..755f4980 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -252,6 +252,7 @@ typedef struct _GLFWlibraryWayland const char* cursorPreviousName; int cursorTimerfd; uint32_t serial; + uint32_t pointerEnterSerial; int32_t keyboardRepeatRate; int32_t keyboardRepeatDelay; diff --git a/src/wl_window.c b/src/wl_window.c index d10861cd..db32f449 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -796,7 +796,7 @@ static void setCursorImage(_GLFWwindow* window, cursorWayland->yhot = image->hotspot_y; } - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, surface, cursorWayland->xhot / scale, cursorWayland->yhot / scale); @@ -1547,7 +1547,7 @@ static void lockPointer(_GLFWwindow* window) window->wl.pointerLock.relativePointer = relativePointer; window->wl.pointerLock.lockedPointer = lockedPointer; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0); } @@ -1611,7 +1611,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) } else if (window->cursorMode == GLFW_CURSOR_HIDDEN) { - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, NULL, 0, 0); + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, NULL, 0, 0); } }