From a1c65818b330f8607e69a5a5813a13e0ef7e2892 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 22 Feb 2018 15:02:52 +0100 Subject: [PATCH] Windows QPA: Ensure a mouse release event is sent after DnD Windows does not send a mouse release by itself, which can leave Quick controls believing the mouse is still pressed. Synthesize an event. Remove code assigning to values to QGuiApplicationPrivate::mouse_buttons as it interferes with the state handling. This is a workaround for the 5.10 branch provided on customer request; the proper fix is to use new platform APIs in 5.12. Task-number: QTBUG-66447 Change-Id: Ia865edddc0c77a1b42b9ad2c38323379e74b6704 --- src/plugins/platforms/windows/qwindowsdrag.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index aa6454ef63..bbffce13eb 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -248,6 +248,7 @@ private: const Mode m_mode; QWindowsDrag *m_drag; + QPointer m_windowUnderMouse; Qt::MouseButtons m_currentButtons; ActionCursorMap m_cursors; QWindowsDragCursorWindow *m_touchDragWindow; @@ -260,6 +261,7 @@ private: QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) : m_mode(QWindowsCursor::cursorState() != QWindowsCursor::CursorSuppressed ? MouseDrag : TouchDrag) , m_drag(drag) + , m_windowUnderMouse(QWindowsContext::instance()->windowUnderMouse()) , m_currentButtons(Qt::NoButton) , m_touchDragWindow(0) { @@ -391,7 +393,19 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) case DRAGDROP_S_DROP: case DRAGDROP_S_CANCEL: QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState); - QGuiApplicationPrivate::mouse_buttons = buttons; + if (buttons != QGuiApplicationPrivate::mouse_buttons) { + if (m_windowUnderMouse.isNull() || m_mode == TouchDrag || fEscapePressed == TRUE) { + QGuiApplicationPrivate::mouse_buttons = buttons; + } else { + // QTBUG 66447: Synthesize a mouse release to the window under mouse at + // start of the DnD operation as Windows does not send any. + const QPoint globalPos = QWindowsCursor::mousePosition(); + const QPoint localPos = m_windowUnderMouse->handle()->mapFromGlobal(globalPos); + QWindowSystemInterface::handleMouseEvent(m_windowUnderMouse.data(), + QPointF(localPos), QPointF(globalPos), + QWindowsMouseHandler::queryMouseButtons()); + } + } m_currentButtons = Qt::NoButton; break; @@ -573,7 +587,6 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, m_lastPoint = QWindowsGeometryHint::mapFromGlobal(m_window, QPoint(pt.x,pt.y)); // grfKeyState does not all ways contain button state in the drop - QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(m_lastKeyState); QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState); QWindowsDrag *windowsDrag = QWindowsDrag::instance(); @@ -583,7 +596,6 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState, m_lastPoint, translateToQDragDropActions(*pdwEffect)); - QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState); m_lastKeyState = grfKeyState; if (response.isAccepted()) { -- 2.13.2.windows.1