From 231a4a11011f9feb35b1eb41846f09d12b79e1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Fri, 26 Sep 2014 15:06:46 +0200 Subject: iOS: Move statusbar visibility handling to QIOSViewController It doesn't belong in QIOScreen, and simplifies the flow when changing the focus window or the window state of the focus window. Both will result in calling updateProperties on the view-controller, which will re-configure the statusbar visibility and hide/show it as appropriate, before triggering a re-layout of its own view, which will in turn trigger an update of the screen properties based on the new statusbar state, before re-layouting of QWindow based on the new screen state. Change-Id: I89077a3fb5f843949ce833e4e727d2c753ea2eb6 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosscreen.h | 3 -- src/plugins/platforms/ios/qiosscreen.mm | 40 ---------------- src/plugins/platforms/ios/qiosviewcontroller.h | 3 +- src/plugins/platforms/ios/qiosviewcontroller.mm | 62 ++++++++++++++++++++----- src/plugins/platforms/ios/qioswindow.mm | 3 +- src/plugins/platforms/ios/quiview.h | 9 +++- src/plugins/platforms/ios/quiview.mm | 10 ++++ 7 files changed, 71 insertions(+), 59 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h index 69fe17d9af..7987ef82d5 100644 --- a/src/plugins/platforms/ios/qiosscreen.h +++ b/src/plugins/platforms/ios/qiosscreen.h @@ -66,9 +66,6 @@ public: void updateProperties(); -public slots: - void updateStatusBarVisibility(); - private: UIScreen *m_uiScreen; UIWindow *m_uiWindow; diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index 266e6848e2..d8a49eace6 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -225,8 +225,6 @@ QIOSScreen::QIOSScreen(UIScreen *screen) } } - connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSScreen::updateStatusBarVisibility); - updateProperties(); } @@ -254,44 +252,6 @@ void QIOSScreen::updateProperties() } } -void QIOSScreen::updateStatusBarVisibility() -{ - if (!isQtApplication()) - return; - - 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(focusWindow->handle()->winId()); - QIOSViewController *viewController = static_cast(view.viewController); - - bool currentStatusBarVisibility = [UIApplication sharedApplication].statusBarHidden; - if (viewController.prefersStatusBarHidden == currentStatusBarVisibility) - return; - -#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0) - if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_7_0) { - [viewController setNeedsStatusBarAppearanceUpdate]; - dispatch_async(dispatch_get_main_queue(), ^{ - updateProperties(); - }); - } else -#endif - { - [[UIApplication sharedApplication] - setStatusBarHidden:[viewController prefersStatusBarHidden] - withAnimation:UIStatusBarAnimationNone]; - - updateProperties(); - } -} - QRect QIOSScreen::geometry() const { return m_geometry; diff --git a/src/plugins/platforms/ios/qiosviewcontroller.h b/src/plugins/platforms/ios/qiosviewcontroller.h index 2ef6400b26..cbb28aec0d 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.h +++ b/src/plugins/platforms/ios/qiosviewcontroller.h @@ -40,8 +40,9 @@ class QIOSScreen; } @property (nonatomic, assign) BOOL changingOrientation; +@property (nonatomic, assign) BOOL prefersStatusBarHidden; - (id)initWithQIOSScreen:(QIOSScreen *)screen; -- (BOOL)prefersStatusBarHidden; +- (void)updateProperties; @end diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index 1c06228e81..ca8d48bf6d 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -147,6 +147,13 @@ #endif self.changingOrientation = NO; + + // Status bar may be initially hidden at startup through Info.plist + self.prefersStatusBarHidden = infoPlistValue(@"UIStatusBarHidden", false); + + QObject::connect(qApp, &QGuiApplication::focusWindowChanged, [self]() { + [self updateProperties]; + }); } return self; @@ -173,6 +180,49 @@ [super viewDidUnload]; } +// ------------------------------------------------------------------------- + +- (void)updateProperties +{ + if (!isQtApplication()) + return; + + QWindow *focusWindow = QGuiApplication::focusWindow(); + + // If we don't have a focus window we leave the statusbar + // 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; + + // We only care about changes to focusWindow that involves our screen + if (!focusWindow->screen() || focusWindow->screen()->handle() != m_screen) + return; + + // All decisions are based on the the top level window + focusWindow = qt_window_private(focusWindow)->topLevelWindow(); + + bool currentStatusBarVisibility = self.prefersStatusBarHidden; + self.prefersStatusBarHidden = focusWindow->windowState() == Qt::WindowFullScreen; + if (self.prefersStatusBarHidden != currentStatusBarVisibility) { +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_7_0) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_7_0) { + [self setNeedsStatusBarAppearanceUpdate]; + } else +#endif + { + [[UIApplication sharedApplication] + setStatusBarHidden:self.prefersStatusBarHidden + withAnimation:UIStatusBarAnimationNone]; + } + + [self.view setNeedsLayout]; + } +} + +// ------------------------------------------------------------------------- + -(BOOL)shouldAutorotate { // Until a proper orientation and rotation API is in place, we always auto rotate. @@ -261,17 +311,5 @@ } #endif -- (BOOL)prefersStatusBarHidden -{ - static bool hiddenFromPlist = infoPlistValue(@"UIStatusBarHidden", false); - if (hiddenFromPlist) - return YES; - QWindow *focusWindow = QGuiApplication::focusWindow(); - if (!focusWindow) - return [UIApplication sharedApplication].statusBarHidden; - - return qt_window_private(focusWindow)->topLevelWindow()->windowState() == Qt::WindowFullScreen; -} - @end diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index 1c9fc6f28a..e29ff53876 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -119,7 +119,6 @@ void QIOSWindow::setVisible(bool visible) if (visible) { requestActivateWindow(); - static_cast(screen())->updateStatusBarVisibility(); } else { // Activate top-most visible QWindow: NSArray *subviews = m_view.viewController.view.subviews; @@ -202,7 +201,7 @@ void QIOSWindow::setWindowState(Qt::WindowState state) qt_window_private(window())->windowState = state; if (window()->isTopLevel() && window()->isVisible() && window()->isActive()) - static_cast(screen())->updateStatusBarVisibility(); + [m_view.qtViewController updateProperties]; switch (state) { case Qt::WindowNoState: diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h index a6a8690c2f..fe71e5bed7 100644 --- a/src/plugins/platforms/ios/quiview.h +++ b/src/plugins/platforms/ios/quiview.h @@ -40,6 +40,8 @@ class QIOSWindow; +@class QIOSViewController; + @interface QUIView : UIView { @public @@ -50,7 +52,7 @@ class QIOSWindow; @private NSMutableArray *m_accessibleElements; -} +}; - (id)initWithQIOSWindow:(QIOSWindow *)window; - (void)sendUpdatedExposeEvent; @@ -59,3 +61,8 @@ class QIOSWindow; @interface QUIView (Accessibility) - (void)clearAccessibleCache; @end + +@interface QUIView (QtHelpers) +- (QIOSViewController*)qtViewController; +@end + diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm index 4e720941f9..272441b41c 100644 --- a/src/plugins/platforms/ios/quiview.mm +++ b/src/plugins/platforms/ios/quiview.mm @@ -43,6 +43,7 @@ #include "qiosglobal.h" #include "qiosintegration.h" +#include "qiosviewcontroller.h" #include "qioswindow.h" #include "qiosmenu.h" @@ -368,6 +369,15 @@ return nil; } +- (QIOSViewController*)qtViewController +{ + UIViewController *vc = self.viewController; + if ([vc isKindOfClass:QIOSViewController.class]) + return static_cast(vc); + + return nil; +} + @end // Include category as an alternative to using -ObjC (Apple QA1490) -- cgit v1.2.3