aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaio Marcelo de Oliveira Filho <caio.oliveira@openbossa.org>2011-08-29 10:08:45 -0300
committerQt by Nokia <qt-info@nokia.com>2011-08-31 03:23:03 +0200
commitede31210aafbfb961059a6e0934d6e6a79e06447 (patch)
tree6243931a2f63ce775b280e591cd714b823477230
parentacf715c4e59a5ec1b4332522bf285ebeebfc7e5c (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.cpp28
-rw-r--r--tests/auto/declarative/qsgitem/tst_qsgitem.cpp84
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"