Fix Wayland cursor offset when the cursor shape changes

The wayland protocol spec
https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_pointer

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.

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
This commit is contained in:
Waris Boonyasiriwat 2021-05-12 00:30:14 -07:00
parent 9a3a8bc267
commit fc6e6910d7
4 changed files with 10 additions and 5 deletions

View File

@ -229,6 +229,7 @@ information on what to include when reporting a bug.
- [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder - [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder
(#1798) (#1798)
- [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792) - [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792)
- [Wayland] Bugfix: Non-arrow cursors are offset from the hotspot (#1706)
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
- [NSGL] Removed enforcement of forward-compatible flag for core contexts - [NSGL] Removed enforcement of forward-compatible flag for core contexts
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer - [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
@ -455,7 +456,7 @@ skills.
- Torsten Walluhn - Torsten Walluhn
- Patrick Walton - Patrick Walton
- Xo Wang - Xo Wang
- Waris - Waris Boonyasiriwat
- Jay Weisskopf - Jay Weisskopf
- Frank Wille - Frank Wille
- Andy Williams - Andy Williams
@ -470,6 +471,8 @@ skills.
- Jonas Ådahl - Jonas Ådahl
- Lasse Öörni - Lasse Öörni
- Leonard König - Leonard König
- Koray Kilinc
- Joseph Chua
- All the unmentioned and anonymous contributors in the GLFW community, for bug - All the unmentioned and anonymous contributors in the GLFW community, for bug
reports, patches, feedback, testing and encouragement reports, patches, feedback, testing and encouragement

View File

@ -105,6 +105,7 @@ static void pointerHandleEnter(void* data,
window->wl.decorations.focus = focus; window->wl.decorations.focus = focus;
_glfw.wl.serial = serial; _glfw.wl.serial = serial;
_glfw.wl.pointerEnterSerial = serial;
_glfw.wl.pointerFocus = window; _glfw.wl.pointerFocus = window;
window->wl.hovered = GLFW_TRUE; window->wl.hovered = GLFW_TRUE;
@ -164,7 +165,7 @@ static void setCursor(_GLFWwindow* window, const char* name)
buffer = wl_cursor_image_get_buffer(image); buffer = wl_cursor_image_get_buffer(image);
if (!buffer) if (!buffer)
return; return;
wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial, wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial,
surface, surface,
image->hotspot_x / scale, image->hotspot_x / scale,
image->hotspot_y / scale); image->hotspot_y / scale);

View File

@ -245,6 +245,7 @@ typedef struct _GLFWlibraryWayland
const char* cursorPreviousName; const char* cursorPreviousName;
int cursorTimerfd; int cursorTimerfd;
uint32_t serial; uint32_t serial;
uint32_t pointerEnterSerial;
int32_t keyboardRepeatRate; int32_t keyboardRepeatRate;
int32_t keyboardRepeatDelay; int32_t keyboardRepeatDelay;

View File

@ -675,7 +675,7 @@ static void setCursorImage(_GLFWwindow* window,
cursorWayland->yhot = image->hotspot_y; 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, surface,
cursorWayland->xhot / scale, cursorWayland->xhot / scale,
cursorWayland->yhot / scale); cursorWayland->yhot / scale);
@ -1440,7 +1440,7 @@ static void lockPointer(_GLFWwindow* window)
window->wl.pointerLock.relativePointer = relativePointer; window->wl.pointerLock.relativePointer = relativePointer;
window->wl.pointerLock.lockedPointer = lockedPointer; 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); NULL, 0, 0);
} }
@ -1504,7 +1504,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
} }
else if (window->cursorMode == GLFW_CURSOR_HIDDEN) 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);
} }
} }