From 4840668994739054f0976d90eebe9ccfdff0ed81 Mon Sep 17 00:00:00 2001 From: Andre de la Rocha Date: Tue, 2 Oct 2018 09:19:19 +0200 Subject: 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 --- .../platforms/windows/qwindowspointerhandler.cpp | 58 ++++++++++++++++------ 1 file changed, 42 insertions(+), 16 deletions(-) (limited to 'src') 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 #include +#include + #include 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 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; } } -- cgit v1.2.3