diff options
author | Caio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org> | 2011-08-29 10:08:45 -0300 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-08-31 03:23:03 +0200 |
commit | ede31210aafbfb961059a6e0934d6e6a79e06447 (patch) | |
tree | 6243931a2f63ce775b280e591cd714b823477230 | |
parent | acf715c4e59a5ec1b4332522bf285ebeebfc7e5c (diff) |
Fix extra hover enter events being sent by QSGCanvas
This fixes two issues: when one item is entered it is getting the
enter event twice. When we are moving from two items that share the
same parent, the parent is getting enter event -- which shouldn't
happen.
Change-Id: If0fe6d64d1f7cfb8679ce11edda7c02dc3783f9a
Reviewed-on: http://codereview.qt.nokia.com/3860
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Alan Alpert <alan.alpert@nokia.com>
-rw-r--r-- | src/declarative/items/qsgcanvas.cpp | 28 | ||||
-rw-r--r-- | tests/auto/declarative/qsgitem/tst_qsgitem.cpp | 84 |
2 files changed, 97 insertions, 15 deletions
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index e62031ab38..23b2b437ce 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -1251,38 +1251,36 @@ bool QSGCanvasPrivate::deliverHoverEvent(QSGItem *item, const QPointF &scenePos, //move accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted); } else { - QList<QSGItem*> parents; + QList<QSGItem *> itemsToHover; QSGItem* parent = item; - parents << item; + itemsToHover << item; while ((parent = parent->parentItem())) - parents << parent; + itemsToHover << parent; - //exit from previous (excepting ancestors) - while (!hoverItems.isEmpty() && !parents.contains(hoverItems[0])){ + // Leaving from previous hovered items until we reach the item or one of its ancestors. + while (!hoverItems.isEmpty() && !itemsToHover.contains(hoverItems[0])) { sendHoverEvent(QEvent::HoverLeave, hoverItems[0], scenePos, lastScenePos, modifiers, accepted); hoverItems.removeFirst(); } if (!hoverItems.isEmpty() && hoverItems[0] == item){//Not entering a new Item + // ### Shouldn't we send moves for the parent items as well? accepted = sendHoverEvent(QEvent::HoverMove, item, scenePos, lastScenePos, modifiers, accepted); } else { - //enter any ancestors that also wish to be hovered and aren't + // Enter items that are not entered yet. int startIdx = -1; if (!hoverItems.isEmpty()) - startIdx = parents.indexOf(hoverItems[0]); + startIdx = itemsToHover.indexOf(hoverItems[0]) - 1; if (startIdx == -1) - startIdx = parents.count() - 1; + startIdx = itemsToHover.count() - 1; for (int i = startIdx; i >= 0; i--) { - if (QSGItemPrivate::get(parents[i])->hoverEnabled) { - hoverItems.prepend(parents[i]); - sendHoverEvent(QEvent::HoverEnter, parents[i], scenePos, lastScenePos, modifiers, accepted); + QSGItem *itemToHover = itemsToHover[i]; + if (QSGItemPrivate::get(itemToHover)->hoverEnabled) { + hoverItems.prepend(itemToHover); + sendHoverEvent(QEvent::HoverEnter, itemToHover, scenePos, lastScenePos, modifiers, accepted); } } - - //enter new item - hoverItems.prepend(item); - accepted = sendHoverEvent(QEvent::HoverEnter, item, scenePos, lastScenePos, modifiers, accepted); } } return true; diff --git a/tests/auto/declarative/qsgitem/tst_qsgitem.cpp b/tests/auto/declarative/qsgitem/tst_qsgitem.cpp index 7a612c433b..5c3b9db526 100644 --- a/tests/auto/declarative/qsgitem/tst_qsgitem.cpp +++ b/tests/auto/declarative/qsgitem/tst_qsgitem.cpp @@ -127,6 +127,7 @@ private slots: void wheelEvent_data(); void wheelEvent(); + void hoverEventInParent(); private: void ensureFocus(QWidget *w) { @@ -894,6 +895,89 @@ void tst_qsgitem::wheelEvent() delete canvas; } +class HoverItem : public QSGItem +{ +Q_OBJECT +public: + HoverItem(QSGItem *parent = 0) + : QSGItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0) + { } + void resetCounters() { + hoverEnterCount = 0; + hoverMoveCount = 0; + hoverLeaveCount = 0; + } + int hoverEnterCount; + int hoverMoveCount; + int hoverLeaveCount; +protected: + virtual void hoverEnterEvent(QHoverEvent *event) { + event->accept(); + ++hoverEnterCount; + } + virtual void hoverMoveEvent(QHoverEvent *event) { + event->accept(); + ++hoverMoveCount; + } + virtual void hoverLeaveEvent(QHoverEvent *event) { + event->accept(); + ++hoverLeaveCount; + } +}; + +// ### For some unknown reason QTest::mouseMove() isn't working correctly. +static void sendMouseMove(QObject *object, const QPoint &position) +{ + QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0); + QApplication::sendEvent(object, &moveEvent); +} + +void tst_qsgitem::hoverEventInParent() +{ + QSGCanvas *canvas = new QSGCanvas(); + canvas->resize(200, 200); + canvas->show(); + + HoverItem *parentItem = new HoverItem(canvas->rootItem()); + parentItem->setSize(QSizeF(200, 200)); + parentItem->setAcceptHoverEvents(true); + + HoverItem *leftItem = new HoverItem(parentItem); + leftItem->setSize(QSizeF(100, 200)); + leftItem->setAcceptHoverEvents(true); + + HoverItem *rightItem = new HoverItem(parentItem); + rightItem->setSize(QSizeF(100, 200)); + rightItem->setPos(QPointF(100, 0)); + rightItem->setAcceptHoverEvents(true); + + const QPoint insideLeft(50, 100); + const QPoint insideRight(150, 100); + + sendMouseMove(canvas, insideLeft); + parentItem->resetCounters(); + leftItem->resetCounters(); + rightItem->resetCounters(); + + sendMouseMove(canvas, insideRight); + QCOMPARE(parentItem->hoverEnterCount, 0); + QCOMPARE(parentItem->hoverLeaveCount, 0); + QCOMPARE(leftItem->hoverEnterCount, 0); + QCOMPARE(leftItem->hoverLeaveCount, 1); + QCOMPARE(rightItem->hoverEnterCount, 1); + QCOMPARE(rightItem->hoverLeaveCount, 0); + + sendMouseMove(canvas, insideLeft); + QCOMPARE(parentItem->hoverEnterCount, 0); + QCOMPARE(parentItem->hoverLeaveCount, 0); + QCOMPARE(leftItem->hoverEnterCount, 1); + QCOMPARE(leftItem->hoverLeaveCount, 1); + QCOMPARE(rightItem->hoverEnterCount, 1); + QCOMPARE(rightItem->hoverLeaveCount, 1); + + delete canvas; +} + QTEST_MAIN(tst_qsgitem) #include "tst_qsgitem.moc" |