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>
This commit is contained in:
parent
ca11725659
commit
e56b2d7a9e
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user