Warning, /graphics/krita/3rdparty/ext_qt/0053-WinInk-Prevent-Leave-event-confusing-mouse-capture-s.patch is written in an unsupported language. File is not indexed.
0001 From 5c29a8f7d18edd5097acd585ac302e8c14114d56 Mon Sep 17 00:00:00 2001 0002 From: Alvin Wong <alvinhochun@gmail.com> 0003 Date: Wed, 6 Apr 2022 18:46:29 +0800 0004 Subject: [PATCH] WinInk: Prevent Leave event confusing mouse capture state 0005 0006 When mouse events are synthesized from tablet strokes, the WM_LBUTTONUP 0007 event can arrive later than WM_POINTERLEAVE if the pen is lifted very 0008 quickly. Normally, the mouse capture does not get released until the 0009 mouse button is released, and no Leave event is generated before that. 0010 However, WM_POINTERLEAVE does not consider the mouse capture state 0011 before unconditionally generating a Leave event. This confuses the mouse 0012 andling and no Enter event is sent before the following mouse events, 0013 which causes parts of Qt to think the cursor isn't inside the window. 0014 0015 The fix is to not generate the Leave event on WM_POINTERLEAVE if mouse 0016 capture is active. In addition, when it does send the Leave event, 0017 immediately handle it synchronously, before more mouse events arrive, 0018 so that the next Enter event can be generated correctly. 0019 0020 Another issue discovered is that, sometimes the Enter event arrives 0021 later than the Tablet events for unknown reasons. The fix (workaround) 0022 is also to handle the Enter event synchronously. 0023 --- 0024 .../windows/qwindowspointerhandler.cpp | 23 ++++++++++++++++--- 0025 1 file changed, 20 insertions(+), 3 deletions(-) 0026 0027 diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp 0028 index 9e518a262f..2da76a59ec 100644 0029 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp 0030 +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp 0031 @@ -657,13 +657,25 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin 0032 // The local coordinates may fall outside the window. 0033 // Wait until the next update to send the enter event. 0034 m_needsEnterOnPointerUpdate = true; 0035 + qCDebug(lcQpaEvents) << "WM_POINTERENTER received, m_windowUnderPointer:" << window; 0036 break; 0037 } 0038 case WM_POINTERLEAVE: 0039 if (m_windowUnderPointer && m_windowUnderPointer == m_currentWindow) { 0040 - QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); 0041 - m_windowUnderPointer = nullptr; 0042 - m_currentWindow = nullptr; 0043 + QWindowsWindow *platformWindow = static_cast<QWindowsWindow *>(window->handle()); 0044 + const bool hasCapture = platformWindow->hasMouseCapture(); 0045 + if (!hasCapture) { 0046 + qCDebug(lcQpaEvents) << "Leaving window " << m_windowUnderPointer << "(WM_POINTERLEAVE)"; 0047 + QWindowSystemInterface::handleLeaveEvent(m_windowUnderPointer); 0048 + m_windowUnderPointer = nullptr; 0049 + m_currentWindow = nullptr; 0050 + // Flush to make sure the Leave event gets processed before 0051 + // we we potentially get more mouse events, so that Qt can 0052 + // correctly generate a new Enter event for them. 0053 + QWindowSystemInterface::flushWindowSystemEvents(); 0054 + } else { 0055 + qCDebug(lcQpaEvents) << "WM_POINTERLEAVE blocked from sending Leave event due to existing mouse capture"; 0056 + } 0057 } 0058 QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, sourceDevice); 0059 break; 0060 @@ -682,10 +694,15 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin 0061 // make sure we subscribe to leave events for this window 0062 trackLeave(hwnd); 0063 0064 + qCDebug(lcQpaEvents) << "Entering window " << window << "(WM_POINTERDOWN / WM_POINTERUP / WM_POINTERUPDATE)"; 0065 QWindowSystemInterface::handleEnterEvent(window, localPos, globalPos); 0066 m_currentWindow = window; 0067 if (QWindowsWindow *wumPlatformWindow = QWindowsWindow::windowsWindowOf(target)) 0068 wumPlatformWindow->applyCursor(); 0069 + // Make sure the Enter event is processed before sending tablet 0070 + // events. Without this, sometimes the tablet events reaches 0071 + // the widget before the Enter event For unknown reasons. 0072 + QWindowSystemInterface::flushWindowSystemEvents(); 0073 } 0074 } 0075 const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); 0076 -- 0077 2.24.1.windows.2 0078