Revert "Fix erratic mouse wrapping movement on Windows (2)"

This reverts commit a3a9459050.

And fixes T103337.

a3a9459050 has some flaws and it needs to go through review (See D16803).

Conflicts:
	intern/ghost/intern/GHOST_SystemWin32.cpp
This commit is contained in:
Germano Cavalcante 2022-12-19 10:06:47 -03:00
parent 4cb2204d3a
commit 1a986f7eba
Notes: blender-bot 2023-02-14 10:11:54 +01:00
Referenced by issue #103596, Blender 3.5: Cursor warping usable on windows remote desktop (RDP)
Referenced by issue #103337, Regression: Infinite drag in the 3D viewport sometimes gets stuck on the edge of the screen.
1 changed files with 23 additions and 32 deletions

View File

@ -1061,16 +1061,11 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
int32_t x_screen = screen_co[0], y_screen = screen_co[1];
if (window->getCursorGrabModeIsWarp()) {
static uint64_t last_warp_time = 0;
{
/* WORKAROUND: Check the mouse event timestamp so we can ignore mouse-move events that were
* already in the queue before we changed the cursor position. */
MOUSEMOVEPOINT mp = {x_screen, y_screen};
::GetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &mp, &mp, 1, GMMP_USE_DISPLAY_POINTS);
if (mp.time <= last_warp_time) {
return NULL;
}
}
/* WORKAROUND:
* Sometimes Windows ignores `SetCursorPos()` or `SendInput()` calls or the mouse event is
* outdated. Identify these cases by checking if the cursor is not yet within bounds. */
static bool is_warping_x = false;
static bool is_warping_y = false;
int32_t x_new = x_screen;
int32_t y_new = y_screen;
@ -1117,35 +1112,31 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
window->getCursorGrabAccum(x_accum, y_accum);
if (x_new != x_screen || y_new != y_screen) {
/* WORKAROUND: Store the current time so that we ignore outdated mouse-move events. */
last_warp_time = ::GetTickCount64();
system->setCursorPosition(x_new, y_new); /* wrap */
/* For more control over which timestamp to store in the event, we use `SendInput` instead of
* `SetCursorPos` here.
* It is quite unlikely to happen, but still possible that some event between
* `last_warp_time` and `GHOST_SystemWin32::setCursorPosition` is sent. */
INPUT input[3] = {0};
input[0].type = INPUT_MOUSE;
input[0].mi.dx = (LONG)(x_new * (65535.0f / GetSystemMetrics(SM_CXSCREEN)));
input[0].mi.dy = (LONG)(y_new * (65535.0f / GetSystemMetrics(SM_CYSCREEN)));
input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
input[0].mi.time = last_warp_time;
/* Do not update the accum values if we are an outdated or failed pos-warp event. */
if (!is_warping_x) {
is_warping_x = x_new != x_screen;
if (is_warping_x) {
x_accum += (x_screen - x_new);
}
}
/* Send 3 events with a jitter to make sure Windows does not occasionally and
* inexplicably ignore `SetCursorPos` or `SendInput`. */
input[2] = input[1] = input[0];
input[1].mi.dx += 1;
::SendInput(3, input, sizeof(INPUT));
x_accum += (x_screen - x_new);
y_accum += (y_screen - y_new);
if (!is_warping_y) {
is_warping_y = y_new != y_screen;
if (is_warping_y) {
y_accum += (y_screen - y_new);
}
}
window->setCursorGrabAccum(x_accum, y_accum);
/* When wrapping we don't need to add an event because the `SendInput` call will cause new
* events after. */
/* When wrapping we don't need to add an event because the setCursorPosition call will cause
* a new event after. */
return NULL;
}
is_warping_x = false;
is_warping_y = false;
x_screen += x_accum;
y_screen += y_accum;
}