[Bf-blender-cvs] [5d1ed47d6c0] geometry-nodes-simulation: Fix T103253: Infinite drag of number buttons is broken on WIN32

Campbell Barton noreply at git.blender.org
Mon Dec 19 19:05:24 CET 2022


Commit: 5d1ed47d6c0761bc62723ec4da6cadd662fb3c2e
Author: Campbell Barton
Date:   Fri Dec 16 18:37:44 2022 +1100
Branches: geometry-nodes-simulation
https://developer.blender.org/rB5d1ed47d6c0761bc62723ec4da6cadd662fb3c2e

Fix T103253: Infinite drag of number buttons is broken on WIN32

Recent reverting of changes to cursor grabbing intended to match
Blender 3.3 release. This is the case for 3.4x branch, however there is
an additional change to grabbing on WIN32 by Germano [0] which is a
significant improvement on old grabbing logic for Windows.
So instead of matching 3.3x behavior, restore logic that keeps
the cursor centered while grabbing & hidden.

This re-introduces T102792 issue displaying the paint-brush while
dragging buttons, this will have to be solved separately.

Re-apply [1] & [2], revert [3] & [4].

[4]: a3a9459050a96e75138b3441c069898f211f179c
[0]: 9fd6dae7939a65b67045749a0eadeb6864ded183
[1]: 4cac8025f00798938813f52dcb117be83db97f22
[2]: 230744d6fd96dcf5afe66a8f9b9f6f8bbe1f41bb
[3]: 0240b895994aa58258db6897ae0d6478da7fce5f

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

M	intern/ghost/intern/GHOST_SystemWin32.cpp
M	intern/ghost/intern/GHOST_SystemX11.cpp
M	source/blender/editors/space_view3d/view3d_navigate_walk.c
M	source/tools

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

diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index d005eec3036..8cb007a756a 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1075,16 +1075,45 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
     int32_t x_new = x_screen;
     int32_t y_new = y_screen;
     int32_t x_accum, y_accum;
-    GHOST_Rect bounds;
 
-    /* Fallback to window bounds. */
-    if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
-      window->getClientBounds(bounds);
-    }
+    /* Warp within bounds. */
+    {
+      GHOST_Rect bounds;
+      int32_t bounds_margin = 0;
+      GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone;
+
+      if (window->getCursorGrabMode() == GHOST_kGrabHide) {
+        window->getClientBounds(bounds);
+
+        /* WARNING(@campbellbarton): The current warping logic fails to warp on every event,
+         * so the box needs to small enough not to let the cursor escape the window but large
+         * enough that the cursor isn't being warped every time.
+         * If this was not the case it would be less trouble to simply warp the cursor to the
+         * center of the screen on every motion, see: D16558 (alternative fix for T102346). */
+        const int32_t subregion_div = 4; /* One quarter of the region. */
+        const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
+        const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
+        /* Shrink the box to prevent the cursor escaping. */
+        bounds.m_l = center[0] - (size[0] / (subregion_div * 2));
+        bounds.m_r = center[0] + (size[0] / (subregion_div * 2));
+        bounds.m_t = center[1] - (size[1] / (subregion_div * 2));
+        bounds.m_b = center[1] + (size[1] / (subregion_div * 2));
+        bounds_margin = 0;
+        bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY);
+      }
+      else {
+        /* Fallback to window bounds. */
+        if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
+          window->getClientBounds(bounds);
+        }
+        bounds_margin = 2;
+        bounds_axis = window->getCursorGrabAxis();
+      }
 
-    /* Could also clamp to screen bounds wrap with a window outside the view will
-     * fail at the moment. Use inset in case the window is at screen bounds. */
-    bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis());
+      /* Could also clamp to screen bounds wrap with a window outside the view will
+       * fail at the moment. Use inset in case the window is at screen bounds. */
+      bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis);
+    }
 
     window->getCursorGrabAccum(x_accum, y_accum);
     if (x_new != x_screen || y_new != y_screen) {
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 72f34dac52e..3122a7ce562 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -917,16 +917,47 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
         int32_t x_new = xme.x_root;
         int32_t y_new = xme.y_root;
         int32_t x_accum, y_accum;
-        GHOST_Rect bounds;
 
-        /* fallback to window bounds */
-        if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
-          window->getClientBounds(bounds);
-        }
+        /* Warp within bounds. */
+        {
+          GHOST_Rect bounds;
+          int32_t bounds_margin = 0;
+          GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone;
+
+          if (window->getCursorGrabMode() == GHOST_kGrabHide) {
+            window->getClientBounds(bounds);
+
+            /* TODO(@campbellbarton): warp the cursor to `window->getCursorGrabInitPos`,
+             * on every motion event, see: D16557 (alternative fix for T102346). */
+            const int32_t subregion_div = 4; /* One quarter of the region. */
+            const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
+            const int32_t center[2] = {
+                (bounds.m_l + bounds.m_r) / 2,
+                (bounds.m_t + bounds.m_b) / 2,
+            };
+            /* Shrink the box to prevent the cursor escaping. */
+            bounds.m_l = center[0] - (size[0] / (subregion_div * 2));
+            bounds.m_r = center[0] + (size[0] / (subregion_div * 2));
+            bounds.m_t = center[1] - (size[1] / (subregion_div * 2));
+            bounds.m_b = center[1] + (size[1] / (subregion_div * 2));
+            bounds_margin = 0;
+            bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY);
+          }
+          else {
+            /* Fallback to window bounds. */
+            if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
+              window->getClientBounds(bounds);
+            }
+            /* Could also clamp to screen bounds wrap with a window outside the view will
+             * fail at the moment. Use offset of 8 in case the window is at screen bounds. */
+            bounds_margin = 8;
+            bounds_axis = window->getCursorGrabAxis();
+          }
 
