From 1f6bd8bfb2206480ca5b5c267da38659e6cff20e 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 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows does not send a mouse release by itself, which can leave Quick controls believing the mouse is still pressed. Synthesize an event. Task-number: QTBUG-66447 Change-Id: Ia865edddc0c77a1b42b9ad2c38323379e74b6704 Reviewed-by: Jan Arve Sæther --- src/plugins/platforms/windows/qwindowsdrag.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index 777c45ae86..db06f81434 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -248,6 +248,7 @@ private: 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) { @@ -400,7 +402,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;