diff options
Diffstat (limited to 'src/plugins/platforms/ios/quiview.mm')
-rw-r--r-- | src/plugins/platforms/ios/quiview.mm | 82 |
1 files changed, 76 insertions, 6 deletions
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 9c7acc9278..5c493617b1 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -44,10 +44,13 @@ #include "qiosviewcontroller.h" #include "qiostextresponder.h" #include "qioswindow.h" +#ifndef Q_OS_TVOS #include "qiosmenu.h" +#endif #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qwindow_p.h> +#include <qpa/qwindowsysteminterface_p.h> @implementation QUIView @@ -56,9 +59,9 @@ return [CAEAGLLayer class]; } -- (id)initWithQIOSWindow:(QIOSWindow *)window +- (id)initWithQIOSWindow:(QT_PREPEND_NAMESPACE(QIOSWindow) *)window { - if (self = [self initWithFrame:toCGRect(window->geometry())]) + if (self = [self initWithFrame:window->geometry().toCGRect()]) m_qioswindow = window; m_accessibleElements = [[NSMutableArray alloc] init]; @@ -78,7 +81,9 @@ if (isQtApplication()) self.hidden = YES; +#ifndef Q_OS_TVOS self.multipleTouchEnabled = YES; +#endif if (QIOSIntegration::instance()->debugWindowManagement()) { static CGFloat hue = 0.0; @@ -149,7 +154,7 @@ // from what we end up with after applying window constraints. QRect requestedGeometry = m_qioswindow->geometry(); - QRect actualGeometry = fromCGRect(self.frame).toRect(); + QRect actualGeometry = QRectF::fromCGRect(self.frame).toRect(); // Persist the actual/new geometry so that QWindow::geometry() can // be queried on the resize event. @@ -184,7 +189,7 @@ QRegion region; if (m_qioswindow->isExposed()) { - QSize bounds = fromCGRect(self.layer.bounds).toRect().size(); + QSize bounds = QRectF::fromCGRect(self.layer.bounds).toRect().size(); Q_ASSERT(m_qioswindow->geometry().size() == bounds); Q_ASSERT(self.hidden == !m_qioswindow->window()->isVisible()); @@ -324,7 +329,8 @@ // Touch positions are expected to be in QScreen global coordinates, and // as we already have the QWindow positioned at the right place, we can // just map from the local view position to global coordinates. - QPoint localViewPosition = fromCGPoint([uiTouch locationInView:self]).toPoint(); + // tvOS: all touches start at the center of the screen and move from there. + QPoint localViewPosition = QPointF::fromCGPoint([uiTouch locationInView:self]).toPoint(); QPoint globalScreenPosition = m_qioswindow->mapToGlobal(localViewPosition); touchPoint.area = QRectF(globalScreenPosition, QSize(0, 0)); @@ -438,16 +444,78 @@ QWindowSystemInterface::flushWindowSystemEvents(); } +- (int)mapPressTypeToKey:(UIPress*)press +{ + switch (press.type) { + case UIPressTypeUpArrow: return Qt::Key_Up; + case UIPressTypeDownArrow: return Qt::Key_Down; + case UIPressTypeLeftArrow: return Qt::Key_Left; + case UIPressTypeRightArrow: return Qt::Key_Right; + case UIPressTypeSelect: return Qt::Key_Select; + case UIPressTypeMenu: return Qt::Key_Menu; + case UIPressTypePlayPause: return Qt::Key_MediaTogglePlayPause; + } + return Qt::Key_unknown; +} + +- (bool)processPresses:(NSSet *)presses withType:(QEvent::Type)type { + // Presses on Menu button will generate a Menu key event. By default, not handling + // this event will cause the application to return to Headboard (tvOS launcher). + // When handling the event (for example, as a back button), both press and + // release events must be handled accordingly. + + QScopedValueRollback<bool> syncRollback(QWindowSystemInterfacePrivate::synchronousWindowSystemEvents, true); + + bool handled = false; + for (UIPress* press in presses) { + int key = [self mapPressTypeToKey:press]; + if (key == Qt::Key_unknown) + continue; + if (QWindowSystemInterface::handleKeyEvent(m_qioswindow->window(), type, key, Qt::NoModifier)) + handled = true; + } + + return handled; +} + +- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event +{ + if (![self processPresses:presses withType:QEvent::KeyPress]) + [super pressesBegan:presses withEvent:event]; +} + +- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event +{ + if (![self processPresses:presses withType:QEvent::KeyPress]) + [super pressesChanged:presses withEvent:event]; +} + +- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event +{ + if (![self processPresses:presses withType:QEvent::KeyRelease]) + [super pressesEnded:presses withEvent:event]; +} + - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { +#ifndef Q_OS_TVOS // Check first if QIOSMenu should handle the action before continuing up the responder chain return [QIOSMenu::menuActionTarget() targetForAction:action withSender:sender] != 0; +#else + Q_UNUSED(action) + Q_UNUSED(sender) + return false; +#endif } - (id)forwardingTargetForSelector:(SEL)selector { Q_UNUSED(selector) +#ifndef Q_OS_TVOS return QIOSMenu::menuActionTarget(); +#else + return nil; +#endif } @end @@ -457,7 +525,7 @@ - (QWindow *)qwindow { if ([self isKindOfClass:[QUIView class]]) { - if (QIOSWindow *w = static_cast<QUIView *>(self)->m_qioswindow) + if (QT_PREPEND_NAMESPACE(QIOSWindow) *w = static_cast<QUIView *>(self)->m_qioswindow) return w->window(); } return nil; @@ -484,5 +552,7 @@ @end +#ifndef QT_NO_ACCESSIBILITY // Include category as an alternative to using -ObjC (Apple QA1490) #include "quiview_accessibility.mm" +#endif |