From e0e1c7ec2da121fa2b3acc8e76eb96e959954608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 16 Apr 2018 15:32:30 +0200 Subject: iOS: Trigger manual layout of root view controller when coming out of background When rotating the device when the application is in the background iOS will ask the root view controller to layout its views when then foregrounding the application, but at that point the application state is still in the suspended state, meaning we block any view resizing or rendering. To ensure the views are resized correctly, we trigger a manual layout after the application comes out of the suspended state. Task-number: QTBUG-67719 Change-Id: I1ef0a4133d4b94edaac7b0f3cb4e49e367eb76d4 Reviewed-by: Richard Moe Gustavsen --- src/plugins/platforms/ios/qiosapplicationstate.h | 4 +- src/plugins/platforms/ios/qiosapplicationstate.mm | 16 ++++---- src/plugins/platforms/ios/qioscontext.mm | 47 +++++++++++++---------- src/plugins/platforms/ios/qiosintegration.h | 2 + src/plugins/platforms/ios/qiosintegration.mm | 3 ++ src/plugins/platforms/ios/qiosviewcontroller.mm | 14 +++++++ 6 files changed, 55 insertions(+), 31 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosapplicationstate.h b/src/plugins/platforms/ios/qiosapplicationstate.h index a68147a72a..8a15a4a51b 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.h +++ b/src/plugins/platforms/ios/qiosapplicationstate.h @@ -56,8 +56,8 @@ public: static Qt::ApplicationState toQtApplicationState(UIApplicationState state); Q_SIGNALS: - void applicationStateWillChange(Qt::ApplicationState); - void applicationStateDidChange(Qt::ApplicationState); + void applicationStateWillChange(Qt::ApplicationState oldState, Qt::ApplicationState newState); + void applicationStateDidChange(Qt::ApplicationState oldState, Qt::ApplicationState newState); }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/ios/qiosapplicationstate.mm b/src/plugins/platforms/ios/qiosapplicationstate.mm index 3407aebf8f..6d9bcdacbf 100644 --- a/src/plugins/platforms/ios/qiosapplicationstate.mm +++ b/src/plugins/platforms/ios/qiosapplicationstate.mm @@ -87,18 +87,18 @@ QIOSApplicationState::QIOSApplicationState() void QIOSApplicationState::handleApplicationStateChanged(UIApplicationState uiState, const QString &reason) { - Qt::ApplicationState state = toQtApplicationState(uiState); - qCDebug(lcQpaApplication) << qPrintable(reason) - << "- moving from" << QGuiApplication::applicationState() << "to" << state; + Qt::ApplicationState oldState = QGuiApplication::applicationState(); + Qt::ApplicationState newState = toQtApplicationState(uiState); + qCDebug(lcQpaApplication) << qPrintable(reason) << "- moving from" << oldState << "to" << newState; if (QIOSIntegration *integration = QIOSIntegration::instance()) { - emit integration->applicationState.applicationStateWillChange(state); - QWindowSystemInterface::handleApplicationStateChanged(state); - emit integration->applicationState.applicationStateDidChange(state); - qCDebug(lcQpaApplication) << "done moving to" << state; + emit integration->applicationState.applicationStateWillChange(oldState, newState); + QWindowSystemInterface::handleApplicationStateChanged(newState); + emit integration->applicationState.applicationStateDidChange(oldState, newState); + qCDebug(lcQpaApplication) << "done moving to" << newState; } else { qCDebug(lcQpaApplication) << "no platform integration yet, setting state directly"; - QGuiApplicationPrivate::applicationState = state; + QGuiApplicationPrivate::applicationState = newState; } } diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm index 03643c19a9..fff66049ff 100644 --- a/src/plugins/platforms/ios/qioscontext.mm +++ b/src/plugins/platforms/ios/qioscontext.mm @@ -301,29 +301,34 @@ bool QIOSContext::verifyGraphicsHardwareAvailability() static dispatch_once_t onceToken = 0; dispatch_once(&onceToken, ^{ QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState; - connect(applicationState, &QIOSApplicationState::applicationStateWillChange, [](Qt::ApplicationState state) { - if (applicationBackgrounded && state != Qt::ApplicationSuspended) { - qCDebug(lcQpaGLContext) << "app no longer backgrounded, rendering enabled"; - applicationBackgrounded = false; + connect(applicationState, &QIOSApplicationState::applicationStateWillChange, + [](Qt::ApplicationState oldState, Qt::ApplicationState newState) { + Q_UNUSED(oldState); + if (applicationBackgrounded && newState != Qt::ApplicationSuspended) { + qCDebug(lcQpaGLContext) << "app no longer backgrounded, rendering enabled"; + applicationBackgrounded = true; + } } - }); - connect(applicationState, &QIOSApplicationState::applicationStateDidChange, [](Qt::ApplicationState state) { - if (state != Qt::ApplicationSuspended) - return; - - qCDebug(lcQpaGLContext) << "app backgrounded, rendering disabled"; - applicationBackgrounded = true; - - // By the time we receive this signal the application has moved into - // Qt::ApplactionStateSuspended, and all windows have been obscured, - // which should stop all rendering. If there's still an active GL context, - // we follow Apple's advice and call glFinish before making it inactive. - if (QOpenGLContext *currentContext = QOpenGLContext::currentContext()) { - qCWarning(lcQpaGLContext) << "explicitly glFinishing and deactivating" << currentContext; - glFinish(); - currentContext->doneCurrent(); + ); + connect(applicationState, &QIOSApplicationState::applicationStateDidChange, + [](Qt::ApplicationState oldState, Qt::ApplicationState newState) { + Q_UNUSED(oldState); + if (newState != Qt::ApplicationSuspended) + return; + + qCDebug(lcQpaGLContext) << "app backgrounded, rendering disabled"; + + // By the time we receive this signal the application has moved into + // Qt::ApplactionStateSuspended, and all windows have been obscured, + // which should stop all rendering. If there's still an active GL context, + // we follow Apple's advice and call glFinish before making it inactive. + if (QOpenGLContext *currentContext = QOpenGLContext::currentContext()) { + qCWarning(lcQpaGLContext) << "explicitly glFinishing and deactivating" << currentContext; + glFinish(); + currentContext->doneCurrent(); + } } - }); + ); }); if (applicationBackgrounded) { diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h index 6be8855020..818250fcee 100644 --- a/src/plugins/platforms/ios/qiosintegration.h +++ b/src/plugins/platforms/ios/qiosintegration.h @@ -62,6 +62,8 @@ public: QIOSIntegration(); ~QIOSIntegration(); + void initialize() override; + bool hasCapability(Capability cap) const override; QPlatformWindow *createPlatformWindow(QWindow *window) const override; diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 92c1e39d72..2e657b3798 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -95,7 +95,10 @@ QIOSIntegration::QIOSIntegration() // Set current directory to app bundle folder QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String])); +} +void QIOSIntegration::initialize() +{ UIScreen *mainScreen = [UIScreen mainScreen]; NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease]; if (![screens containsObject:mainScreen]) { diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm index a7663b9e94..d7db6ba856 100644 --- a/src/plugins/platforms/ios/qiosviewcontroller.mm +++ b/src/plugins/platforms/ios/qiosviewcontroller.mm @@ -273,6 +273,20 @@ m_focusWindowChangeConnection = QObject::connect(qApp, &QGuiApplication::focusWindowChanged, [self]() { [self updateProperties]; }); + + QIOSApplicationState *applicationState = &QIOSIntegration::instance()->applicationState; + QObject::connect(applicationState, &QIOSApplicationState::applicationStateDidChange, + [self](Qt::ApplicationState oldState, Qt::ApplicationState newState) { + if (oldState == Qt::ApplicationSuspended && newState != Qt::ApplicationSuspended) { + // We may have ignored an earlier layout because the application was suspended, + // and we didn't want to render anything at that moment in fear of being killed + // due to rendering in the background, so we trigger an explicit layout when + // coming out of the suspended state. + qCDebug(lcQpaWindow) << "triggering root VC layout when coming out of suspended state"; + [self.view setNeedsLayout]; + } + } + ); } return self; -- cgit v1.2.3 From 34e34f22097c87e8e937d72117d83d8c572bbea4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 18 Apr 2018 15:37:58 +0200 Subject: iOS: Use the non deprecated application:openURL function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In iOS 9.0, the original application:openURL function was deprecated and replaced with a newer one. As iOS 9.0 is no longer supported we can safely switch to the new one. This is also required to prevent a crash when the LSSupportsOpeningDocumentsInPlace and UIFileSharingEnabled keys are set to true in the Info.plist file. Change-Id: I59a7ee82e3ddb2777ef78e28b964ef8666c629af Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosapplicationdelegate.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/ios') diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 9cdbed303c..a56c1e4568 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -50,11 +50,10 @@ @implementation QIOSApplicationDelegate -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { Q_UNUSED(application); - Q_UNUSED(sourceApplication); - Q_UNUSED(annotation); + Q_UNUSED(options); if (!QGuiApplication::instance()) return NO; -- cgit v1.2.3