iOS: Add support for delivering touch pressure on iPhone 6s/6s+ devices

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ø <tor.arne.vestbo@theqtcompany.com>
This commit is contained in:
Tor Arne Vestbø 2015-10-19 14:11:28 +02:00
parent 9b28fd5bfc
commit 980f8aed32
2 changed files with 33 additions and 6 deletions

View File

@ -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();
}

View File

@ -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;
}
}
}
}