summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@digia.com>2013-11-21 11:25:48 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-22 22:36:34 +0100
commitf441d8e52360fe5c03887fa0bbce8bfda2c8ff2d (patch)
tree765ec2cd47d947962fddb7a2a88085070c3704f4 /src/plugins/platforms
parentae5392a00bdd5a569250cd4e387868141cbd68e9 (diff)
iOS: Change show() to imply maximize, and showFullScreen() to hide status bar
Matches the Android behavior, and gives an easy and predictable way to show true fullscreen windows that is similar to how one would do it on a desktop platform. We keep the statusbar visibility in sync with the window state of the active window. Change-Id: Ia4b99e03f83e19f9ef56cc99b9d477cc6da4c734 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/ios/qiosapplicationdelegate.mm16
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm2
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h7
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm29
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.h1
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm25
-rw-r--r--src/plugins/platforms/ios/qioswindow.h2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm33
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