[Bf-blender-cvs] [dc2736a7dcf] grab_walk_fix: Fix Windows cursor wrap jumps.
Nicholas Rishel
noreply at git.blender.org
Sat Jul 24 00:27:51 CEST 2021
Commit: dc2736a7dcf11ef393ff78c76d61608fa9bd2f47
Author: Nicholas Rishel
Date: Fri Jul 16 15:08:48 2021 -0700
Branches: grab_walk_fix
https://developer.blender.org/rBdc2736a7dcf11ef393ff78c76d61608fa9bd2f47
Fix Windows cursor wrap jumps.
===================================================================
M intern/ghost/intern/GHOST_SystemWin32.cpp
M intern/ghost/intern/GHOST_WindowWin32.cpp
M intern/ghost/intern/GHOST_WindowWin32.h
===================================================================
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index d0ca53e593b..65b7380c959 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1094,10 +1094,12 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
system->getCursorPosition(x_screen, y_screen);
+ int32_t x_accum = 0;
+ int32_t y_accum = 0;
+
if (window->getCursorGrabModeIsWarp()) {
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. */
@@ -1111,29 +1113,41 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
window->getCursorGrabAccum(x_accum, y_accum);
if (x_new != x_screen || y_new != y_screen) {
- /* When wrapping we don't need to add an event because the setCursorPosition call will cause
- * a new event after. */
system->setCursorPosition(x_new, y_new); /* wrap */
- window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new));
+
+ /* We may be in an event before cursor wrap has taken effect */
+ if (window->m_activeWarpX >= 0 && x_new - x_screen < 0 ||
+ window->m_activeWarpX <= 0 && x_new - x_screen > 0) {
+ x_accum = x_accum + (x_screen - x_new);
+ }
+
+ if (window->m_activeWarpY >= 0 && y_new - y_screen < 0 ||
+ window->m_activeWarpY <= 0 && y_new - y_screen > 0) {
+ y_accum = y_accum + (y_screen - y_new);
+ }
+
+ window->setCursorGrabAccum(x_accum, y_accum);
+
+ window->m_activeWarpX = x_new - x_screen;
+ window->m_activeWarpY = y_new - y_screen;
+
+ /* When wrapping we don't need to add an event because the setCursorPosition call will cause
+ * a new event after. We also need to skip outdated messages while warp is active to prevent
+ * applying cursor accumulation to old coordinates. */
+ return NULL;
}
else {
- return new GHOST_EventCursor(system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x_screen + x_accum,
- y_screen + y_accum,
- GHOST_TABLET_DATA_NONE);
+ window->m_activeWarpX = 0;
+ window->m_activeWarpY = 0;
}
}
- else {
- return new GHOST_EventCursor(system->getMilliSeconds(),
- GHOST_kEventCursorMove,
- window,
- x_screen,
- y_screen,
- GHOST_TABLET_DATA_NONE);
- }
- return NULL;
+
+ return new GHOST_EventCursor(system->getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ x_screen + x_accum,
+ y_screen + y_accum,
+ GHOST_TABLET_DATA_NONE);
}
void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam)
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index b5d0fd8e6db..084b9677fab 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -75,6 +75,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_isDialog(dialog),
m_hasMouseCaptured(false),
m_hasGrabMouse(false),
+ m_activeWarpX(0),
+ m_activeWarpY(0),
m_nPressedButtons(0),
m_customCursor(0),
m_wantAlphaBackground(alphaBackground),
@@ -820,6 +822,8 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode
if (mode != GHOST_kGrabNormal) {
m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
setCursorGrabAccum(0, 0);
+ m_activeWarpX = 0;
+ m_activeWarpY = 0;
if (mode == GHOST_kGrabHide)
setWindowCursorVisibility(false);
@@ -843,6 +847,8 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode
/* Almost works without but important otherwise the mouse GHOST location
* can be incorrect on exit. */
setCursorGrabAccum(0, 0);
+ m_activeWarpX = 0;
+ m_activeWarpY = 0;
m_cursorGrabBounds.m_l = m_cursorGrabBounds.m_r = -1; /* disable */
updateMouseCapture(OperatorUngrab);
}
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index ed5292f1712..306398618cd 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -307,6 +307,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
/** True if the mouse is either over or captured by the window. */
bool m_mousePresent;
+ /** Active cursor warp in x axis. */
+ int32_t m_activeWarpX;
+ /** Active cursor warp in y axis. */
+ int32_t m_activeWarpY;
/** True if the window currently resizing. */
bool m_inLiveResize;
More information about the Bf-blender-cvs
mailing list