diff options
author | Campbell Barton <campbell@blender.org> | 2022-07-01 11:00:30 +0300 |
---|---|---|
committer | Campbell Barton <campbell@blender.org> | 2022-07-01 11:06:20 +0300 |
commit | ccbf9ee48262c6078bcd10817f07c6e3f4bb9a25 (patch) | |
tree | b71e78630e9a170bd2c7d2d161e3b0adc6d68b4f /intern | |
parent | eff62ea8abaccbaa8dab9c00e3780aaa873148d2 (diff) |
Fix un-grab cursor positioning failing for Wayland
UI elements such as sliders & color picker set an un-grab location
which GHOST/Wayland didn't implement.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.cpp | 27 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWayland.h | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWayland.cpp | 2 |
3 files changed, 29 insertions, 1 deletions
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 3a5e524782f..d00c8b34ed7 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -271,6 +271,8 @@ struct input_t { #ifdef USE_GNOME_CONFINE_HACK bool use_pointer_software_confine = false; #endif + /** The cursor location (in pixel-space) when hidden grab started (#GHOST_kGrabHide). */ + wl_fixed_t grab_lock_xy[2] = {0, 0}; struct cursor_t cursor; @@ -3281,6 +3283,7 @@ static input_grab_state_t input_grab_state_from_mode(const GHOST_TGrabCursorMode GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mode, const GHOST_TGrabCursorMode mode_current, + int32_t init_grab_xy[2], wl_surface *surface) { /* Ignore, if the required protocols are not supported. */ @@ -3370,6 +3373,20 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo input->locked_pointer, xy_new[0], xy_new[1]); wl_surface_commit(surface); } + else if (mode_current == GHOST_kGrabHide) { + if ((init_grab_xy[0] != input->grab_lock_xy[0]) || + (init_grab_xy[1] != input->grab_lock_xy[1])) { + GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + const int scale = win->scale(); + const wl_fixed_t xy_next[2] = { + wl_fixed_from_int(init_grab_xy[0]) / scale, + wl_fixed_from_int(init_grab_xy[1]) / scale, + }; + zwp_locked_pointer_v1_set_cursor_position_hint( + input->locked_pointer, xy_next[0], xy_next[1]); + wl_surface_commit(surface); + } + } #ifdef USE_GNOME_CONFINE_HACK else if (mode_current == GHOST_kGrabNormal) { if (was_software_confine) { @@ -3410,6 +3427,16 @@ GHOST_TSuccess GHOST_SystemWayland::setCursorGrab(const GHOST_TGrabCursorMode mo nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); } + if (mode == GHOST_kGrabHide) { + /* Set the initial position to detect any changes when un-grabbing, + * otherwise the unlocked cursor defaults to un-locking in-place. */ + GHOST_WindowWayland *win = GHOST_WindowWayland::from_surface_mut(surface); + const int scale = win->scale(); + init_grab_xy[0] = wl_fixed_to_int(scale * input->pointer.xy[0]); + init_grab_xy[1] = wl_fixed_to_int(scale * input->pointer.xy[1]); + input->grab_lock_xy[0] = init_grab_xy[0]; + input->grab_lock_xy[1] = init_grab_xy[1]; + } } else if (grab_state_next.use_confine) { if (!grab_state_prev.use_confine) { diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index 7fe35146be0..4286aa9d183 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -132,6 +132,7 @@ class GHOST_SystemWayland : public GHOST_System { GHOST_TSuccess setCursorGrab(const GHOST_TGrabCursorMode mode, const GHOST_TGrabCursorMode mode_current, + int32_t init_grab_xy[2], wl_surface *surface); /* WAYLAND direct-data access. */ diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 159cd808c0c..00d75d62c9f 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -484,7 +484,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mode) { - return m_system->setCursorGrab(mode, m_cursorGrab, w->wl_surface); + return m_system->setCursorGrab(mode, m_cursorGrab, m_cursorGrabInitPos, w->wl_surface); } GHOST_TSuccess GHOST_WindowWayland::setWindowCursorShape(GHOST_TStandardCursor shape) |