From c1ead32a84db96fd1b48e47d81511adf64cfe410 Mon Sep 17 00:00:00 2001 From: Jan Arve Saether Date: Mon, 23 Apr 2018 11:39:56 +0200 Subject: Fix crash in QMacPanGestureRecognizer The reason it crashed was this: 1. Button was pressed => _panTimer started with the graphics view as destination. 2. Button was released => the graphicsview is destroyed 3. 300 ms later: Qt tries to deliver TimerEvent from _panTimer to the graphics view. Unfortunately, the graphics view is deleted, but Qt doesn't know that... (*crash*) We therefore chose to start the timer with a destination we are controlling the lifetime of: the QMacPanGestureRecognizer. Inside the timerEvent of that we can check if the actual target is already destroyed. Task-number: QTBUG-60404 Change-Id: Iff8f5b7217de42c4c5cf551ca507f0cff1c99a78 Reviewed-by: Frederik Gladhorn --- tests/auto/other/gestures/tst_gestures.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'tests/auto/other/gestures/tst_gestures.cpp') diff --git a/tests/auto/other/gestures/tst_gestures.cpp b/tests/auto/other/gestures/tst_gestures.cpp index 0767efb817..9abe9a77c0 100644 --- a/tests/auto/other/gestures/tst_gestures.cpp +++ b/tests/auto/other/gestures/tst_gestures.cpp @@ -331,6 +331,9 @@ private slots: void graphicsViewParentPropagation(); void panelPropagation(); void panelStacksBehindParent(); +#ifdef Q_OS_MACOS + void deleteMacPanGestureRecognizerTargetWidget(); +#endif void deleteGestureTargetWidget(); void deleteGestureTargetItem_data(); void deleteGestureTargetItem(); @@ -1807,6 +1810,31 @@ void tst_Gestures::panelStacksBehindParent() QCOMPARE(panel->gestureOverrideEventsReceived, 0); } +#ifdef Q_OS_MACOS +void tst_Gestures::deleteMacPanGestureRecognizerTargetWidget() +{ + QWidget window; + window.resize(400,400); + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene, &window); + view->resize(400, 400); + window.show(); + + QVERIFY(QTest::qWaitForWindowExposed(&window)); + QTouchDevice *device = QTest::createTouchDevice(); + // QMacOSPenGestureRecognizer will start a timer on a touch press event + QTest::touchEvent(&window, device).press(1, QPoint(100, 100), &window); + delete view; + + // wait until after that the QMacOSPenGestureRecognizer timer (300ms) is triggered. + // This is needed so that the whole test does not finish before the timer triggers + // and to make sure it crashes while executing *this* function. (otherwise it might give the + // impression that some of the subsequent test function caused the crash...) + + QTest::qWait(400); // DO NOT CRASH while waiting +} +#endif + void tst_Gestures::deleteGestureTargetWidget() { } -- cgit v1.2.3