summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-08-15 15:55:48 +0200
committerRichard Moe Gustavsen <richard.gustavsen@qt.io>2022-08-18 19:53:21 +0200
commit0250f9364fbf31950601bf27c2a93c520c4abd80 (patch)
tree3f9134cd75ca6d49ae234b70e3011b4c911ef9c2 /src/plugins/platforms/ios
parent78c85616585d3e6b9346d0a0ed236c23127b3810 (diff)
iOS: use NSProcessInfo to resolve timestamps in simulator builds
We currently build Qt for simulator using X86_64, even on ARM based macs. This results in the simulator running on ARM, while the app is running inside it using Rosetta. And with this combination, the event.timestamp, which is documented to be in seconds, looks to be something else, and is not progressing in sync with a normal clock. Sending out mouse events with a timestamp that doesn't follow normal clock time will cause problems for mouse-, and pointer handlers that uses them to e.g calculate the time between a press and release, and to decide if the user is performing a tap or a drag. For that reason, we choose to ignore UIEvent.timestamp under the mentioned condition, and instead rely on NSProcessInfo. Note that if we force the whole simulator to use Rosetta (and not only the Qt app), the timestamps will progress normally. Fixes: QTBUG-105810 Pick-to: 6.4 6.3 6.2 Change-Id: Ib4e60593cac3230567ebc53d634f434fcefc98d0 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/ios')
-rw-r--r--src/plugins/platforms/ios/quiview.mm36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 85f27f8450..63dfab674c 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -24,6 +24,32 @@
Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
Q_LOGGING_CATEGORY(lcQpaInputEvents, "qt.qpa.input.events")
+namespace {
+inline ulong getTimeStamp(UIEvent *event)
+{
+#if TARGET_OS_SIMULATOR == 1
+ // We currently build Qt for simulator using X86_64, even on ARM based macs.
+ // This results in the simulator running on ARM, while the app is running
+ // inside it using Rosetta. And with this combination, the event.timestamp, which is
+ // documented to be in seconds, looks to be something else, and is not progressing
+ // in sync with a normal clock.
+ // Sending out mouse events with a timestamp that doesn't follow normal clock time
+ // will cause problems for mouse-, and pointer handlers that uses them to e.g calculate
+ // the time between a press and release, and to decide if the user is performing a tap
+ // or a drag.
+ // For that reason, we choose to ignore UIEvent.timestamp under the mentioned condition, and
+ // instead rely on NSProcessInfo. Note that if we force the whole simulator to use Rosetta
+ // (and not only the Qt app), the timestamps will progress normally.
+#if defined(Q_PROCESSOR_ARM)
+ #warning The timestamp work-around for x86_64 can (probably) be removed when building for ARM
+#endif
+ return ulong(NSProcessInfo.processInfo.systemUptime * 1000);
+#endif
+
+ return ulong(event.timestamp * 1000);
+}
+}
+
@implementation QUIView {
QHash<NSUInteger, QWindowSystemInterface::TouchPoint> m_activeTouches;
UITouch *m_activePencilTouch;
@@ -490,17 +516,17 @@ Q_LOGGING_CATEGORY(lcQpaInputEvents, "qt.qpa.input.events")
topLevel->requestActivateWindow();
}
- [self handleTouches:touches withEvent:event withState:QEventPoint::State::Pressed withTimestamp:ulong(event.timestamp * 1000)];
+ [self handleTouches:touches withEvent:event withState:QEventPoint::State::Pressed withTimestamp:getTimeStamp(event)];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
- [self handleTouches:touches withEvent:event withState:QEventPoint::State::Updated withTimestamp:ulong(event.timestamp * 1000)];
+ [self handleTouches:touches withEvent:event withState:QEventPoint::State::Updated withTimestamp:getTimeStamp(event)];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
- [self handleTouches:touches withEvent:event withState:QEventPoint::State::Released withTimestamp:ulong(event.timestamp * 1000)];
+ [self handleTouches:touches withEvent:event withState:QEventPoint::State::Released withTimestamp:getTimeStamp(event)];
// Remove ended touch points from the active set:
#ifndef Q_OS_TVOS
@@ -556,7 +582,7 @@ Q_LOGGING_CATEGORY(lcQpaInputEvents, "qt.qpa.input.events")
m_nextTouchId = 0;
m_activePencilTouch = nil;
- NSTimeInterval timestamp = event ? event.timestamp : [[NSProcessInfo processInfo] systemUptime];
+ ulong timestamp = event ? getTimeStamp(event) : ([[NSProcessInfo processInfo] systemUptime] * 1000);
QIOSIntegration *iosIntegration = static_cast<QIOSIntegration *>(QGuiApplicationPrivate::platformIntegration());
@@ -564,7 +590,7 @@ Q_LOGGING_CATEGORY(lcQpaInputEvents, "qt.qpa.input.events")
// 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());
+ self.platformWindow->window(), timestamp, iosIntegration->touchDevice());
}
- (int)mapPressTypeToKey:(UIPress*)press withModifiers:(Qt::KeyboardModifiers)qtModifiers text:(QString &)text