From 54ce087390724b5e03f95b93a5661d0a60765daa Mon Sep 17 00:00:00 2001
From: Dominik Holland <dominik.holland@nokia.com>
Date: Fri, 12 Nov 2010 10:47:55 +0100
Subject: Crash fix, when the Object will be deleted during handling a
 QGestureEvent.

The QGestures will now not be deleted immediatly. QGestureManager waits until all
QGestureEvents are processed and will delete the QGestures afterwards.

Task: QT-4022
Reviewed By: Zeno Albisser
---
 src/gui/kernel/qgesturemanager.cpp | 10 ++++++++--
 src/gui/kernel/qgesturemanager_p.h |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 5e9a0cb..9519447 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -175,9 +175,9 @@ void QGestureManager::cleanupCachedGestures(QObject *target, Qt::GestureType typ
                 m_activeGestures.remove(g);
                 m_gestureOwners.remove(g);
                 m_gestureTargets.remove(g);
+                m_gesturesToDelete.insert(g);
             }
 
-            qDeleteAll(gestures);
             iter = m_objectGestures.erase(iter);
         } else {
             ++iter;
@@ -385,6 +385,11 @@ bool QGestureManager::filterEventThroughContexts(const QMultiMap<QObject *,
         recycle(gesture);
         m_gestureTargets.remove(gesture);
     }
+
+    //Clean up the Gestures
+    qDeleteAll(m_gesturesToDelete);
+    m_gesturesToDelete.clear();
+
     return ret;
 }
 
@@ -447,7 +452,8 @@ void QGestureManager::cancelGesturesForChildren(QGesture *original)
 void QGestureManager::cleanupGesturesForRemovedRecognizer(QGesture *gesture)
 {
     QGestureRecognizer *recognizer = m_deletedRecognizers.value(gesture);
-    Q_ASSERT(recognizer);
+    if(!recognizer) //The Gesture is removed while in the even loop, so the recognizers for this gestures was removed
+        return;
     m_deletedRecognizers.remove(gesture);
     if (m_deletedRecognizers.keys(recognizer).isEmpty()) {
         // no more active gestures, cleanup!
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index 0d84b67..a5a3482 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -130,6 +130,7 @@ private:
 
     QHash<QGestureRecognizer *, QSet<QGesture *> > m_obsoleteGestures;
     QHash<QGesture *, QGestureRecognizer *> m_deletedRecognizers;
+    QSet<QGesture *> m_gesturesToDelete;
     void cleanupGesturesForRemovedRecognizer(QGesture *gesture);
 
     QGesture *getState(QObject *widget, QGestureRecognizer *recognizer,
-- 
cgit v0.12


From 149cfee3fea478640384559e69209a16bfda44a9 Mon Sep 17 00:00:00 2001
From: Dominik Holland <dominik.holland@nokia.com>
Date: Mon, 15 Nov 2010 13:08:03 +0100
Subject: Fixed QGesture autotest for QGesture lazy deletion.

Reviewed By: Trust Me
---
 tests/auto/gestures/tst_gestures.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp
index 667cdd3..ee19125 100644
--- a/tests/auto/gestures/tst_gestures.cpp
+++ b/tests/auto/gestures/tst_gestures.cpp
@@ -1486,13 +1486,15 @@ void tst_Gestures::ungrabGesture() // a method on QWidget
     QVERIFY(customGestureA.data() != customGestureB.data());
 
     a->ungrabGesture(CustomGesture::GestureType);
-    QVERIFY(customGestureA.isNull());
+    //We changed the deletion of Gestures to lazy during QT-4022, so we can't ensure the QGesture is deleted until now
     QVERIFY(!customGestureB.isNull());
 
     a->gestures.clear();
     a->reset();
     // send again to 'b' and make sure a never gets it.
     sendCustomGesture(&event, b);
+    //After all Gestures are processed in the QGestureManager, we can ensure the QGesture is now deleted
+    QVERIFY(customGestureA.isNull());
     QCOMPARE(a->gestureEventsReceived, 0);
     QCOMPARE(a->gestureOverrideEventsReceived, 0);
 }
-- 
cgit v0.12