diff options
author | Campbell Barton <campbell@blender.org> | 2022-06-12 17:15:14 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-06-12 17:20:31 +0300 |
commit | 37097ae62a9c13fca81f3fb6d1342057b2f17763 (patch) | |
tree | 7cab4526f3cced6cb162182464f7b9e7786e64f9 /intern | |
parent | 3ac656d36779ef81e451544bbf7641870f4854d9 (diff) |
Fix T98714: Cursor grab restores to the initial location in Wayland
While Wayland can't warp the cursor, it can set a hint for the cursor
restore location when removing the lock.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index fd7c0f8b6b6..c3300c82b55 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -2131,6 +2131,37 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo input->relative_pointer = nullptr; } if (input->locked_pointer) { + /* Request location to restore to. */ + if (mode_current == GHOST_kGrabWrap) { + GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(get_window(surface)); + GHOST_Rect bounds; + int x_new = input->x, y_new = input->y; + + /* Fallback to window bounds. */ + if (win->getCursorGrabBounds(bounds) == GHOST_kFailure) { + ((GHOST_Window *)win)->getClientBounds(bounds); + } + bounds.wrapPoint(x_new, y_new, 0, win->getCursorGrabAxis()); + + /* Push an event so the new location is registered. */ + if ((x_new != input->x) || (y_new != input->y)) { + input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(), + GHOST_kEventCursorMove, + win, + x_new, + y_new, + GHOST_TABLET_DATA_NONE)); + } + input->x = x_new; + input->y = y_new; + + const int scale = win->scale(); + zwp_locked_pointer_v1_set_cursor_position_hint(input->locked_pointer, + wl_fixed_from_int(x_new) / scale, + wl_fixed_from_int(y_new) / scale); + wl_surface_commit(surface); + } + zwp_locked_pointer_v1_destroy(input->locked_pointer); input->locked_pointer = nullptr; } |