diff options
Diffstat (limited to 'tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp')
-rw-r--r-- | tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 0813a13693..f0b4bd6dd9 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -83,6 +83,7 @@ private slots: #if QT_CONFIG(draganddrop) void tst_dnd(); + void tst_dnd_events(); #endif void tst_qtbug35600(); @@ -597,6 +598,92 @@ void tst_QWidget_window::tst_dnd() QCOMPARE(log, expectedLog); } + +class DnDEventRecorder : public QWidget +{ + Q_OBJECT +public: + QString _dndEvents; + DnDEventRecorder() { setAcceptDrops(true); } + +protected: + void mousePressEvent(QMouseEvent *) + { + QMimeData *mimeData = new QMimeData; + mimeData->setData("application/x-dnditemdata", "some data"); + QDrag *drag = new QDrag(this); + drag->setMimeData(mimeData); + drag->exec(); + } + + void dragEnterEvent(QDragEnterEvent *e) + { + e->accept(); + _dndEvents.append(QStringLiteral("DragEnter ")); + } + void dragMoveEvent(QDragMoveEvent *e) + { + e->accept(); + _dndEvents.append(QStringLiteral("DragMove ")); + emit releaseMouseButton(); + } + void dragLeaveEvent(QDragLeaveEvent *e) + { + e->accept(); + _dndEvents.append(QStringLiteral("DragLeave ")); + } + void dropEvent(QDropEvent *e) + { + e->accept(); + _dndEvents.append(QStringLiteral("DropEvent ")); + } + +signals: + void releaseMouseButton(); +}; + +void tst_QWidget_window::tst_dnd_events() +{ + // Note: This test is somewhat a hack as testing DnD with qtestlib is not + // supported at the moment. The test verifies that we get an expected event + // sequence on dnd operation that does not move a mouse. This logic is implemented + // in QGuiApplication, so we have to go via QWindowSystemInterface API (QTest::mouse*). + const auto platformName = QGuiApplication::platformName().toLower(); + // The test is known to work with XCB and platforms that use the default dnd + // implementation QSimpleDrag (e.g. qnx). Running on XCB should be sufficient to + // catch regressions at cross platform code: QGuiApplication::processDrag/Leave(). + if (platformName != "xcb") + return; + + const QString expectedDndEvents = "DragEnter DragMove DropEvent DragEnter DragMove " + "DropEvent DragEnter DragMove DropEvent "; + DnDEventRecorder dndWidget; + dndWidget.setGeometry(100, 100, 200, 200); + dndWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dndWidget)); + QVERIFY(QTest::qWaitForWindowActive(&dndWidget)); + + // ### FIXME - QTBUG-35117 ??? + auto targetCenter = QPoint(dndWidget.width(), dndWidget.height()) / 2; + auto targetCenterGlobal = dndWidget.mapToGlobal(targetCenter); + QCursor::setPos(targetCenterGlobal); + QVERIFY(QTest::qWaitFor([&]() { return QCursor::pos() == targetCenterGlobal; })); + QCoreApplication::processEvents(); // clear mouse events generated from cursor + + auto window = dndWidget.window()->windowHandle(); + + // 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, [=]() { + QTest::mouseRelease(window, Qt::LeftButton); + }, Qt::QueuedConnection); + + QTest::mousePress(window, Qt::LeftButton); + QTest::mousePress(window, Qt::LeftButton); + QTest::mousePress(window, Qt::LeftButton); + + QCOMPARE(dndWidget._dndEvents, expectedDndEvents); +} #endif void tst_QWidget_window::tst_qtbug35600() |