-        /* Could also clamp to screen bounds wrap with a window outside the view will
-         * fail at the moment. Use offset of 8 in case the window is at screen bounds. */
-        bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis());
+          /* Could also clamp to screen bounds wrap with a window outside the view will
+           * fail at the moment. Use inset in case the window is at screen bounds. */
+          bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis);
+        }
 
         window->getCursorGrabAccum(x_accum, y_accum);
 
diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c
index 5606527a5fd..9aa8328287b 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_walk.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c
@@ -55,14 +55,6 @@
 
 #define USE_TABLET_SUPPORT
 
-/**
- * Use alternative behavior when cursor warp is supported
- * to prevent the cursor escaping the window bounds, see: T102346.
- *
- * \note this is not needed if cursor positioning is not supported.
- */
-#define USE_CURSOR_WARP_HACK
-
 /* -------------------------------------------------------------------- */
 /** \name Modal Key-map
  * \{ */
@@ -229,10 +221,6 @@ typedef struct WalkInfo {
   bool need_rotation_keyframe;
   bool need_translation_keyframe;
 
-#ifdef USE_CURSOR_WARP_HACK
-  bool need_modal_cursor_warp_hack;
-#endif
-
   /** Previous 2D mouse values. */
   int prev_mval[2];
   /** Initial mouse location. */
@@ -591,10 +579,6 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int
   walk->need_rotation_keyframe = false;
   walk->need_translation_keyframe = false;
 
-#ifdef USE_CURSOR_WARP_HACK
-  walk->need_modal_cursor_warp_hack = false;
-#endif
-
   walk->time_lastdraw = PIL_check_seconds_timer();
 
   walk->draw_handle_pixel = ED_region_draw_cb_activate(
@@ -610,32 +594,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int
   copy_v2_v2_int(walk->init_mval, mval);
   copy_v2_v2_int(walk->prev_mval, mval);
 
-#ifdef USE_CURSOR_WARP_HACK
-  if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) {
-    const rcti *winrct = &walk->region->winrct;
-    const int center[2] = {BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct)};
-    const int size[2] = {BLI_rcti_size_x(winrct), BLI_rcti_size_y(winrct)};
-    const int div = 4; /* Where 2 is the region size. */
-
-    const rcti wrap_region = {
-        .xmin = center[0] - (size[0] / div),
-        .xmax = center[0] + (size[0] / div),
-        .ymin = center[1] - (size[1] / div),
-        .ymax = center[1] + (size[1] / div),
-    };
-
-    WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, &wrap_region, false);
-
-    /* Important to hide afterwards (not part of grabbing),
-     * since enabling cursor and hiding at the same time ignores bounds. */
-    WM_cursor_modal_set(win, WM_CURSOR_NONE);
-    walk->need_modal_cursor_warp_hack = true;
-  }
-  else
-#endif /* USE_CURSOR_WARP_HACK */
-  {
-    WM_cursor_grab_enable(win, WM_CURSOR_WRAP_NONE, NULL, true);
-  }
+  WM_cursor_grab_enable(win, 0, NULL, true);
 
   return 1;
 }
@@ -686,15 +645,6 @@ static int walkEnd(bContext *C, WalkInfo *walk)
 
   WM_cursor_grab_disable(win, NULL);
 
-#ifdef USE_CURSOR_WARP_HACK
-  if (walk->need_modal_cursor_warp_hack) {
-    WM_cursor_warp(win,
-                   walk->region->winrct.xmin + walk->init_mval[0],
-                   walk->region->winrct.ymin + walk->init_mval[1]);
-    WM_cursor_modal_restore(win);
-  }
-#endif
-
   if (walk->state == WALK_CONFIRM) {
     MEM_freeN(walk);
     return OPERATOR_FINISHED;
diff --git a/source/tools b/source/tools
index dfa16042bf7..fdfa2fcb949 160000
--- a/source/tools
+++ b/source/tools
@@ -1 +1 @@
-Subproject commit dfa16042bf7149475ad318d29a8202d969982abb
+Subproject commit fdfa2fcb9495d87571f2dfe2ae9fa0e032536600



More information about the Bf-blender-cvs mailing list