From 980f8aed32403527e2922c2c671bbe29a6911c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 19 Oct 2015 14:11:28 +0200 Subject: iOS: Add support for delivering touch pressure on iPhone 6s/6s+ devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As 3D touch can be disabled/enabled at runtime on those devices, we need to watch for changes to the relevant settings and update the touch device capabilities that we report to the user. Note that iOS will deliver touchesBegan with a touch force of 0, which we will reflect/propagate as a 0 pressure, but there is no clear alternative, as we don't want to wait for a touchedMoved before sending a touch press event to Qt, just to have a valid pressure. Change-Id: I47fb8a9f98ab3244e16a337bbfcf1fe24e4c7aa2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 10 +++++++--- src/plugins/platforms/ios/quiview.mm | 29 +++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index eaff0daf19..0e3da8dce8 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -89,10 +89,11 @@ QIOSIntegration::QIOSIntegration() // Set current directory to app bundle folder QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String])); + UIScreen *mainScreen = [UIScreen mainScreen]; NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease]; - if (![screens containsObject:[UIScreen mainScreen]]) { + if (![screens containsObject:mainScreen]) { // Fallback for iOS 7.1 (QTBUG-42345) - [screens insertObject:[UIScreen mainScreen] atIndex:0]; + [screens insertObject:mainScreen atIndex:0]; } for (UIScreen *screen in screens) @@ -103,7 +104,10 @@ QIOSIntegration::QIOSIntegration() m_touchDevice = new QTouchDevice; m_touchDevice->setType(QTouchDevice::TouchScreen); - m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition; + if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) + touchCapabilities |= QTouchDevice::Pressure; + m_touchDevice->setCapabilities(touchCapabilities); QWindowSystemInterface::registerTouchDevice(m_touchDevice); QMacInternalPasteboardMime::initializeMimeTypes(); } diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index c6ef843b9f..53b3d30327 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -280,6 +280,19 @@ // ------------------------------------------------------------------------- +- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection +{ + [super traitCollectionDidChange: previousTraitCollection]; + + QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice(); + QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities(); + if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) + touchCapabilities |= QTouchDevice::Pressure; + else + touchCapabilities &= ~QTouchDevice::Pressure; + touchDevice->setCapabilities(touchCapabilities); +} + -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput) @@ -289,6 +302,8 @@ - (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state { + bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure; + foreach (UITouch *uiTouch, m_activeTouches.keys()) { QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch]; if (![touches containsObject:uiTouch]) { @@ -309,9 +324,17 @@ touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(), globalScreenPosition.y() / screenSize.height()); - // We don't claim that our touch device supports QTouchDevice::Pressure, - // but fill in a meaningfull value in case clients use it anyways. - touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; + if (supportsPressure) { + // Note: iOS will deliver touchesBegan with a touch force of 0, which + // we will reflect/propagate as a 0 pressure, but there is no clear + // alternative, as we don't want to wait for a touchedMoved before + // sending a touch press event to Qt, just to have a valid pressure. + touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce; + } else { + // We don't claim that our touch device supports QTouchDevice::Pressure, + // but fill in a meaningfull value in case clients use it anyways. + touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0; + } } } } -- cgit v1.2.3