diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2010-05-03 14:03:11 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2010-05-03 15:31:29 (GMT) |
commit | 7bcc52d4c1905a5d1777c4c43427e359948959fe (patch) | |
tree | bc2f5fe8628c42a8bf6f18bc2e4bc9b56da98db0 | |
parent | fe59ef0bf3c8d0ae92c15cd69839df2232a60936 (diff) | |
download | Qt-7bcc52d4c1905a5d1777c4c43427e359948959fe.zip Qt-7bcc52d4c1905a5d1777c4c43427e359948959fe.tar.gz Qt-7bcc52d4c1905a5d1777c4c43427e359948959fe.tar.bz2 |
Fixes a crash in QGestureManager when unregistering recognizers.
Task-number: QTBUG-9801
Reviewed-by: Thomas Zander
-rw-r--r-- | src/gui/kernel/qgesturemanager.cpp | 20 | ||||
-rw-r--r-- | tests/auto/gestures/tst_gestures.cpp | 71 |
2 files changed, 81 insertions, 10 deletions
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index aa6720e..a806629 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -132,20 +132,20 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type) QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); if (list.contains(recognizer)) { m_deletedRecognizers.insert(g, recognizer); - m_gestureToRecognizer.remove(g); } } - foreach (QGestureRecognizer *recognizer, list) { - QList<QGesture *> obsoleteGestures; - QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin(); - while (iter != m_objectGestures.end()) { - ObjectGesture objectGesture = iter.key(); - if (objectGesture.gesture == type) - obsoleteGestures << iter.value(); - ++iter; + QMap<ObjectGesture, QList<QGesture *> >::const_iterator iter = m_objectGestures.begin(); + while (iter != m_objectGestures.end()) { + ObjectGesture objectGesture = iter.key(); + if (objectGesture.gesture == type) { + foreach (QGesture *g, iter.value()) { + QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g); + m_gestureToRecognizer.remove(g); + m_obsoleteGestures[recognizer].append(g); + } } - m_obsoleteGestures.insert(recognizer, obsoleteGestures); + ++iter; } } diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index f8ecca3..dfadf48 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -50,6 +50,7 @@ #include <qgesturerecognizer.h> #include <qgraphicsitem.h> #include <qgraphicsview.h> +#include <qmainwindow.h> #include <qdebug.h> @@ -355,6 +356,7 @@ private slots: void deleteGestureTargetItem(); void viewportCoordinates(); void partialGesturePropagation(); + void testQGestureRecognizerCleanup(); }; tst_Gestures::tst_Gestures() @@ -1949,5 +1951,74 @@ void tst_Gestures::partialGesturePropagation() QCOMPARE(item4->gestureEventsReceived, 0); } +class WinNativePan : public QPanGesture { +public: + WinNativePan() {} +}; + +class Pan : public QPanGesture { +public: + Pan() {} +}; + +class CustomPan : public QPanGesture { +public: + CustomPan() {} +}; + +// Recognizer for active gesture triggers on mouse press +class PanRecognizer : public QGestureRecognizer { +public: + enum PanType { Platform, Default, Custom }; + + PanRecognizer(int id) : m_id(id) {} + QGesture *create(QObject *) { + switch(m_id) { + case Platform: return new WinNativePan(); + case Default: return new Pan(); + default: return new CustomPan(); + } + } + + Result recognize(QGesture *, QObject *, QEvent *) { return QGestureRecognizer::Ignore; } + + const int m_id; +}; + +void tst_Gestures::testQGestureRecognizerCleanup() +{ + // Clean first the current recognizers in QGManager + QGestureRecognizer::unregisterRecognizer(Qt::PanGesture); + + // v-- Qt singleton QGManager initialization + + // Mimic QGestureManager: register both default and "platform" recognizers + // (this is done in windows when QT_NO_NATIVE_GESTURES is not defined) + PanRecognizer *def = new PanRecognizer(PanRecognizer::Default); + QGestureRecognizer::registerRecognizer(def); + PanRecognizer *plt = new PanRecognizer(PanRecognizer::Platform); + QGestureRecognizer::registerRecognizer(plt); + qDebug () << "register: default =" << def << "; platform =" << plt; + + // ^-- Qt singleton QGManager initialization + + // Here, application code would start + + // Create QGV (has a QAScrollArea, which uses Qt::PanGesture) + QMainWindow *w = new QMainWindow; + QGraphicsView *v = new QGraphicsView(); + w->setCentralWidget(v); + + // Unregister Qt recognizers + QGestureRecognizer::unregisterRecognizer(Qt::PanGesture); + + // Register a custom Pan recognizer + //QGestureRecognizer::registerRecognizer(new PanRecognizer(PanRecognizer::Custom)); + + w->show(); + QTest::qWaitForWindowShown(w); + delete w; +} + QTEST_MAIN(tst_Gestures) #include "tst_gestures.moc" |