diff options
author | Albert Astals Cid <albert.astals@canonical.com> | 2012-04-24 11:45:46 (GMT) |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-05-14 09:51:19 (GMT) |
commit | c3eb2e63425c47b8e3eeb7416e225fab10c5c15a (patch) | |
tree | 7461733238e94076f0bef7311271984e4724c8b0 /tests | |
parent | a93b7025c71f8c4f81ba3b516a65ee41e6ef419c (diff) | |
download | Qt-c3eb2e63425c47b8e3eeb7416e225fab10c5c15a.zip Qt-c3eb2e63425c47b8e3eeb7416e225fab10c5c15a.tar.gz Qt-c3eb2e63425c47b8e3eeb7416e225fab10c5c15a.tar.bz2 |
XShaping drag and drop fixes
No shaping rectangles means no interaction with the window
The shaping rectangles are based on the window coords, so need to substract the window coords when checking for the point
And some tests to prove this change is needed
Backport from commit 07f3c1e26aa6dcd07a9705e7b2ea02ace9ea7c5d from qtbase
Change-Id: I6dd6c75c2bd70463561445b4f4a3894c80981d26
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/qdrag/dummy.png | bin | 0 -> 126 bytes | |||
-rw-r--r-- | tests/auto/qdrag/tst_qdrag.cpp | 255 |
2 files changed, 255 insertions, 0 deletions
diff --git a/tests/auto/qdrag/dummy.png b/tests/auto/qdrag/dummy.png Binary files differnew file mode 100644 index 0000000..c4b5723 --- /dev/null +++ b/tests/auto/qdrag/dummy.png diff --git a/tests/auto/qdrag/tst_qdrag.cpp b/tests/auto/qdrag/tst_qdrag.cpp index 07d82b3..3aac909 100644 --- a/tests/auto/qdrag/tst_qdrag.cpp +++ b/tests/auto/qdrag/tst_qdrag.cpp @@ -46,9 +46,132 @@ #include <qdebug.h> #include <qdrag.h> +#ifdef Q_WS_X11 +#include <QBitmap> +#include <QPainter> +#include <QX11Info> + +#include <X11/extensions/shape.h> +#endif + //TESTED_CLASS= //TESTED_FILES= +class DragEnterCounterWidget : public QWidget +{ +public: + DragEnterCounterWidget(); + + void dragEnterEvent(QDragEnterEvent * event); + + int enterEvents; +}; + +class DragCounterAndCreatorWidget : public DragEnterCounterWidget +{ +public: + DragCounterAndCreatorWidget(); + + void mousePressEvent(QMouseEvent * event); + + int startedDrags; +}; + +class BiggerDragCounterWidget : public DragEnterCounterWidget +{ +public: + BiggerDragCounterWidget(); +}; + +DragEnterCounterWidget::DragEnterCounterWidget() : QWidget(0), enterEvents(0) +{ + setAcceptDrops(true); + setWindowFlags(Qt::FramelessWindowHint); + show(); +} + +void DragEnterCounterWidget::dragEnterEvent(QDragEnterEvent * event) +{ + event->acceptProposedAction(); + ++enterEvents; +} + +DragCounterAndCreatorWidget::DragCounterAndCreatorWidget() : startedDrags(0) +{ + resize(80, 80); + move(300, 300); +} + +void DragCounterAndCreatorWidget::mousePressEvent(QMouseEvent * /*event*/) +{ + ++startedDrags; + QDrag *drag = new QDrag(this); + drag->setMimeData(new QMimeData); + QPixmap p("dummy.png"); + drag->setHotSpot(QPoint( p.width() / 2, p.height() / 2 )); + drag->setPixmap(p); + drag->exec(); +} + +BiggerDragCounterWidget::BiggerDragCounterWidget() +{ + resize(180, 180); + move(250, 250); +} + +class DoMouseReleaseHelper : public QTimer +{ +Q_OBJECT + +public: + DoMouseReleaseHelper(QWidget *w, int timeout = 0); + +private slots: + void doMouseRelease(); + +private: + QWidget *m_w; +}; + +DoMouseReleaseHelper::DoMouseReleaseHelper(QWidget *w, int timeout) : m_w(w) +{ + setSingleShot(true); + start(timeout); + connect(this, SIGNAL(timeout()), this, SLOT(doMouseRelease())); +} + +void DoMouseReleaseHelper::doMouseRelease() +{ + QTest::mouseRelease(m_w, Qt::LeftButton); +} + +class DoMouseMoveHelper : public QTimer +{ +Q_OBJECT + +public: + DoMouseMoveHelper(QWidget *w, const QPoint &p, int timeout = 0); + +private slots: + void doMouseMove(); + +private: + QWidget *m_w; + QPoint m_p; +}; + +DoMouseMoveHelper::DoMouseMoveHelper(QWidget *w, const QPoint &p, int timeout) : m_w(w), m_p(p) +{ + setSingleShot(true); + start(timeout); + connect(this, SIGNAL(timeout()), this, SLOT(doMouseMove())); +} + +void DoMouseMoveHelper::doMouseMove() +{ + QTest::mouseMove(m_w, m_p); +} + class tst_QDrag : public QObject { Q_OBJECT @@ -59,6 +182,10 @@ public: private slots: void getSetCheck(); + void testDragEnterSelf(); + void testDragEnterNoShaping(); + void testDragEnterSomeShaping(); + void testDragEnterAllShaping(); }; tst_QDrag::tst_QDrag() @@ -90,5 +217,133 @@ void tst_QDrag::getSetCheck() QCOMPARE(result, Qt::IgnoreAction); } +void tst_QDrag::testDragEnterSelf() +{ +#ifdef Q_WS_X11 + // Widget of 80x80 at 300, 300 + DragCounterAndCreatorWidget dw; + QTest::qWaitForWindowShown(&dw); + + // Press mouse to create a drag in dw + QTest::qWait(100); + QTest::mouseMove(&dw); + DoMouseReleaseHelper aux(&dw); + QTest::mousePress(&dw, Qt::LeftButton); + + // Verify that without a window in the middle the drag goes to dw itself + QCOMPARE(dw.startedDrags, 1); + QCOMPARE(dw.enterEvents, 1); +#endif +} + +void tst_QDrag::testDragEnterNoShaping() +{ +#ifdef Q_WS_X11 + // Widget of 80x80 at 300, 300 + DragCounterAndCreatorWidget dw; + QTest::qWaitForWindowShown(&dw); + + // Widget of 180x180 at 250, 250 + BiggerDragCounterWidget widgetOnTop; + QTest::qWaitForWindowShown(&widgetOnTop); + + // Press mouse to create a drag in dw + QTest::qWait(100); + QTest::mouseMove(&dw); + DoMouseReleaseHelper aux(&dw); + QTest::mousePress(&dw, Qt::LeftButton); + + // Verify that with widgetOnTop in the middle the drag, the drag event does not go to dw + // and goes to widgetOnTop + QCOMPARE(dw.startedDrags, 1); + QCOMPARE(dw.enterEvents, 0); + QCOMPARE(widgetOnTop.enterEvents, 1); +#endif +} + +void tst_QDrag::testDragEnterSomeShaping() +{ +#ifdef Q_WS_X11 + // Widget of 80x80 at 300, 300 + DragCounterAndCreatorWidget dw; + QTest::qWaitForWindowShown(&dw); + + // Widget of 180x180 at 250, 250 + BiggerDragCounterWidget widgetOnTop; + QTest::qWaitForWindowShown(&widgetOnTop); + + // Punch a hole in widgetOnTop to let the mouse go through the widget + // in the center of dw + QBitmap inputShape(180, 180); + inputShape.fill(Qt::color1); + QPainter painter(&inputShape); + painter.fillRect(80, 80, 50, 50, Qt::color0); + painter.end(); + XShapeCombineRegion(QX11Info::display(), widgetOnTop.effectiveWinId(), ShapeInput, 0, 0, QRegion(inputShape).handle(), ShapeSet); + + // Press mouse to create a drag in dw + QTest::qWait(100); + QTest::mouseMove(&dw); + DoMouseReleaseHelper aux(&dw); + QTest::mousePress(&dw, Qt::LeftButton); + + // Verify that with a input shaped widgetOnTop in the middle the drag, the drag event goes to dw + // and does not go to widgetOnTop + QCOMPARE(dw.startedDrags, 1); + QCOMPARE(dw.enterEvents, 1); + QCOMPARE(widgetOnTop.enterEvents, 0); + + // Press mouse to create a drag in dw and move it to the corner of the dw where widgetOnTop is not shaped anymore + DoMouseMoveHelper aux2(&dw, QPoint(1, 1), 100); + DoMouseReleaseHelper aux3(&dw, 200); + QTest::mousePress(&dw, Qt::LeftButton); + + // Verify once we get out of the shaped area the drag event also goes to widgetOnTop + QCOMPARE(dw.startedDrags, 2); + QCOMPARE(dw.enterEvents, 2); + QCOMPARE(widgetOnTop.enterEvents, 1); +#endif +} + +void tst_QDrag::testDragEnterAllShaping() +{ +#ifdef Q_WS_X11 + // Widget of 80x80 at 300, 300 + DragCounterAndCreatorWidget dw; + QTest::qWaitForWindowShown(&dw); + + // Widget of 180x180 at 250, 250 + BiggerDragCounterWidget widgetOnTop; + QTest::qWaitForWindowShown(&widgetOnTop); + + // Make widgetOnTop totally a hole regarding input + QBitmap inputShape(180, 180); + inputShape.fill(Qt::color0); + XShapeCombineRegion(QX11Info::display(), widgetOnTop.effectiveWinId(), ShapeInput, 0, 0, QRegion(inputShape).handle(), ShapeSet); + + // Press mouse to create a drag in dw + QTest::qWait(100); + QTest::mouseMove(&dw); + DoMouseReleaseHelper aux(&dw); + QTest::mousePress(&dw, Qt::LeftButton); + + // Verify that with a input shaped widgetOnTop in the middle the drag, the drag event goes to dw + // and does not go to widgetOnTop + QCOMPARE(dw.startedDrags, 1); + QCOMPARE(dw.enterEvents, 1); + QCOMPARE(widgetOnTop.enterEvents, 0); + + // Press mouse to create a drag in dw and move it to the corner of the dw + DoMouseMoveHelper aux2(&widgetOnTop, QPoint(1, 1)); + DoMouseReleaseHelper aux3(&dw, 200); + QTest::mousePress(&dw, Qt::LeftButton); + + // Verify the event also went to dw + QCOMPARE(dw.startedDrags, 2); + QCOMPARE(dw.enterEvents, 2); + QCOMPARE(widgetOnTop.enterEvents, 0); +#endif +} + QTEST_MAIN(tst_QDrag) #include "tst_qdrag.moc" |