summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorMike Krus <mike.krus@kdab.com>2020-05-22 15:38:24 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2020-06-29 20:45:42 +0000
commit4bb45126492152db9306c809391e3df0d43057a2 (patch)
tree1c2698bfc886e5bd6add403577931b232069db97 /src/plugins
parent122a9512fc2e22ace1caf897d9b99ae5a26e9907 (diff)
Fix UITouch event handling on tvOS
On tvOS touchesEnded: occasionally gets called with touches that have not been passed via the touchesBegan:. When this happens previously cached touch event (that HAVE been passed to touchesBegan:) are no longer valid. This causes a crash when testing if new touches contain old ones (since NSSet dereferences the needle which is no longer valid). Fix uses the unique (unsigned int) hash that UIKIT assigns to the UITouch instance so cached copies are never accessed. Furthermore, tvOS only supports single touch so now just clearing cache when touch has ended. Task-number: QTBUG-84383 Change-Id: I7592cdde74ce834285e7b14196171f6b57736cc8 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit 428115340bee4357d6821eee78e1fff0ae910712) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/ios/quiview.mm32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 91a186bace..dca113abdd 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -56,7 +56,7 @@
Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
@implementation QUIView {
- QHash<UITouch *, QWindowSystemInterface::TouchPoint> m_activeTouches;
+ QHash<NSUInteger, QWindowSystemInterface::TouchPoint> m_activeTouches;
UITouch *m_activePencilTouch;
int m_nextTouchId;
NSMutableArray<UIAccessibilityElement *> *m_accessibleElements;
@@ -403,9 +403,19 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
#endif
- for (UITouch *uiTouch : m_activeTouches.keys()) {
- QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch];
- if (![touches containsObject:uiTouch]) {
+ if (m_activeTouches.isEmpty())
+ return;
+ for (auto it = m_activeTouches.begin(); it != m_activeTouches.end(); ++it) {
+ auto hash = it.key();
+ QWindowSystemInterface::TouchPoint &touchPoint = it.value();
+ UITouch *uiTouch = nil;
+ for (UITouch *touch in touches) {
+ if (touch.hash == hash) {
+ uiTouch = touch;
+ break;
+ }
+ }
+ if (!uiTouch) {
touchPoint.state = Qt::TouchPointStationary;
} else {
touchPoint.state = state;
@@ -437,8 +447,6 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
}
}
- if (m_activeTouches.isEmpty())
- return;
if ([self.window isKindOfClass:[QUIWindow class]] &&
!static_cast<QUIWindow *>(self.window).sendingEvent) {
@@ -474,9 +482,9 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
m_activePencilTouch = touch;
} else
{
- Q_ASSERT(!m_activeTouches.contains(touch));
+ Q_ASSERT(!m_activeTouches.contains(touch.hash));
#endif
- m_activeTouches[touch].id = m_nextTouchId++;
+ m_activeTouches[touch.hash].id = m_nextTouchId++;
#if QT_CONFIG(tabletevent)
}
#endif
@@ -503,6 +511,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
[self handleTouches:touches withEvent:event withState:Qt::TouchPointReleased withTimestamp:ulong(event.timestamp * 1000)];
// Remove ended touch points from the active set:
+#ifndef Q_OS_TVOS
for (UITouch *touch in touches) {
#if QT_CONFIG(tabletevent)
if (touch.type == UITouchTypeStylus) {
@@ -510,9 +519,14 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
} else
#endif
{
- m_activeTouches.remove(touch);
+ m_activeTouches.remove(touch.hash);
}
}
+#else
+ // tvOS only supports single touch
+ m_activeTouches.clear();
+#endif
+
if (m_activeTouches.isEmpty() && !m_activePencilTouch)
m_nextTouchId = 0;
}