diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2022-11-24 16:56:01 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-04-25 19:56:43 +0000 |
commit | 08cb6771f39ff35398b77d99d1a45d22af2df809 (patch) | |
tree | 2057c407a1451c7469f3482c2c778e142fc9feb0 | |
parent | 0fde572310ac0c834d8b04a85afa150e6223ae75 (diff) |
TapHandler: don't (dis)connect signals to a null window
This is unexpected, but we're told that it happens somehow.
Pick-to: 6.6 6.5
Fixes: QTBUG-108696
Change-Id: I738099f43003056f7a24c09b1dc36024a81cbbb1
Reviewed-by: Vladimir Belyavsky <belyavskyv@gmail.com>
Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io>
(cherry picked from commit 821f8f1f6c74b562bd984a12c959bc137dd2c11f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quick/handlers/qquicktaphandler.cpp | 22 | ||||
-rw-r--r-- | src/quick/handlers/qquicktaphandler_p.h | 1 |
2 files changed, 18 insertions, 5 deletions
diff --git a/src/quick/handlers/qquicktaphandler.cpp b/src/quick/handlers/qquicktaphandler.cpp index f662bcbc2a..accf307382 100644 --- a/src/quick/handlers/qquicktaphandler.cpp +++ b/src/quick/handlers/qquicktaphandler.cpp @@ -461,13 +461,25 @@ void QQuickTapHandler::onGrabChanged(QQuickPointerHandler *grabber, QPointingDev void QQuickTapHandler::connectPreRenderSignal(bool conn) { + // disconnect pre-existing connection, if any + disconnect(m_preRenderSignalConnection); + auto par = parentItem(); - if (!par) + if (!par || !par->window()) return; - if (conn) - connect(par->window(), &QQuickWindow::beforeSynchronizing, this, &QQuickTapHandler::updateTimeHeld); - else - disconnect(par->window(), &QQuickWindow::beforeSynchronizing, this, &QQuickTapHandler::updateTimeHeld); + + /* + Note: beforeSynchronizing is emitted from the SG thread, and the + timeHeldChanged signal can be used to do arbitrary things in user QML. + + But the docs say the GUI thread is blockd, and "Therefore, it is safe + to access GUI thread thread data in a slot or lambda that is connected + with Qt::DirectConnection." We use the default AutoConnection just in case. + */ + if (conn) { + m_preRenderSignalConnection = connect(par->window(), &QQuickWindow::beforeSynchronizing, + this, &QQuickTapHandler::updateTimeHeld); + } } void QQuickTapHandler::updateTimeHeld() diff --git a/src/quick/handlers/qquicktaphandler_p.h b/src/quick/handlers/qquicktaphandler_p.h index 7b78690572..c1e7d4bd50 100644 --- a/src/quick/handlers/qquicktaphandler_p.h +++ b/src/quick/handlers/qquicktaphandler_p.h @@ -103,6 +103,7 @@ private: QBasicTimer m_longPressTimer; QBasicTimer m_doubleTapTimer; QEventPoint m_singleTapReleasedPoint; + QMetaObject::Connection m_preRenderSignalConnection; Qt::MouseButton m_singleTapReleasedButton; int m_tapCount = 0; int m_longPressThreshold = -1; |