[Bf-blender-cvs] [ccbf9ee4826] master: Fix un-grab cursor positioning failing for Wayland

Campbell Barton noreply at git.blender.org
Fri Jul 1 10:07:17 CEST 2022


Commit: ccbf9ee48262c6078bcd10817f07c6e3f4bb9a25
Author: Campbell Barton
Date:   Fri Jul 1 18:00:30 2022 +1000
Branches: master
https://developer.blender.org/rBccbf9ee48262c6078bcd10817f07c6e3f4bb9a25

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.

===================================================================

M	intern/ghost/intern/GHOST_SystemWayland.cpp
M	intern/ghost/intern/GHOST_SystemWayland.h
M	intern/ghost/intern/GHOST_WindowWayland.cpp

===================================================================

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)



More information about the Bf-blender-cvs mailing list