From 544075d51a081959f9c8e71befc27175ac948c46 Mon Sep 17 00:00:00 2001 From: Philippe Hermite Date: Thu, 24 Oct 2019 19:00:45 +0200 Subject: [PATCH 14/15] Fix tablet events on windows to have synthesized mouse events after receiving tablet events --- qtbase/src/corelib/global/qnamespace.h | 4 ++- .../windows/qwindowspointerhandler.cpp | 35 ++++++++++++------- .../windows/qwindowspointerhandler.h | 1 + 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/qtbase/src/corelib/global/qnamespace.h b/qtbase/src/corelib/global/qnamespace.h index dec2c4463..27b0e39e0 100644 --- a/qtbase/src/corelib/global/qnamespace.h +++ b/qtbase/src/corelib/global/qnamespace.h @@ -1712,7 +1712,9 @@ public: MouseEventNotSynthesized, MouseEventSynthesizedBySystem, MouseEventSynthesizedByQt, - MouseEventSynthesizedByApplication + MouseEventSynthesizedByApplication, + // Hack: For now I don't have time to implement the handleTabletEvent inside qtdeclarative/src/quick/items/qquickwindow.cpp + MousePointerEventSynthesizedBySystem }; enum MouseEventFlag { diff --git a/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 71a09304c..5f1aa4b44 100644 --- a/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -579,19 +579,16 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin const QTabletEvent::TabletDevice device = QTabletEvent::Stylus; QTabletEvent::PointerType type; - Qt::MouseButtons mouseButtons; - - const bool pointerInContact = IS_POINTER_INCONTACT_WPARAM(msg.wParam); + Qt::MouseButtons mouseButtons = queryMouseButtons(); + + const bool pointerInContact = penInfo->pointerInfo.pointerFlags & POINTER_FLAG_INCONTACT; if (pointerInContact) - mouseButtons = Qt::LeftButton; + { + if (penInfo->pointerInfo.pointerFlags & POINTER_FLAG_FIRSTBUTTON) mouseButtons = Qt::LeftButton; + else if (penInfo->pointerInfo.pointerFlags & POINTER_FLAG_SECONDBUTTON) mouseButtons = Qt::RightButton; + } - if (penInfo->penFlags & (PEN_FLAG_ERASER | PEN_FLAG_INVERTED)) { - type = QTabletEvent::Eraser; - } else { - type = QTabletEvent::Pen; - if (pointerInContact && penInfo->penFlags & PEN_FLAG_BARREL) - mouseButtons = Qt::RightButton; // Either left or right, not both - } + type = (penInfo->penFlags & (PEN_FLAG_ERASER | PEN_FLAG_INVERTED)) ? QTabletEvent::Eraser : QTabletEvent::Pen; switch (msg.message) { case WM_POINTERENTER: { @@ -600,6 +597,7 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin // The local coordinates may fall outside the window. // Wait until the next update to send the enter event. m_needsEnterOnPointerUpdate = true; + blockMouseWhenUsingATablet_ = false; break; } case WM_POINTERLEAVE: @@ -609,10 +607,12 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin m_currentWindow = nullptr; } QWindowSystemInterface::handleTabletLeaveProximityEvent(device, type, sourceDevice); + blockMouseWhenUsingATablet_ = false; break; case WM_POINTERDOWN: case WM_POINTERUP: case WM_POINTERUPDATE: { + blockMouseWhenUsingATablet_ = msg.message != WM_POINTERUP; QWindow *target = QGuiApplicationPrivate::tabletDevicePoint(sourceDevice).target; // Pass to window that grabbed it. if (!target && m_windowUnderPointer) target = m_windowUnderPointer; @@ -727,15 +727,26 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window, } Qt::MouseEventSource source = Qt::MouseEventNotSynthesized; + // Hack: Just doing this because of the windows API... + const bool synthesizedFromPenOrTouch = isMouseEventSynthesizedFromPenOrTouch(); // Following the logic of the old mouse handler, only events synthesized // for touch screen are marked as such. On some systems, using the bit 7 of // the extra msg info for checking if synthesized for touch does not work, // so we use the pointer type of the last pointer message. - if (isMouseEventSynthesizedFromPenOrTouch() && m_pointerType == QT_PT_TOUCH) { + if (synthesizedFromPenOrTouch && m_pointerType == QT_PT_TOUCH) { if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) return false; source = Qt::MouseEventSynthesizedBySystem; } + else if (synthesizedFromPenOrTouch || blockMouseWhenUsingATablet_) { + // Hack: I'm using a new entry hoping it will not affect the rest of the code + // It can leads to really weird behaviors, it will be safer to just remove the '&& m_pointerType == QT_PT_TOUCH' test + // and add inside qtdeclarative/src/quick/items/qquickwindow.cpp the handleTabletEvent... + if (QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch) + return false; + source = Qt::MousePointerEventSynthesizedBySystem; + } + if (!synthesizedFromPenOrTouch) blockMouseWhenUsingATablet_ = false; const MouseEvent mouseEvent = eventFromMsg(msg); Qt::MouseButtons mouseButtons; diff --git a/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.h b/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.h index b6b89cefe..0b469f471 100644 --- a/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.h +++ b/qtbase/src/plugins/platforms/windows/qwindowspointerhandler.h @@ -83,6 +83,7 @@ private: QEvent::Type m_lastEventType = QEvent::None; Qt::MouseButton m_lastEventButton = Qt::NoButton; DWORD m_pointerType = 0; + bool blockMouseWhenUsingATablet_ = false; }; QT_END_NAMESPACE -- 2.19.1.windows.1