From ab5986cf3a2eea3a8ba3f7029f936f79ade921ef Mon Sep 17 00:00:00 2001 From: Nicholas Rishel Date: Sun, 10 Jan 2021 21:13:44 -0800 Subject: [PATCH] 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. --- intern/ghost/intern/GHOST_SystemWin32.cpp | 7 +++- intern/ghost/intern/GHOST_WindowWin32.cpp | 50 ++++++++++++++++------- intern/ghost/intern/GHOST_WindowWin32.h | 9 +++- 3 files changed, 49 insertions(+), 17 deletions(-) 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> 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 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. */