From e7758c506dfcf258566f866c761c1b6bd7d98011 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 --- 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 cb19510a..5d9ff571 100644 --- a/README.md +++ b/README.md @@ -246,6 +246,7 @@ information on what to include when reporting a bug. (#1798) - [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792) - [Wayland] Bugfix: Some keys were not repeating in Wayland (#1908) + - [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706,#1899) - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [NSGL] Removed enforcement of forward-compatible flag for core contexts @@ -298,6 +299,7 @@ skills. - Denis Bernard - Doug Binks - blanco + - Waris Boonyasiriwat - Kyle Brenneman - Rok Breulj - Kai Burjack @@ -306,6 +308,7 @@ skills. - David Carlier - Arturo Castro - Chi-kwan Chan + - Joseph Chua - Ian Clarkson - Michał Cichoń - Lambert Clara @@ -481,7 +484,6 @@ skills. - Torsten Walluhn - Patrick Walton - Xo Wang - - Waris - Jay Weisskopf - Frank Wille - Andy Williams diff --git a/src/wl_init.c b/src/wl_init.c index ac938795..2c73a7a9 100644 --- a/src/wl_init.c +++ b/src/wl_init.c @@ -118,6 +118,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; @@ -177,7 +178,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 a24943c9..d6017513 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -317,6 +317,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 618c8e7f..06cd7084 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -683,7 +683,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); @@ -1455,7 +1455,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); } @@ -1519,7 +1519,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); } }