diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index 10fb059df8b..6ca99ba75e6 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -8448,9 +8448,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; } @@ -8526,6 +8548,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 @@ -9098,7 +9123,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 152049ad982..66d75d0ff76 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]; }