From 00a663dafd3bc214181a2987af1f5dac81e3b053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Apr 2023 22:47:18 +0200 Subject: [PATCH 1/3] Wayland: Fix fallback decorations emitting errors A GLFW_CURSOR_UNAVAILABLE error would be emitted each time the cursor moved over the fallback decorations if the standard cursor shape appropriate for that part was missing on the system. These errors served no useful purpose and have been removed. --- README.md | 1 + src/wl_window.c | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7815c72a..e3d18ec8 100644 --- a/README.md +++ b/README.md @@ -384,6 +384,7 @@ information on what to include when reporting a bug. decorations - [Wayland] Bugfix: Connecting a mouse after `glfwInit` would segfault (#1450) - [Wayland] Bugfix: Joysticks connected after `glfwInit` were not detected (#2198) + - [Wayland] Bugfix: Fallback decorations emitted `GLFW_CURSOR_UNAVAILABLE` errors - [POSIX] Removed use of deprecated function `gettimeofday` - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [Linux] Bugfix: Joysticks without buttons were ignored (#2042,#2043) diff --git a/src/wl_window.c b/src/wl_window.c index 52d3b9eb..43090112 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1327,11 +1327,8 @@ static void setCursor(_GLFWwindow* window, const char* name) cursor = wl_cursor_theme_get_cursor(theme, name); if (!cursor) - { - _glfwInputError(GLFW_CURSOR_UNAVAILABLE, - "Wayland: Standard cursor shape unavailable"); return; - } + // TODO: handle animated cursors too. image = cursor->images[0]; From 6b48f2be97057cf436c6eb3059bbbfdcb5f66d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Apr 2023 22:53:17 +0200 Subject: [PATCH 2/3] Wayland: Merge function called once This brings together the two halves of the cursor setting logic for the fallback decorations. --- src/wl_window.c | 85 ++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index 43090112..fe0a2b79 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1308,48 +1308,6 @@ static void pointerHandleLeave(void* userData, _glfwInputCursorEnter(window, GLFW_FALSE); } -static void setCursor(_GLFWwindow* window, const char* name) -{ - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; - struct wl_surface* surface = _glfw.wl.cursorSurface; - struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; - int scale = 1; - - if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI) - { - // We only support up to scale=2 for now, since libwayland-cursor - // requires us to load a different theme for each size. - scale = 2; - theme = _glfw.wl.cursorThemeHiDPI; - } - - cursor = wl_cursor_theme_get_cursor(theme, name); - if (!cursor) - return; - - // TODO: handle animated cursors too. - image = cursor->images[0]; - - if (!image) - return; - - buffer = wl_cursor_image_get_buffer(image); - if (!buffer) - return; - wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, - surface, - image->hotspot_x / scale, - image->hotspot_y / scale); - wl_surface_set_buffer_scale(surface, scale); - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); - wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; -} - static void pointerHandleMotion(void* userData, struct wl_pointer* pointer, uint32_t time, @@ -1405,8 +1363,49 @@ static void pointerHandleMotion(void* userData, default: assert(0); } + if (_glfw.wl.cursorPreviousName != cursorName) - setCursor(window, cursorName); + { + struct wl_buffer* buffer; + struct wl_cursor* cursor; + struct wl_cursor_image* image; + struct wl_surface* surface = _glfw.wl.cursorSurface; + struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; + int scale = 1; + + if (window->wl.contentScale > 1 && _glfw.wl.cursorThemeHiDPI) + { + // We only support up to scale=2 for now, since libwayland-cursor + // requires us to load a different theme for each size. + scale = 2; + theme = _glfw.wl.cursorThemeHiDPI; + } + + cursor = wl_cursor_theme_get_cursor(theme, name); + if (!cursor) + return; + + // TODO: handle animated cursors too. + image = cursor->images[0]; + + if (!image) + return; + + buffer = wl_cursor_image_get_buffer(image); + if (!buffer) + return; + + wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.pointerEnterSerial, + surface, + image->hotspot_x / scale, + image->hotspot_y / scale); + wl_surface_set_buffer_scale(surface, scale); + wl_surface_attach(surface, buffer, 0, 0); + wl_surface_damage(surface, 0, 0, + image->width, image->height); + wl_surface_commit(surface); + _glfw.wl.cursorPreviousName = name; + } } static void pointerHandleButton(void* userData, From 3eaf1255b29fdf5c2895856c7be7d7185ef2b241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Tue, 25 Apr 2023 22:59:25 +0200 Subject: [PATCH 3/3] Wayland: Cleanup Update naming and declarations to current standard. --- src/wl_window.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/wl_window.c b/src/wl_window.c index fe0a2b79..7b9e3d0d 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1315,47 +1315,47 @@ static void pointerHandleMotion(void* userData, wl_fixed_t sy) { _GLFWwindow* window = _glfw.wl.pointerFocus; - const char* cursorName = NULL; - double x, y; - if (!window) return; if (window->cursorMode == GLFW_CURSOR_DISABLED) return; - x = wl_fixed_to_double(sx); - y = wl_fixed_to_double(sy); - window->wl.cursorPosX = x; - window->wl.cursorPosY = y; + + const double xpos = wl_fixed_to_double(sx); + const double ypos = wl_fixed_to_double(sy); + window->wl.cursorPosX = xpos; + window->wl.cursorPosY = ypos; + + const char* cursorName = NULL; switch (window->wl.decorations.focus) { case GLFW_MAIN_WINDOW: _glfw.wl.cursorPreviousName = NULL; - _glfwInputCursorPos(window, x, y); + _glfwInputCursorPos(window, xpos, ypos); return; case GLFW_TOP_DECORATION: - if (y < GLFW_BORDER_SIZE) + if (ypos < GLFW_BORDER_SIZE) cursorName = "n-resize"; else cursorName = "left_ptr"; break; case GLFW_LEFT_DECORATION: - if (y < GLFW_BORDER_SIZE) + if (ypos < GLFW_BORDER_SIZE) cursorName = "nw-resize"; else cursorName = "w-resize"; break; case GLFW_RIGHT_DECORATION: - if (y < GLFW_BORDER_SIZE) + if (ypos < GLFW_BORDER_SIZE) cursorName = "ne-resize"; else cursorName = "e-resize"; break; case GLFW_BOTTOM_DECORATION: - if (x < GLFW_BORDER_SIZE) + if (xpos < GLFW_BORDER_SIZE) cursorName = "sw-resize"; - else if (x > window->wl.width + GLFW_BORDER_SIZE) + else if (xpos > window->wl.width + GLFW_BORDER_SIZE) cursorName = "se-resize"; else cursorName = "s-resize"; @@ -1366,9 +1366,6 @@ static void pointerHandleMotion(void* userData, if (_glfw.wl.cursorPreviousName != cursorName) { - struct wl_buffer* buffer; - struct wl_cursor* cursor; - struct wl_cursor_image* image; struct wl_surface* surface = _glfw.wl.cursorSurface; struct wl_cursor_theme* theme = _glfw.wl.cursorTheme; int scale = 1; @@ -1381,17 +1378,16 @@ static void pointerHandleMotion(void* userData, theme = _glfw.wl.cursorThemeHiDPI; } - cursor = wl_cursor_theme_get_cursor(theme, name); + struct wl_cursor* cursor = wl_cursor_theme_get_cursor(theme, cursorName); if (!cursor) return; // TODO: handle animated cursors too. - image = cursor->images[0]; - + struct wl_cursor_image* image = cursor->images[0]; if (!image) return; - buffer = wl_cursor_image_get_buffer(image); + struct wl_buffer* buffer = wl_cursor_image_get_buffer(image); if (!buffer) return; @@ -1401,10 +1397,10 @@ static void pointerHandleMotion(void* userData, image->hotspot_y / scale); wl_surface_set_buffer_scale(surface, scale); wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, - image->width, image->height); + wl_surface_damage(surface, 0, 0, image->width, image->height); wl_surface_commit(surface); - _glfw.wl.cursorPreviousName = name; + + _glfw.wl.cursorPreviousName = cursorName; } }