summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-10-14 12:45:27 (GMT)
committerDenis Dzyubenko <denis.dzyubenko@nokia.com>2009-10-22 14:59:18 (GMT)
commitc5c1b878891b5ace5a71b95ea62229e26722fdba (patch)
tree7ef44d068a73c35efd938870c24fe6f0b778969e
parentd1a60dcbddbae46aaea655bb55c0c8fd46f38b2c (diff)
downloadQt-c5c1b878891b5ace5a71b95ea62229e26722fdba.zip
Qt-c5c1b878891b5ace5a71b95ea62229e26722fdba.tar.gz
Qt-c5c1b878891b5ace5a71b95ea62229e26722fdba.tar.bz2
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 30440eb..aee8afc 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 4f8a911..8928d1c 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 3ce5b86..a5e66cf 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"