[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