diff options
author | Andre de la Rocha <andre.rocha@qt.io> | 2018-10-02 09:19:19 +0200 |
---|---|---|
committer | Andre de la Rocha <andre.rocha@qt.io> | 2018-10-02 23:42:29 +0000 |
commit | 4840668994739054f0976d90eebe9ccfdff0ed81 (patch) | |
tree | 77465825289ed2bba9e69ea5a9a5ae6578ad1131 | |
parent | 18be2337ea85655e39f4ffe3b77d2b3ab243c140 (diff) |
Windows QPA: Fix multiple mouse button presses detection
The detection of multiple mouse button presses was broken in the new
WM_POINTER-based implementation. The bug was due to the incorrect
assumption that the press/release of a second mouse button (while
another one is held) would also send WM_POINTERDOWN/WM_POINTERUP, while
in fact it sends a WM_POINTERUPDATE with the actual event type given
by pointerInfo->ButtonChangeType.
Task-number: QTBUG-70787
Change-Id: Ib6776ab7f3d0b8eb5e832a0c863a15bde456e0dd
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | src/plugins/platforms/windows/qwindowspointerhandler.cpp | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/plugins/platforms/windows/qwindowspointerhandler.cpp b/src/plugins/platforms/windows/qwindowspointerhandler.cpp index 7ead14822a..c5acc38e7c 100644 --- a/src/plugins/platforms/windows/qwindowspointerhandler.cpp +++ b/src/plugins/platforms/windows/qwindowspointerhandler.cpp @@ -61,6 +61,8 @@ #include <QtCore/qloggingcategory.h> #include <QtCore/qoperatingsystemversion.h> +#include <algorithm> + #include <windowsx.h> QT_BEGIN_NAMESPACE @@ -184,41 +186,65 @@ static void getMouseEventInfo(UINT message, POINTER_BUTTON_CHANGE_TYPE changeTyp {POINTER_CHANGE_FIFTHBUTTON_UP, Qt::XButton2}, }; - static const QHash<UINT, QEvent::Type> eventMapping { - {WM_POINTERUPDATE, QEvent::MouseMove}, - {WM_POINTERDOWN, QEvent::MouseButtonPress}, - {WM_POINTERUP, QEvent::MouseButtonRelease}, - {WM_NCPOINTERUPDATE, QEvent::NonClientAreaMouseMove}, - {WM_NCPOINTERDOWN, QEvent::NonClientAreaMouseButtonPress}, - {WM_NCPOINTERUP, QEvent::NonClientAreaMouseButtonRelease}, - {WM_POINTERWHEEL, QEvent::Wheel}, - {WM_POINTERHWHEEL, QEvent::Wheel}, + static const POINTER_BUTTON_CHANGE_TYPE downChanges[] = { + POINTER_CHANGE_FIRSTBUTTON_DOWN, + POINTER_CHANGE_SECONDBUTTON_DOWN, + POINTER_CHANGE_THIRDBUTTON_DOWN, + POINTER_CHANGE_FOURTHBUTTON_DOWN, + POINTER_CHANGE_FIFTHBUTTON_DOWN, + }; + + static const POINTER_BUTTON_CHANGE_TYPE upChanges[] = { + POINTER_CHANGE_FIRSTBUTTON_UP, + POINTER_CHANGE_SECONDBUTTON_UP, + POINTER_CHANGE_THIRDBUTTON_UP, + POINTER_CHANGE_FOURTHBUTTON_UP, + POINTER_CHANGE_FIFTHBUTTON_UP, }; if (!eventType || !mouseButton) return; - if (message == WM_POINTERDOWN || message == WM_POINTERUP || message == WM_NCPOINTERDOWN || message == WM_NCPOINTERUP) - *mouseButton = buttonMapping.value(changeType, Qt::NoButton); - else - *mouseButton = Qt::NoButton; + const bool nonClient = message == WM_NCPOINTERUPDATE || + message == WM_NCPOINTERDOWN || + message == WM_NCPOINTERUP; + + if (std::find(std::begin(downChanges), + std::end(downChanges), changeType) < std::end(downChanges)) { + *eventType = nonClient ? QEvent::NonClientAreaMouseButtonPress : + QEvent::MouseButtonPress; + } else if (std::find(std::begin(upChanges), + std::end(upChanges), changeType) < std::end(upChanges)) { + *eventType = nonClient ? QEvent::NonClientAreaMouseButtonRelease : + QEvent::MouseButtonRelease; + } else if (message == WM_POINTERWHEEL || message == WM_POINTERHWHEEL) { + *eventType = QEvent::Wheel; + } else { + *eventType = nonClient ? QEvent::NonClientAreaMouseMove : + QEvent::MouseMove; + } - *eventType = eventMapping.value(message, QEvent::None); + *mouseButton = buttonMapping.value(changeType, Qt::NoButton); // Pointer messages lack a double click indicator. Check if this is the case here. - if (message == WM_POINTERDOWN) { + if (*eventType == QEvent::MouseButtonPress || + *eventType == QEvent::NonClientAreaMouseButtonPress) { static LONG lastTime = 0; static Qt::MouseButton lastButton = Qt::NoButton; + static QEvent::Type lastEvent = QEvent::None; static QPoint lastPos; LONG messageTime = GetMessageTime(); if (*mouseButton == lastButton + && *eventType == lastEvent && messageTime - lastTime < (LONG)GetDoubleClickTime() && qAbs(globalPos.x() - lastPos.x()) < GetSystemMetrics(SM_CXDOUBLECLK) && qAbs(globalPos.y() - lastPos.y()) < GetSystemMetrics(SM_CYDOUBLECLK)) { - *eventType = QEvent::MouseButtonDblClick; + *eventType = nonClient ? QEvent::NonClientAreaMouseButtonDblClick : + QEvent::MouseButtonDblClick; } lastTime = messageTime; lastButton = *mouseButton; + lastEvent = *eventType; lastPos = globalPos; } } |