summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-10-14 14:45:27 +0200
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-10-22 16:59:18 +0200
commitc5c1b878891b5ace5a71b95ea62229e26722fdba (patch)
tree7ef44d068a73c35efd938870c24fe6f0b778969e
parentd1a60dcbddbae46aaea655bb55c0c8fd46f38b2c (diff)
Fixed gesture event delivery when several gestures are triggered.
When there are two different gestures are being triggered and they are supposed to be sent to different widgets, don't stop event "propagation" when the first event is successfully delivered. Reviewed-by: trustme
-rw-r--r--src/gui/kernel/qapplication.cpp2
-rw-r--r--src/gui/kernel/qgesturemanager.cpp41
-rw-r--r--tests/auto/gestures/tst_gestures.cpp45
3 files changed, 59 insertions, 29 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 30440ebed4..aee8afc125 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -4183,7 +4183,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
res = d->notify_helper(w, &ge);
gestureEvent->spont = false;
eventAccepted = ge.isAccepted();
- if (res && eventAccepted)
+ if (res && eventAccepted && allGestures.isEmpty())
break;
if (!eventAccepted) {
// ### two ways to ignore the event/gesture
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 4f8a9114c3..8928d1ca2b 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -361,7 +361,8 @@ void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures,
GesturesPerReceiver groupedGestures;
// for conflicted gestures the key is always the innermost widget (i.e. the child)
GesturesPerReceiver conflictedGestures;
- QMultiHash<QObject *, QGesture *> objectGestures;
+ typedef QMultiHash<QWidget *, QGesture *> WidgetMultiGestures;
+ WidgetMultiGestures widgetMultiGestures;
foreach (QGesture *gesture, gestures) {
QObject *target = gestureTargets.value(gesture, 0);
@@ -380,7 +381,7 @@ void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures,
if (target) {
gestureTargets.insert(gesture, target);
if (target->isWidgetType())
- objectGestures.insert(target, gesture);
+ widgetMultiGestures.insert(static_cast<QWidget *>(target), gesture);
groupedGestures[target].append(gesture);
} else {
qWarning() << "QGestureManager::deliverEvent: could not find the target for gesture"
@@ -389,30 +390,26 @@ void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures,
}
}
- typedef QMultiHash<QObject *, QGesture *>::const_iterator ObjectGesturesIterator;
- for (ObjectGesturesIterator it = objectGestures.begin(),
- e = objectGestures.end(); it != e; ++it) {
- QObject *object1 = it.key();
- QWidget *widget1 = qobject_cast<QWidget *>(object1);
- QGraphicsObject *item1 = qobject_cast<QGraphicsObject *>(object1);
+ typedef WidgetMultiGestures::const_iterator WidgetMultiGesturesIterator;
+ for (WidgetMultiGesturesIterator it = widgetMultiGestures.begin(),
+ e = widgetMultiGestures.end(); it != e; ++it) {
+ QWidget *widget1 = it.key();
QGesture *gesture1 = it.value();
- ObjectGesturesIterator cit = it;
+ WidgetMultiGesturesIterator cit = it;
for (++cit; cit != e; ++cit) {
- QObject *object2 = cit.key();
- QWidget *widget2 = qobject_cast<QWidget *>(object2);
- QGraphicsObject *item2 = qobject_cast<QGraphicsObject *>(object2);
+ QWidget *widget2 = cit.key();
QGesture *gesture2 = cit.value();
+ if (gesture1->gestureType() != gesture2->gestureType())
+ continue;
// TODO: ugly, rewrite this.
- if ((widget1 && widget2 && widget2->isAncestorOf(widget1)) ||
- (item1 && item2 && item2->isAncestorOf(item1))) {
- groupedGestures[object2].removeOne(gesture2);
- groupedGestures[object1].removeOne(gesture1);
- conflictedGestures[object1].append(gesture1);
- } else if ((widget1 && widget2 && widget1->isAncestorOf(widget2)) ||
- (item1 && item2 && item1->isAncestorOf(item2))) {
- groupedGestures[object2].removeOne(gesture2);
- groupedGestures[object1].removeOne(gesture1);
- conflictedGestures[object2].append(gesture2);
+ if ((widget1 && widget2 && widget2->isAncestorOf(widget1))) {
+ groupedGestures[widget2].removeOne(gesture2);
+ groupedGestures[widget1].removeOne(gesture1);
+ conflictedGestures[widget1].append(gesture1);
+ } else if ((widget1 && widget2 && widget1->isAncestorOf(widget2))) {
+ groupedGestures[widget2].removeOne(gesture2);
+ groupedGestures[widget1].removeOne(gesture1);
+ conflictedGestures[widget2].append(gesture2);
}
}
}
diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp
index 3ce5b86ec4..a5e66cffa6 100644
--- a/tests/auto/gestures/tst_gestures.cpp
+++ b/tests/auto/gestures/tst_gestures.cpp
@@ -105,8 +105,8 @@ class CustomGestureRecognizer : public QGestureRecognizer
public:
CustomGestureRecognizer()
{
- CustomEvent::EventType = QEvent::registerEventType();
- eventsCounter = 0;
+ if (!CustomEvent::EventType)
+ CustomEvent::EventType = QEvent::registerEventType();
}
QGesture* createGesture(QObject *)
@@ -123,7 +123,6 @@ public:
g->serial = e->serial;
if (e->hasHotSpot)
g->setHotSpot(e->hotSpot);
- ++eventsCounter;
if (g->serial >= CustomGesture::SerialFinishedThreshold)
result |= QGestureRecognizer::GestureFinished;
else if (g->serial >= CustomGesture::SerialStartedThreshold)
@@ -143,9 +142,6 @@ public:
g->serial = 0;
QGestureRecognizer::reset(state);
}
-
- int eventsCounter;
- QString name;
};
class GestureWidget : public QWidget
@@ -272,6 +268,7 @@ private slots:
void graphicsItemGesture();
void explicitGraphicsObjectTarget();
void gestureOverChildGraphicsItem();
+ void multipleGestures();
};
tst_Gestures::tst_Gestures()
@@ -785,5 +782,41 @@ void tst_Gestures::gestureOverChildGraphicsItem()
QCOMPARE(item1->gestureOverrideEventsReceived, TotalGestureEventsCount);
}
+void tst_Gestures::multipleGestures()
+{
+ GestureWidget parent("parent");
+ QVBoxLayout *l = new QVBoxLayout(&parent);
+ GestureWidget *child = new GestureWidget("child");
+ l->addWidget(child);
+
+ Qt::GestureType SecondGesture = qApp->registerGestureRecognizer(new CustomGestureRecognizer);
+
+ parent.grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture);
+ child->grabGesture(SecondGesture, Qt::WidgetWithChildrenGesture);
+
+ CustomEvent event;
+ // sending events that form a gesture to one widget, but they will be
+ // filtered by two different gesture recognizers and will generate two
+ // QGesture objects. Check that those gesture objects are delivered to
+ // different widgets properly.
+ sendCustomGesture(&event, child);
+
+ static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1;
+ static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1;
+
+ QCOMPARE(child->customEventsReceived, TotalCustomEventsCount);
+ QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount);
+ QCOMPARE(child->gestureOverrideEventsReceived, 0);
+ QCOMPARE(child->events.all.size(), TotalGestureEventsCount);
+ for(int i = 0; i < child->events.all.size(); ++i)
+ QCOMPARE(child->events.all.at(i), SecondGesture);
+
+ QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount);
+ QCOMPARE(parent.gestureOverrideEventsReceived, 0);
+ QCOMPARE(parent.events.all.size(), TotalGestureEventsCount);
+ for(int i = 0; i < child->events.all.size(); ++i)
+ QCOMPARE(parent.events.all.at(i), CustomGesture::GestureType);
+}
+
QTEST_MAIN(tst_Gestures)
#include "tst_gestures.moc"