[Bf-blender-cvs] [0240b895994] master: Fix T102346: Mouse escapes window during walk navigation

Campbell Barton noreply at git.blender.org
Thu Dec 15 02:17:55 CET 2022


Commit: 0240b895994aa58258db6897ae0d6478da7fce5f
Author: Campbell Barton
Date:   Thu Dec 15 11:57:00 2022 +1100
Branches: master
https://developer.blender.org/rB0240b895994aa58258db6897ae0d6478da7fce5f

Fix T102346: Mouse escapes window during walk navigation

This is an alternative fix to [0] which kept the cursor centrally
located as part of GHOST cursor grabbing which caused T102792.

Now this is done as part of walk mode as it's the operator that most
often ran into this problem although ideally this would be handled by
GHOST - but that's a much bigger project.

[0]: 9fd6dae7939a65b67045749a0eadeb6864ded183

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

M	source/blender/editors/space_view3d/view3d_navigate_walk.c

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

diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c
index 2a426bfd480..a1d293dc53f 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_walk.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c
@@ -55,6 +55,14 @@
 
 #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
  * \{ */
@@ -221,6 +229,10 @@ 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. */
@@ -579,6 +591,10 @@ 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(
@@ -594,7 +610,31 @@ 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);
 
-  WM_cursor_grab_enable(win, 0, true, NULL);
+#ifdef USE_CURSOR_WARP_HACK
+  if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) {
+    int bounds[4];
+    const rcti *rect = &walk->region->winrct;
+    const int center[2] = {BLI_rcti_cent_x(rect), BLI_rcti_cent_y(rect)};
+    const int size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
+    const int div = 4; /* Where 2 is the region size. */
+
+    bounds[0] = center[0] - (size[0] / div); /* X-min. */
+    bounds[1] = center[1] + (size[1] / div); /* Y-max. */
+    bounds[2] = center[0] + (size[0] / div); /* X-max. */
+    bounds[3] = center[1] - (size[1] / div); /* Y-min. */
+
+    WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, false, bounds);
+
+    /* 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, 0, true, NULL);
+  }
 
   return 1;
 }
@@ -643,7 +683,16 @@ static int walkEnd(bContext *C, WalkInfo *walk)
   }
 #endif
 
-  WM_cursor_grab_enable(win, 0, true, NULL);
+  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);



More information about the Bf-blender-cvs mailing list