summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/ios/qiosscreen.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/ios/qiosscreen.mm')
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm158
1 files changed, 120 insertions, 38 deletions
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 5331d05ae9..eb3b7e3c44 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qiosglobal.h"
+#include "qiosintegration.h"
#include "qiosscreen.h"
#include "qioswindow.h"
#include <qpa/qwindowsysteminterface.h>
@@ -48,6 +49,63 @@
#include <sys/sysctl.h>
+// -------------------------------------------------------------------------
+
+static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
+{
+ foreach (QScreen *screen, QGuiApplication::screens()) {
+ QIOSScreen *platformScreen = static_cast<QIOSScreen *>(screen->handle());
+ if (platformScreen->uiScreen() == uiScreen)
+ return platformScreen;
+ }
+
+ return 0;
+}
+
+@interface QIOSScreenTracker : NSObject
+@end
+
+@implementation QIOSScreenTracker
+
++ (void)load
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserver:self selector:@selector(screenConnected:)
+ name:UIScreenDidConnectNotification object:nil];
+ [center addObserver:self selector:@selector(screenDisconnected:)
+ name:UIScreenDidDisconnectNotification object:nil];
+ [center addObserver:self selector:@selector(screenModeChanged:)
+ name:UIScreenModeDidChangeNotification object:nil];
+}
+
++ (void)screenConnected:(NSNotification*)notification
+{
+ QIOSIntegration *integration = QIOSIntegration::instance();
+ Q_ASSERT_X(integration, Q_FUNC_INFO, "Screen connected before QIOSIntegration creation");
+
+ integration->addScreen(new QIOSScreen([notification object]));
+}
+
++ (void)screenDisconnected:(NSNotification*)notification
+{
+ QIOSScreen *screen = qtPlatformScreenFor([notification object]);
+ Q_ASSERT_X(screen, Q_FUNC_INFO, "Screen disconnected that we didn't know about");
+
+ delete screen;
+}
+
++ (void)screenModeChanged:(NSNotification*)notification
+{
+ QIOSScreen *screen = qtPlatformScreenFor([notification object]);
+ Q_ASSERT_X(screen, Q_FUNC_INFO, "Screen changed that we didn't know about");
+
+ screen->updateProperties();
+}
+
+@end
+
+// -------------------------------------------------------------------------
+
@interface QIOSOrientationListener : NSObject {
@public
QIOSScreen *m_screen;
@@ -99,6 +157,8 @@
@end
+// -------------------------------------------------------------------------
+
/*!
Returns the model identifier of the device.
@@ -118,27 +178,51 @@ static QString deviceModelIdentifier()
return QString::fromLatin1(value);
}
-QIOSScreen::QIOSScreen(unsigned int screenIndex)
+QIOSScreen::QIOSScreen(UIScreen *screen)
: QPlatformScreen()
- , m_uiScreen([[UIScreen screens] count] > screenIndex
- ? [[UIScreen screens] objectAtIndex:screenIndex]
- : [UIScreen mainScreen])
+ , m_uiScreen(screen)
+ , m_uiWindow(0)
, m_orientationListener(0)
{
- QString deviceIdentifier = deviceModelIdentifier();
-
- if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */
- || deviceIdentifier == QStringLiteral("iPod3,1") /* iPod touch 3G */) {
- m_depth = 18;
+ if (screen == [UIScreen mainScreen]) {
+ QString deviceIdentifier = deviceModelIdentifier();
+
+ if (deviceIdentifier == QStringLiteral("iPhone2,1") /* iPhone 3GS */
+ || deviceIdentifier == QStringLiteral("iPod3,1") /* iPod touch 3G */) {
+ m_depth = 18;
+ } else {
+ m_depth = 24;
+ }
+
+ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
+ && !deviceIdentifier.contains(QRegularExpression("^iPad2,[567]$")) /* excluding iPad Mini */) {
+ m_unscaledDpi = 132;
+ } else {
+ m_unscaledDpi = 163; // Regular iPhone DPI
+ }
} else {
+ // External display, hard to say
m_depth = 24;
+ m_unscaledDpi = 96;
}
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
- && !deviceIdentifier.contains(QRegularExpression("^iPad2,[567]$")) /* excluding iPad Mini */) {
- m_unscaledDpi = 132;
- } else {
- m_unscaledDpi = 163; // Regular iPhone DPI
+ for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) {
+ if (existingWindow.screen == m_uiScreen) {
+ m_uiWindow = [m_uiWindow retain];
+ break;
+ }
+ }
+
+ if (!m_uiWindow) {
+ // Create a window and associated view-controller that we can use
+ m_uiWindow = [[UIWindow alloc] initWithFrame:[m_uiScreen bounds]];
+ m_uiWindow.rootViewController = [[[QIOSViewController alloc] initWithQIOSScreen:this] autorelease];
+
+ // FIXME: Only do once windows are added to the screen, and for any screen
+ if (screen == [UIScreen mainScreen]) {
+ m_uiWindow.screen = m_uiScreen;
+ m_uiWindow.hidden = NO;
+ }
}
connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSScreen::updateStatusBarVisibility);
@@ -149,40 +233,31 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex)
QIOSScreen::~QIOSScreen()
{
[m_orientationListener release];
+ [m_uiWindow release];
}
void QIOSScreen::updateProperties()
{
- UIWindow *uiWindow = 0;
- for (uiWindow in [[UIApplication sharedApplication] windows]) {
- if (uiWindow.screen == m_uiScreen)
- break;
- }
+ QRect previousGeometry = m_geometry;
+ QRect previousAvailableGeometry = m_availableGeometry;
- bool inPortrait = UIInterfaceOrientationIsPortrait(uiWindow.rootViewController.interfaceOrientation);
- QRect geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect()
+ bool inPortrait = UIInterfaceOrientationIsPortrait(m_uiWindow.rootViewController.interfaceOrientation);
+ m_geometry = inPortrait ? fromCGRect(m_uiScreen.bounds).toRect()
: QRect(m_uiScreen.bounds.origin.x, m_uiScreen.bounds.origin.y,
m_uiScreen.bounds.size.height, m_uiScreen.bounds.size.width);
- if (geometry != m_geometry) {
- m_geometry = geometry;
-
- const qreal millimetersPerInch = 25.4;
- m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch;
-
- QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry);
- }
-
- QRect availableGeometry = geometry;
+ m_availableGeometry = m_geometry;
CGSize applicationFrameSize = m_uiScreen.applicationFrame.size;
- int statusBarHeight = geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width);
+ int statusBarHeight = m_geometry.height() - (inPortrait ? applicationFrameSize.height : applicationFrameSize.width);
- availableGeometry.adjust(0, statusBarHeight, 0, 0);
+ m_availableGeometry.adjust(0, statusBarHeight, 0, 0);
- if (availableGeometry != m_availableGeometry) {
- m_availableGeometry = availableGeometry;
- QWindowSystemInterface::handleScreenAvailableGeometryChange(screen(), m_availableGeometry);
+ if (m_geometry != previousGeometry || m_availableGeometry != previousAvailableGeometry) {
+ const qreal millimetersPerInch = 25.4;
+ m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch;
+
+ QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry, m_availableGeometry);
}
if (screen())
@@ -294,8 +369,15 @@ qreal QIOSScreen::devicePixelRatio() const
Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
{
- // A UIScreen stays in the native orientation, regardless of rotation
- return m_uiScreen.bounds.size.width >= m_uiScreen.bounds.size.height ?
+ CGRect nativeBounds =
+#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_8_0)
+ QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0 ? m_uiScreen.nativeBounds :
+#endif
+ m_uiScreen.bounds;
+
+ // All known iOS devices have a native orientation of portrait, but to
+ // be on the safe side we compare the width and height of the bounds.
+ return nativeBounds.size.width >= nativeBounds.size.height ?
Qt::LandscapeOrientation : Qt::PortraitOrientation;
}