[Bf-blender-cvs] [ab5986cf3a2] master: Fix T84501: Wintab button lag.

Nicholas Rishel noreply at git.blender.org
Mon Jan 11 06:20:12 CET 2021


Commit: ab5986cf3a2eea3a8ba3f7029f936f79ade921ef
Author: Nicholas Rishel
Date:   Sun Jan 10 21:13:44 2021 -0800
Branches: master
https://developer.blender.org/rBab5986cf3a2eea3a8ba3f7029f936f79ade921ef

Fix T84501: Wintab button lag.

Multiple Wintab tablets do not send relative button state when
configured to do so. This causes button events to be delayed until
processed as Win32 button events.

This commit fixes the issue by configuring Wintab to use absolute
button state and tracking changes manually.

===================================================================

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 181e3ad4014..5de97199fd8 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -1559,7 +1559,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
           break;
         case WT_PROXIMITY: {
           if (window->useTabletAPI(GHOST_kTabletWintab)) {
-            window->m_tabletInRange = LOWORD(lParam);
+            if (LOWORD(lParam)) {
+              window->m_tabletInRange = true;
+            }
+            else {
+              window->processWintabLeave();
+            }
           }
           eventHandled = true;
           break;
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index f5088c6505e..255d487649b 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -1155,16 +1155,21 @@ void GHOST_WindowWin32::setWintabOverlap(bool overlap)
         /* If context is disabled, Windows Ink may be active and managing m_tabletInRange. Don't
          * modify it. */
         if (!(context.lcStatus & CXS_DISABLED)) {
-          /* Set tablet as not in range, proximity event may not occur. */
-          m_tabletInRange = false;
-          /* Clear the packet queue. */
-          m_wintab.packetsGet(m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
+          processWintabLeave();
         }
       }
     }
   }
 }
 
+void GHOST_WindowWin32::processWintabLeave()
+{
+  m_tabletInRange = false;
+  m_wintab.buttons = 0;
+  /* Clear the packet queue. */
+  m_wintab.packetsGet(m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
+}
+
 void GHOST_WindowWin32::processWintabDisplayChangeEvent()
 {
   LOGCONTEXT lc_sys = {0}, lc_curr = {0};
@@ -1327,17 +1332,32 @@ GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin3
       out.tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
     }
 
-    out.button = wintabMouseToGhost(pkt.pkCursor, LOWORD(pkt.pkButtons));
-    switch (HIWORD(pkt.pkButtons)) {
-      case TBN_NONE:
-        out.type = GHOST_kEventCursorMove;
-        break;
-      case TBN_DOWN:
-        out.type = GHOST_kEventButtonDown;
-        break;
-      case TBN_UP:
-        out.type = GHOST_kEventButtonUp;
-        break;
+    /* Some Wintab libraries don't handle relative button input, so we track button presses
+     * manually. */
+    out.button = GHOST_kButtonMaskNone;
+    out.type = GHOST_kEventCursorMove;
+
+    DWORD buttonsChanged = m_wintab.buttons ^ pkt.pkButtons;
+    if (buttonsChanged) {
+      /* Find the index for the changed button from the button map. */
+      WORD physicalButton = 0;
+      for (DWORD diff = (unsigned)buttonsChanged >> 1; diff > 0; diff = (unsigned)diff >> 1) {
+        physicalButton++;
+      }
+
+      out.button = wintabMouseToGhost(pkt.pkCursor, physicalButton);
+
+      if (out.button != GHOST_kButtonMaskNone) {
+        if (buttonsChanged & pkt.pkButtons) {
+          out.type = GHOST_kEventButtonDown;
+        }
+        else {
+          out.type = GHOST_kEventButtonUp;
+        }
+      }
+
+      /* Only update handled button, in case multiple button events arrived simultaneously. */
+      m_wintab.buttons ^= 1 << physicalButton;
     }
 
     out.time = system->tickCountToMillis(pkt.pkTime);
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 1cff8b2036e..a7e7cdc6602 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -41,7 +41,7 @@
 // PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first
 #define PACKETDATA \
   (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_X | PK_Y | PK_TIME)
-#define PACKETMODE PK_BUTTONS
+#define PACKETMODE 0
 #include <pktdef.h>
 
 class GHOST_SystemWin32;
@@ -466,6 +466,11 @@ class GHOST_WindowWin32 : public GHOST_Window {
    */
   void setWintabOverlap(bool overlap);
 
+  /**
+   * Resets Wintab state.
+   */
+  void processWintabLeave();
+
   /**
    * Handle Wintab coordinate changes when DisplayChange events occur.
    */
@@ -614,6 +619,8 @@ class GHOST_WindowWin32 : public GHOST_Window {
     HCTX context = NULL;
     /** Number of connected Wintab digitizers. */
     UINT numDevices = 0;
+    /** Pressed button map. */
+    GHOST_TUns8 buttons = 0;
     LONG maxPressure = 0;
     LONG maxAzimuth = 0, maxAltitude = 0;
     /** Reusable buffer to read in Wintab Packets. */



More information about the Bf-blender-cvs mailing list