summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer.cpp15
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer_p.h4
-rw-r--r--tests/auto/other/gestures/tst_gestures.cpp28
3 files changed, 45 insertions, 2 deletions
diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp
index 6dedd3c2d0..d39b93e320 100644
--- a/src/widgets/kernel/qmacgesturerecognizer.cpp
+++ b/src/widgets/kernel/qmacgesturerecognizer.cpp
@@ -43,6 +43,7 @@
#include "qevent.h"
#include "qwidget.h"
#include "qdebug.h"
+#include <QtCore/qcoreapplication.h>
#ifndef QT_NO_GESTURES
@@ -181,6 +182,16 @@ QGesture *QMacPanGestureRecognizer::create(QObject *target)
return 0;
}
+void QMacPanGestureRecognizer::timerEvent(QTimerEvent *ev)
+{
+ if (ev->timerId() == _panTimer.timerId()) {
+ if (_panTimer.isActive())
+ _panTimer.stop();
+ if (_target)
+ QCoreApplication::sendEvent(_target, ev);
+ }
+}
+
QGestureRecognizer::Result
QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *event)
{
@@ -195,7 +206,8 @@ QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *
if (ev->touchPoints().size() == 1) {
reset(gesture);
_startPos = QCursor::pos();
- _panTimer.start(panBeginDelay, target);
+ _target = target;
+ _panTimer.start(panBeginDelay, this);
_panCanceled = false;
return QGestureRecognizer::MayBeGesture;
}
@@ -242,7 +254,6 @@ QMacPanGestureRecognizer::recognize(QGesture *gesture, QObject *target, QEvent *
case QEvent::Timer: {
QTimerEvent *ev = static_cast<QTimerEvent *>(event);
if (ev->timerId() == _panTimer.timerId()) {
- _panTimer.stop();
if (_panCanceled)
break;
// Begin new pan session!
diff --git a/src/widgets/kernel/qmacgesturerecognizer_p.h b/src/widgets/kernel/qmacgesturerecognizer_p.h
index be3f3266ac..e381a6cc2f 100644
--- a/src/widgets/kernel/qmacgesturerecognizer_p.h
+++ b/src/widgets/kernel/qmacgesturerecognizer_p.h
@@ -55,6 +55,7 @@
#include "qtimer.h"
#include "qpoint.h"
#include "qgesturerecognizer.h"
+#include <QtCore/qpointer.h>
#ifndef QT_NO_GESTURES
@@ -88,10 +89,13 @@ public:
QGesture *create(QObject *target);
QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event);
void reset(QGesture *gesture);
+protected:
+ void timerEvent(QTimerEvent *ev) override;
private:
QPointF _startPos;
QBasicTimer _panTimer;
bool _panCanceled;
+ QPointer<QObject> _target;
};
QT_END_NAMESPACE
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()
{
}