From c1a7d6f24d5adf23966c36d9d699df1832ba6089 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Oct 2025 00:46:40 +0000 Subject: [PATCH] Docs: update cursor warp comment, note vulkan buffer size bug Cursor warping is now supported by Wayland protocols, however I'd rather not use it given the issues it's caused on other platforms. --- intern/ghost/intern/GHOST_SystemWayland.cc | 34 +++++++++++++++++++--- intern/ghost/intern/GHOST_WindowWayland.cc | 4 +++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index 1221a57e34f..fd815460615 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -8439,9 +8439,31 @@ static GHOST_TSuccess setCursorPositionClientRelative_impl(GWL_Seat *seat, const int32_t x, const int32_t y) { - /* NOTE: WAYLAND doesn't support warping the cursor. - * However when grab is enabled, we already simulate a cursor location - * so that can be set to a new location. */ + /* NOTE(@ideasman42): Regarding Cursor Warp Support: + * + * Before Wayland Protocols 1.45, (`wp_pointer_warp_v1`) cursor warping wasn't supported, + * although at time of writing (2025) no mainstream compositors support it. + * As an alternative, a software cursor is used which can be warped while "grabbed" + * (see `relative_pointer` & `pointer_constraints`). + * Other backends use warping to implement grabbing, + * however this is error-prone with issues such as: + * + * - Fast motion can exit the window. + * - Absolute input devices don't work with warping, causing erratic cursor motion glitches. + * - Motion events may be in the queue which need to be handled before the warp is handled. + * + * These issues can be mitigated but avoiding problems gets involved and isn't foolproof: + * Input may be clamped, tablets can be assumed absolute & motion event timestamps + * can be used to detect events that were in the queue before the artificial warp motion. + * + * Given the trouble cursor warping has caused on other platforms over the years + * I believe we're better off avoiding cursor warping (`wp_pointer_warp_v1`) + * and accept limited support for warping. + * + * See: #134818, #113511, #102346, #89399, #82870, #49498. */ + + /* When grab is enabled, we already simulate a cursor location, + * so cursor warping can be supported in this case. */ if (!seat->wp.relative_pointer) { return GHOST_kFailure; } @@ -8517,6 +8539,9 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) co GHOST_TSuccess GHOST_SystemWayland::setCursorPosition(const int32_t x, const int32_t y) { + /* See comments in the body of #setCursorPositionClientRelative_impl + * for an explanation of the state of this functionality. */ + #ifdef USE_EVENT_BACKGROUND_THREAD std::lock_guard lock_server_guard{*server_mutex}; #endif @@ -9089,7 +9114,8 @@ GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const /* WAYLAND cannot precisely place windows among multiple monitors. */ GHOST_kCapabilityMultiMonitorPlacement | /* WAYLAND doesn't support setting the cursor position directly, - * this is an intentional choice, forcing us to use a software cursor in this case. */ + * this is an intentional choice, forcing us to use a software cursor in this case. + * For details see comments in: #setCursorPositionClientRelative_impl. */ GHOST_kCapabilityCursorWarp | /* Some drivers don't support front-buffer reading, see: #98462 & #106264. * diff --git a/intern/ghost/intern/GHOST_WindowWayland.cc b/intern/ghost/intern/GHOST_WindowWayland.cc index 3d7308fdd56..fd5c47344da 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cc +++ b/intern/ghost/intern/GHOST_WindowWayland.cc @@ -509,6 +509,10 @@ static void gwl_window_resize_for_backend(GWL_Window *win, const int32_t size[2] #endif #ifdef WITH_VULKAN_BACKEND if (win->ghost_context_type == GHOST_kDrawingContextTypeVulkan) { + /* FIXME: unlike EGL, the underlying surface is not resized + * which is needed in situations where the buffer scale changes + * (moving the window to an output with a different scale for e.g.). + * Failing to do so can exit with a protocol error, see: #148243. */ win->backend.vulkan_window_info->size[0] = size[0]; win->backend.vulkan_window_info->size[1] = size[1]; }