QBasicDrag: Send QDragMoveEvent when modifiers change
... without moving the mouse. This allows to update drop action and cursor. Task-number: QTBUG-56218 Task-number: QTBUG-82934 Pick-to: 5.15 Change-Id: I8b0ac2a008a9dbcc4c2d6abce282e6f169c2f542 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
45ed28a9d3
commit
af3caa2271
@ -145,15 +145,17 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
|
||||
disableEventFilter();
|
||||
exitDndEventLoop();
|
||||
|
||||
} else if (ke->modifiers() != QGuiApplication::keyboardModifiers()) {
|
||||
move(m_lastPos, QGuiApplication::mouseButtons(), ke->modifiers());
|
||||
}
|
||||
return true; // Eat all key events
|
||||
}
|
||||
|
||||
case QEvent::MouseMove:
|
||||
{
|
||||
QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window);
|
||||
m_lastPos = getNativeMousePos(e, m_drag_icon_window);
|
||||
auto mouseMove = static_cast<QMouseEvent *>(e);
|
||||
move(nativePosition, mouseMove->buttons(), mouseMove->modifiers());
|
||||
move(m_lastPos, mouseMove->buttons(), mouseMove->modifiers());
|
||||
return true; // Eat all mouse move events
|
||||
}
|
||||
case QEvent::MouseButtonRelease:
|
||||
@ -230,6 +232,7 @@ void QBasicDrag::startDrag()
|
||||
pos = QPoint();
|
||||
}
|
||||
#endif
|
||||
m_lastPos = pos;
|
||||
recreateShapedPixmapWindow(m_screen, pos);
|
||||
enableEventFilter();
|
||||
}
|
||||
|
@ -126,6 +126,7 @@ private:
|
||||
QShapedPixmapWindow *m_drag_icon_window = nullptr;
|
||||
bool m_useCompositing = true;
|
||||
QScreen *m_screen = nullptr;
|
||||
QPoint m_lastPos;
|
||||
};
|
||||
|
||||
class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
|
||||
|
@ -725,7 +725,7 @@ protected:
|
||||
{
|
||||
e->accept();
|
||||
_dndEvents.append(QStringLiteral("DragMove "));
|
||||
emit releaseMouseButton();
|
||||
emit dragMoveReceived();
|
||||
}
|
||||
void dragLeaveEvent(QDragLeaveEvent *e)
|
||||
{
|
||||
@ -739,7 +739,7 @@ protected:
|
||||
}
|
||||
|
||||
signals:
|
||||
void releaseMouseButton();
|
||||
void dragMoveReceived();
|
||||
};
|
||||
|
||||
void tst_QWidget_window::tst_dnd_events()
|
||||
@ -774,7 +774,7 @@ void tst_QWidget_window::tst_dnd_events()
|
||||
|
||||
// Some dnd implementation rely on running internal event loops, so we have to use
|
||||
// the following queued signal hack to simulate mouse clicks in the widget.
|
||||
QObject::connect(&dndWidget, &DnDEventRecorder::releaseMouseButton, this, [=]() {
|
||||
QObject::connect(&dndWidget, &DnDEventRecorder::dragMoveReceived, this, [=]() {
|
||||
QTest::mouseRelease(window, Qt::LeftButton);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
@ -783,6 +783,27 @@ void tst_QWidget_window::tst_dnd_events()
|
||||
QTest::mousePress(window, Qt::LeftButton);
|
||||
|
||||
QCOMPARE(dndWidget._dndEvents, expectedDndEvents);
|
||||
|
||||
dndWidget._dndEvents.clear();
|
||||
dndWidget.disconnect();
|
||||
int step = 0;
|
||||
QObject::connect(&dndWidget, &DnDEventRecorder::dragMoveReceived, this, [window, &step]() {
|
||||
switch (step++) {
|
||||
case 0:
|
||||
QTest::keyPress(window, Qt::Key_Shift, Qt::ShiftModifier);
|
||||
break;
|
||||
case 1:
|
||||
QTest::keyRelease(window, Qt::Key_Shift, Qt::NoModifier);
|
||||
break;
|
||||
default:
|
||||
QTest::mouseRelease(window, Qt::LeftButton);
|
||||
break;
|
||||
}
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
QTest::mousePress(window, Qt::LeftButton);
|
||||
const QString expectedDndWithModsEvents = "DragEnter DragMove DragMove DragMove DropEvent ";
|
||||
QCOMPARE(dndWidget._dndEvents, expectedDndWithModsEvents);
|
||||
}
|
||||
|
||||
class DropTarget : public QWidget
|
||||
|
Loading…
x
Reference in New Issue
Block a user