summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios/quiview.mm
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2022-06-17 13:29:55 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2022-07-01 15:42:10 +0200
commite56b2d7a9e1a762edaf6c34748a4bd2f63648069 (patch)
treea10c31ecd6c2ef306d9e5a9dcacb8cdeb23bb63a /src/plugins/platforms/ios/quiview.mm
parentca11725659a14f1b57de8f35b783bcd40d822dc6 (diff)
iOS: Send touch events asynchronously to avoid deadlocking UIKit event loop
Although CFRunLoop is documented to support nesting, the UIKit event delivery machinery is not prepared to handle nested event loops. If the user starts a nested event loop in response to e.g. a button press/release, it will deadlock the entire UIKit event machinery, stopping processing of both screen updates (CATransactions) as well as other events. This became an issue on iPhone hardware device in iOS 15, but can not be reproduces on iPads or in the simulator. To be on the safe side, we deliver all touch events asynchronously, even if that means the application code will always be one step behind the event delivered by the operating system. Fixes: QTBUG-98651 Pick-to: 6.4 6.3 6.2 5.15 Change-Id: Id0a9fa60b7bb7aa98606d46257e99eac144a1080 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/plugins/platforms/ios/quiview.mm')
-rw-r--r--src/plugins/platforms/ios/quiview.mm12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index eac492044c..32f27587c6 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -430,7 +430,10 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>(
self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
} else {
- QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::SynchronousDelivery>(
+ // Send the touch event asynchronously, as the application might spin a recursive
+ // event loop in response to the touch event (a dialog e.g.), which will deadlock
+ // the UIKit event delivery system (QTBUG-98651).
+ QWindowSystemInterface::handleTouchEvent<QWindowSystemInterface::AsynchronousDelivery>(
self.platformWindow->window(), timeStamp, iosIntegration->touchDevice(), m_activeTouches.values());
}
}
@@ -536,7 +539,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
- QWindowSystemInterface::handleTouchCancelEvent(self.platformWindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
+
+ // Send the touch event asynchronously, as the application might spin a recursive
+ // event loop in response to the touch event (a dialog e.g.), which will deadlock
+ // the UIKit event delivery system (QTBUG-98651).
+ QWindowSystemInterface::handleTouchCancelEvent<QWindowSystemInterface::AsynchronousDelivery>(
+ self.platformWindow->window(), ulong(timestamp * 1000), iosIntegration->touchDevice());
}
- (int)mapPressTypeToKey:(UIPress*)press withModifiers:(Qt::KeyboardModifiers)qtModifiers text:(QString &)text