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.

Task-number: QTBUG-66447
Change-Id: Ia865edddc0c77a1b42b9ad2c38323379e74b6704
Reviewed-by: Jan Arve Sæther <jan-arve.saether@qt.io>
This commit is contained in:
Friedemann Kleint 2018-02-22 15:02:52 +01:00
parent b2d2b655e5
commit 1f6bd8bfb2

View File

@ -248,6 +248,7 @@ private:
Mode m_mode;
QWindowsDrag *m_drag;
QPointer<QWindow> 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;