[Bf-blender-cvs] [b87bcd3f8fe] blender-v3.4-release: Fix T102346: Mouse escapes window during walk navigation

Campbell Barton noreply at git.blender.org
Fri Dec 16 16:03:32 CET 2022


Commit: b87bcd3f8fe132b3cb99e5f17e77d8eca7f73d6f
Author: Campbell Barton
Date:   Thu Dec 15 11:57:00 2022 +1100
Branches: blender-v3.4-release
https://developer.blender.org/rBb87bcd3f8fe132b3cb99e5f17e77d8eca7f73d6f

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 fcb4f549353..108f986d5cd 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