[Bf-blender-cvs] [a8f7bfa2136] grab_walk_fix: Continuous grab mostly working for Wintab and Windows Ink. Some minor race conditions for Windows Ink when a pen quickly enters then leaves range shortly after a mouse event.
Nicholas Rishel
noreply at git.blender.org
Mon Sep 6 05:20:26 CEST 2021
Commit: a8f7bfa21366de1bc37c9aef29f3555b61249964
Author: Nicholas Rishel
Date: Sat Sep 4 18:20:40 2021 -0700
Branches: grab_walk_fix
https://developer.blender.org/rBa8f7bfa21366de1bc37c9aef29f3555b61249964
Continuous grab mostly working for Wintab and Windows Ink. Some minor race conditions for Windows Ink when a pen quickly enters then leaves range shortly after a mouse event.
# Conflicts:
# intern/ghost/intern/GHOST_SystemWin32.cpp
===================================================================
M intern/ghost/intern/GHOST_SystemWin32.cpp
M intern/ghost/intern/GHOST_SystemWin32.h
M intern/ghost/intern/GHOST_WindowWin32.cpp
M intern/ghost/intern/GHOST_WindowWin32.h
M intern/ghost/intern/GHOST_Wintab.cpp
M intern/ghost/intern/GHOST_Wintab.h
M source/blender/windowmanager/intern/wm_cursors.c
===================================================================
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 8511da5b233..e79c5e0ce0a 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -150,6 +150,8 @@ GHOST_SystemWin32::GHOST_SystemWin32()
// blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI.
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
+ EnableMouseInPointer(true);
+
// Check if current keyboard layout uses AltGr and save keylayout ID for
// specialized handling if keys like VK_OEM_*. I.e. french keylayout
// generates VK_OEM_8 for their exclamation key (key left of right shift)
@@ -160,6 +162,11 @@ GHOST_SystemWin32::GHOST_SystemWin32()
#ifdef WITH_INPUT_NDOF
m_ndofManager = new GHOST_NDOFManagerWin32(*this);
#endif
+
+ POINT pt;
+ ::GetCursorPos(&pt);
+ m_lastX = pt.x;
+ m_lastY = pt.y;
}
GHOST_SystemWin32::~GHOST_SystemWin32()
@@ -878,7 +885,7 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
}
-void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
+void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window, UINT genSerial)
{
GHOST_Wintab *wt = window->getWintab();
if (!wt) {
@@ -888,7 +895,7 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
std::vector<GHOST_WintabInfoWin32> wintabInfo;
- wt->getInput(wintabInfo);
+ wt->getInput(wintabInfo, genSerial);
/* Wintab provided coordinates are untrusted until a Wintab and Win32 button down event match.
* This is checked on every button down event, and revoked if there is a mismatch. This can
@@ -908,8 +915,35 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
}
wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
+
+ if (system->m_firstProximity) {
+ system->m_firstProximity = false;
+
+ // XXX bad if not trusted coodinates
+ if (window->getCursorGrabModeIsWarp()) {
+ int32_t x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x_accum -= info.x - system->m_lastX;
+ y_accum -= info.y - system->m_lastY;
+ window->setCursorGrabAccum(x_accum, y_accum);
+ }
+ }
+
+ int x = info.x;
+ int y = info.y;
+
+ if (window->getCursorGrabModeIsWarp()) {
+ int32_t x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x += x_accum;
+ y += y_accum;
+ }
+
system->pushEvent(new GHOST_EventCursor(
- info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
+ info.time, GHOST_kEventCursorMove, window, x, y, info.tabletData));
+
+ system->m_lastX = info.x;
+ system->m_lastY = info.y;
break;
}
@@ -948,8 +982,18 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
/* Move cursor to button location, to prevent incorrect cursor position when
* transitioning from unsynchronized Win32 to Wintab cursor control. */
wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
+
+ int x = info.x;
+ int y = info.y;
+
+ if (window->getCursorGrabModeIsWarp()) {
+ int32_t x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x += x_accum;
+ y += y_accum;
+ }
system->pushEvent(new GHOST_EventCursor(
- info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
+ info.time, GHOST_kEventCursorMove, window, x, y, info.tabletData));
window->updateMouseCapture(MousePressed);
system->pushEvent(
@@ -1006,6 +1050,17 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
int x, y;
system->getCursorPosition(x, y);
+ /* TODO decouple required ordering of accum and last position */
+ system->m_lastX = x;
+ system->m_lastY = y;
+
+ if (window->getCursorGrabModeIsWarp()) {
+ int32_t x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x += x_accum;
+ y += y_accum;
+ }
+
/* TODO supply tablet data */
GHOST_TabletData td = wt->getLastTabletData();
td.Pressure = 1.0f;
@@ -1017,9 +1072,13 @@ void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
void GHOST_SystemWin32::processPointerEvent(
UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
{
+ int32_t pointerId = GET_POINTERID_WPARAM(wParam);
+ POINTER_INPUT_TYPE inputType;
+ GetPointerType(pointerId, &inputType);
+
/* Pointer events might fire when changing windows for a device which is set to use Wintab,
* even when Wintab is left enabled but set to the bottom of Wintab overlap order. */
- if (!window->usingTabletAPI(GHOST_kTabletWinPointer)) {
+ if (!window->usingTabletAPI(GHOST_kTabletWinPointer) && inputType != PT_MOUSE) {
return;
}
@@ -1027,6 +1086,13 @@ void GHOST_SystemWin32::processPointerEvent(
std::vector<GHOST_PointerInfoWin32> pointerInfo;
if (window->getPointerInfo(pointerInfo, wParam, lParam) != GHOST_kSuccess) {
+ if (inputType == PT_MOUSE && type == WM_POINTERUPDATE) {
+ GHOST_EventCursor *event = processCursorEvent(window, pointerId);
+ if (event) {
+ system->pushEvent(event);
+ eventHandled = true;
+ }
+ }
return;
}
@@ -1035,25 +1101,43 @@ void GHOST_SystemWin32::processPointerEvent(
/* Coalesced pointer events are reverse chronological order, reorder chronologically.
* Only contiguous move events are coalesced. */
for (uint32_t i = pointerInfo.size(); i-- > 0;) {
- system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time,
- GHOST_kEventCursorMove,
- window,
- pointerInfo[i].pixelLocation.x,
- pointerInfo[i].pixelLocation.y,
- pointerInfo[i].tabletData));
+ int x = pointerInfo[i].pixelLocation.x;
+ int y = pointerInfo[i].pixelLocation.y;
+
+ if (window->getCursorGrabModeIsWarp()) {
+ int32_t x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x += x_accum;
+ y += y_accum;
+ }
+
+ system->pushEvent(new GHOST_EventCursor(
+ pointerInfo[i].time, GHOST_kEventCursorMove, window, x, y, pointerInfo[i].tabletData));
+ }
+
+ if (pointerInfo.size() > 0) {
+ GHOST_PointerInfoWin32 front = pointerInfo.front();
+ system->m_lastX = front.pixelLocation.x;
+ system->m_lastY = front.pixelLocation.y;
}
/* Leave event unhandled so that system cursor is moved. */
break;
- case WM_POINTERDOWN:
+ case WM_POINTERDOWN: {
+ int x = pointerInfo[0].pixelLocation.x;
+ int y = pointerInfo[0].pixelLocation.y;
+
+ if (window->getCursorGrabModeIsWarp()) {
+ int32_t x_accum, y_accum;
+ window->getCursorGrabAccum(x_accum, y_accum);
+ x += x_accum;
+ y += y_accum;
+ }
+
/* Move cursor to point of contact because GHOST_EventButton does not include position. */
- system->pushEvent(new GHOST_EventCursor(pointerInfo[0].time,
- GHOST_kEventCursorMove,
- window,
- pointerInfo[0].pixelLocation.x,
- pointerInfo[0].pixelLocation.y,
- pointerInfo[0].tabletData));
+ system->pushEvent(new GHOST_EventCursor(
+ pointerInfo[0].time, GHOST_kEventCursorMove, window, x, y, pointerInfo[0].tabletData));
system->pushEvent(new GHOST_EventButton(pointerInfo[0].time,
GHOST_kEventButtonDown,
window,
@@ -1065,6 +1149,7 @@ void GHOST_SystemWin32::processPointerEvent(
eventHandled = true;
break;
+ }
case WM_POINTERUP:
system->pushEvent(new GHOST_EventButton(pointerInfo[0].time,
GHOST_kEventButtonUp,
@@ -1082,9 +1167,9 @@ void GHOST_SystemWin32::processPointerEvent(
}
}
-GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
+GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window,
+ int32_t pointerId)
{
- int32_t x_screen, y_screen;
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
if (window->getTabletData().Active != GHOST_kTabletModeNone) {
@@ -1092,9 +1177,11 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
return NULL;
}
- DWORD pos = ::GetMessagePos();
- x_screen = GET_X_LPARAM(pos);
- y_screen = GET_Y_LPARAM(pos);
+ POINTER_INFO pointerInfo;
+ GetPointerInfo(pointerId, &pointerInfo);
+
+ int32_t x_screen = pointerInfo.ptPixelLocation.x;
+ int32_t y_screen = pointerInfo.ptPixelLocation.y;
int32_t x_accum = 0;
int32_t y_accum = 0;
@@ -1120,21 +1207,24 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
system->setCursorPosition(x_new, y_new); /* wrap */
/* We may be in an event before cursor wrap has taken effect */
- if (window->m_activeWarpX >= 0 && warpX < 0 ||
- window->m_activeWarpX <= 0 && warpX > 0) {
+ if (window->m_activeWarpX >= 0 && warpX < 0 || window->m_activeWarpX <= 0 && warpX > 0) {
x_accum -= warpX;
}
- if (window->m_activeWarpY >= 0 && warpY < 0 ||
- window->m_activeWarpY <= 0 && warpY > 0) {
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list