From 69e925444ecebd352462f742d894b326d4cc9a72 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Mon, 3 Oct 2011 10:59:16 +1000 Subject: [PATCH] Fix order of QSGItem mouse filtering. QGraphicsView filtered child items beginning with the item's parent, grandparent, greatgrandparent... QSGCanvas did the opposite, which breaks the QML mouse handling element filtering logic. Task-number: QTBUG-21446 Change-Id: I18e125305eef536237195895a7f41f88b532d4aa Reviewed-on: http://codereview.qt-project.org/5819 Reviewed-by: Qt Sanity Bot Reviewed-by: Bea Lam --- src/declarative/items/qsgcanvas.cpp | 6 +-- tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp | 53 +++++++++++++++++++++- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 2ced204..d4a74cd 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -1439,14 +1439,14 @@ bool QSGCanvasPrivate::sendFilteredMouseEvent(QSGItem *target, QSGItem *item, QM if (!target) return false; - if (sendFilteredMouseEvent(target->parentItem(), item, event)) - return true; - QSGItemPrivate *targetPrivate = QSGItemPrivate::get(target); if (targetPrivate->filtersChildMouseEvents) if (target->childMouseEventFilter(item, event)) return true; + if (sendFilteredMouseEvent(target->parentItem(), item, event)) + return true; + return false; } diff --git a/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp b/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp index 32271b0..a504de8 100644 --- a/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp +++ b/tests/auto/declarative/qsgcanvas/tst_qsgcanvas.cpp @@ -121,9 +121,11 @@ class TestTouchItem : public QSGRectangle Q_OBJECT public: TestTouchItem(QSGItem *parent = 0) - : QSGRectangle(parent), acceptEvents(true) + : QSGRectangle(parent), acceptEvents(true), mousePressId(0) { border()->setWidth(1); + setAcceptedMouseButtons(Qt::LeftButton); + setFiltersChildMouseEvents(true); } void reset() { @@ -136,6 +138,7 @@ public: bool acceptEvents; TouchEventData lastEvent; + int mousePressId; protected: virtual void touchEvent(QTouchEvent *event) { @@ -146,8 +149,20 @@ protected: lastEvent = makeTouchData(event->type(), event->widget(), event->touchPointStates(), event->touchPoints()); event->accept(); } + + virtual void mousePressEvent(QMouseEvent *event) { + mousePressId = ++mousePressNum; + } + + bool childMouseEventFilter(QSGItem *, QEvent *) { + mousePressId = ++mousePressNum; + return false; + } + + static int mousePressNum; }; +int TestTouchItem::mousePressNum = 0; class ConstantUpdateItem : public QSGItem { @@ -181,6 +196,7 @@ private slots: void touchEvent_propagation_data(); void clearCanvas(); + void mouseFiltering(); }; tst_qsgcanvas::tst_qsgcanvas() @@ -464,6 +480,41 @@ void tst_qsgcanvas::clearCanvas() delete item; } +void tst_qsgcanvas::mouseFiltering() +{ + QSGCanvas *canvas = new QSGCanvas; + canvas->resize(250, 250); + canvas->move(100, 100); + canvas->show(); + + TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); + bottomItem->setObjectName("Bottom Item"); + bottomItem->setSize(QSizeF(150, 150)); + + TestTouchItem *middleItem = new TestTouchItem(bottomItem); + middleItem->setObjectName("Middle Item"); + middleItem->setPos(QPointF(50, 50)); + middleItem->setSize(QSizeF(150, 150)); + + TestTouchItem *topItem = new TestTouchItem(middleItem); + topItem->setObjectName("Top Item"); + topItem->setPos(QPointF(50, 50)); + topItem->setSize(QSizeF(150, 150)); + + QPoint pos(100, 100); + + QTest::mousePress(canvas, Qt::LeftButton, 0, pos); + QTest::qWait(50); + + // Mouse filtering propagates down the stack, so the + // correct order is + // 1. middleItem filters event + // 2. bottomItem filters event + // 3. topItem receives event + QCOMPARE(middleItem->mousePressId, 1); + QCOMPARE(bottomItem->mousePressId, 2); + QCOMPARE(topItem->mousePressId, 3); +} QTEST_MAIN(tst_qsgcanvas) -- 2.7.4