diff options
-rw-r--r-- | src/plugins/platforms/ios/qiosapplicationdelegate.mm | 16 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosintegration.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosscreen.h | 7 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosscreen.mm | 29 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosviewcontroller.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosviewcontroller.mm | 25 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 33 |
8 files changed, 109 insertions, 6 deletions
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 775074baae..e325666f69 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -58,6 +58,22 @@ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; + QSysInfo::MacVersion iosVersion = QSysInfo::MacintoshVersion; + + // We prefer to keep the root viewcontroller in fullscreen layout, so that + // we don't have to compensate for the viewcontroller position. This also + // gives us the same behavior on iOS 5/6 as on iOS 7, where full screen layout + // is the only way. + if (iosVersion < QSysInfo::MV_IOS_7_0) + self.window.rootViewController.wantsFullScreenLayout = YES; + + // Use translucent statusbar by default on iOS6 (unless the user changed the + // default in the Info.plist), so that windows placed under the stausbar are + // still visible, just like on iOS7. + if (iosVersion >= QSysInfo::MV_IOS_6_0 && iosVersion < QSysInfo::MV_IOS_7_0 + && [UIApplication sharedApplication].statusBarStyle == UIStatusBarStyleDefault) + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent]; + self.window.hidden = NO; return YES; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 44ac749454..5c8f67bda2 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -160,7 +160,7 @@ QPlatformServices *QIOSIntegration::services() const QVariant QIOSIntegration::styleHint(StyleHint hint) const { switch (hint) { - case ShowIsFullScreen: + case ShowIsMaximized: return true; case SetFocusOnTouchRelease: return true; diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 9de62c5646..173bd11719 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -50,8 +50,10 @@ QT_BEGIN_NAMESPACE -class QIOSScreen : public QPlatformScreen +class QIOSScreen : public QObject, public QPlatformScreen { + Q_OBJECT + public: QIOSScreen(unsigned int screenIndex); ~QIOSScreen(); @@ -75,6 +77,9 @@ public: void updateProperties(); void layoutWindows(); +public slots: + void updateStatusBarVisibility(); + private: UIScreen *m_uiScreen; QRect m_geometry; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 3c054b4b04..42c3e13e7e 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -139,6 +139,8 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) m_unscaledDpi = 163; // Regular iPhone DPI } + connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSScreen::updateStatusBarVisibility); + updateProperties(); } @@ -185,6 +187,31 @@ void QIOSScreen::updateProperties() layoutWindows(); } +void QIOSScreen::updateStatusBarVisibility() +{ + QWindow *focusWindow = QGuiApplication::focusWindow(); + + // If we don't have a focus window we leave the status + // bar as is, so that the user can activate a new window + // with the same window state without the status bar jumping + // back and forth. + if (!focusWindow) + return; + + UIView *view = reinterpret_cast<UIView *>(focusWindow->handle()->winId()); +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_7_0) { + [view.viewController setNeedsStatusBarAppearanceUpdate]; + } else +#endif + { + QIOSViewController *viewController = static_cast<QIOSViewController *>(view.viewController); + [[UIApplication sharedApplication] + setStatusBarHidden:[viewController prefersStatusBarHidden] + withAnimation:UIStatusBarAnimationNone]; + } +} + void QIOSScreen::layoutWindows() { QList<QWindow*> windows = QGuiApplication::topLevelWindows(); @@ -273,4 +300,6 @@ UIScreen *QIOSScreen::uiScreen() const return m_uiScreen; } +#include "moc_qiosscreen.cpp" + QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index d5a61cb3f4..a0017808d3 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -42,5 +42,6 @@ #import <UIKit/UIKit.h> @interface QIOSViewController : UIViewController +- (BOOL)prefersStatusBarHidden; @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 1d5e69beac..11ac92fea5 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -42,9 +42,11 @@ #import "qiosviewcontroller.h" #include <QtGui/QGuiApplication> +#include <QtGui/QWindow> #include <QtGui/QScreen> #include "qiosscreen.h" #include "qiosglobal.h" +#include "qioswindow.h" @implementation QIOSViewController @@ -74,5 +76,28 @@ qiosScreen->updateProperties(); } +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0) +- (UIStatusBarStyle)preferredStatusBarStyle +{ + // Since we don't place anything behind the status bare by default, we + // end up with a black area, so we have to enable the white text mode + // of the iOS7 statusbar. + return UIStatusBarStyleLightContent; + + // FIXME: Try to detect the content underneath the statusbar and choose + // an appropriate style, and/or expose Qt APIs to control the style. +} +#endif + +- (BOOL)prefersStatusBarHidden +{ + QWindow *focusWindow = QGuiApplication::focusWindow(); + if (!focusWindow) + return [UIApplication sharedApplication].statusBarHidden; + + QIOSWindow *topLevel = static_cast<QIOSWindow *>(focusWindow->handle())->topLevelWindow(); + return topLevel->window()->windowState() == Qt::WindowFullScreen; +} + @end diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h index 4ebdd4635c..a5e122bda1 100644 --- a/src/plugins/platforms/ios/qioswindow.h +++ b/src/plugins/platforms/ios/qioswindow.h @@ -85,6 +85,8 @@ public: WId winId() const { return WId(m_view); }; + QIOSWindow *topLevelWindow() const; + private: void applyGeometry(const QRect &rect); diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index e835b829a8..d4e656c390 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -456,6 +456,10 @@ void QIOSWindow::setVisible(bool visible) if (visible) { requestActivateWindow(); + + if (window()->isTopLevel()) + static_cast<QIOSScreen *>(screen())->updateStatusBarVisibility(); + } else { // Activate top-most visible QWindow: NSArray *subviews = m_view.viewController.view.subviews; @@ -530,10 +534,6 @@ void QIOSWindow::applyGeometry(const QRect &rect) void QIOSWindow::setWindowState(Qt::WindowState state) { - // FIXME: Figure out where or how we should disable/enable the statusbar. - // Perhaps setting QWindow to maximized should also mean that we'll show - // the statusbar, and vice versa for fullscreen? - switch (state) { case Qt::WindowNoState: applyGeometry(m_normalGeometry); @@ -552,6 +552,14 @@ void QIOSWindow::setWindowState(Qt::WindowState state) default: Q_UNREACHABLE(); } + + if (window()->isTopLevel() && window()->isVisible() && window()->isActive()) { + // The window state of the QWindow is not updated until after + // we return from this method, so we have to defer any updates + // of the statusbar that depend on the current window state. + QMetaObject::invokeMethod(static_cast<QIOSScreen *>(screen()), + "updateStatusBarVisibility", Qt::QueuedConnection); + } } void QIOSWindow::setParent(const QPlatformWindow *parentWindow) @@ -569,6 +577,23 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow) } } +QIOSWindow *QIOSWindow::topLevelWindow() const +{ + QWindow *window = this->window(); + while (window) { + QWindow *parent = window->parent(); + if (!parent) + parent = window->transientParent(); + + if (!parent) + break; + + window = parent; + } + + return static_cast<QIOSWindow *>(window->handle()); +} + void QIOSWindow::requestActivateWindow() { // Note that several windows can be active at the same time if they exist in the same |