From 5ea3845bd0bf4dec9828270ab18e7c94d596975e Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 15 Apr 2013 15:15:36 +0200 Subject: [PATCH] iOS: use an explicit pointer to qiosViewController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it stood, we always relied on the root view controller being a QIOSViewController if isQtApplication() returned true. For mixed application, this might not always be true as native code can choose to replace the root view controller at times, or even rip it out, and place it as a child of another (e.g UISplitViewController). This change will give an extra protection against that. Change-Id: I0cb85796a8b82f9037c32f9e85e04e1dc7aad8e2 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosapplicationdelegate.h | 3 +++ src/plugins/platforms/ios/qiosapplicationdelegate.mm | 2 ++ src/plugins/platforms/ios/qiosglobal.h | 2 +- src/plugins/platforms/ios/qiosglobal.mm | 8 ++++++-- src/plugins/platforms/ios/qiosscreen.mm | 2 +- src/plugins/platforms/ios/qioswindow.mm | 4 ++-- src/plugins/platforms/ios/qtmain.mm | 3 ++- 7 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.h b/src/plugins/platforms/ios/qiosapplicationdelegate.h index 442b37f1b3..3d3ba58049 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.h +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.h @@ -42,9 +42,12 @@ #import #import +#import "qiosviewcontroller.h" + @interface QIOSApplicationDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; +@property (strong, nonatomic) QIOSViewController *qiosViewController; @end diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 41a3fff84f..10cbe529c4 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -46,6 +46,7 @@ @implementation QIOSApplicationDelegate @synthesize window; +@synthesize qiosViewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { @@ -85,6 +86,7 @@ - (void)dealloc { + [qiosViewController release]; [window release]; [super dealloc]; } diff --git a/src/plugins/platforms/ios/qiosglobal.h b/src/plugins/platforms/ios/qiosglobal.h index 3be9f8bb21..fd328c9171 100644 --- a/src/plugins/platforms/ios/qiosglobal.h +++ b/src/plugins/platforms/ios/qiosglobal.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QPlatformScreen; bool isQtApplication(); -QIOSViewController *rootViewController(); +QIOSViewController *qiosViewController(); CGRect toCGRect(const QRect &rect); QRect fromCGRect(const CGRect &rect); diff --git a/src/plugins/platforms/ios/qiosglobal.mm b/src/plugins/platforms/ios/qiosglobal.mm index 5860078372..d26eca54e5 100644 --- a/src/plugins/platforms/ios/qiosglobal.mm +++ b/src/plugins/platforms/ios/qiosglobal.mm @@ -58,10 +58,14 @@ bool isQtApplication() return isQt; } -QIOSViewController *rootViewController() +QIOSViewController *qiosViewController() { + // If Qt controls the application, we have created a root view controller were we place top-level + // QWindows. Note that in a mixed native application, our view controller might later be removed or + // added as a child of another controller. To protect against that, we keep an explicit pointer to the + // view controller in cases where this is the controller we need to access. static QIOSViewController *c = isQtApplication() ? - static_cast([UIApplication sharedApplication].delegate.window.rootViewController) : nil; + static_cast([UIApplication sharedApplication].delegate).qiosViewController : nil; return c; } diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm index d86ed5f090..b73f9c3cbc 100644 --- a/src/plugins/platforms/ios/qiosscreen.mm +++ b/src/plugins/platforms/ios/qiosscreen.mm @@ -142,7 +142,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex) if (isQtApplication()) { // When in a non-mixed environment, let QScreen follow the current interface orientation: - setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(rootViewController().interfaceOrientation))); + setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(qiosViewController().interfaceOrientation))); } [pool release]; diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm index d7a2fa1a75..5edf81af93 100644 --- a/src/plugins/platforms/ios/qioswindow.mm +++ b/src/plugins/platforms/ios/qioswindow.mm @@ -375,7 +375,7 @@ void QIOSWindow::setVisible(bool visible) requestActivateWindow(); } else { // Activate top-most visible QWindow: - NSArray *subviews = rootViewController().view.subviews; + NSArray *subviews = qiosViewController().view.subviews; for (int i = int(subviews.count) - 1; i >= 0; --i) { UIView *view = [subviews objectAtIndex:i]; if (!view.hidden) { @@ -431,7 +431,7 @@ void QIOSWindow::setParent(const QPlatformWindow *parentWindow) UIView *parentView = reinterpret_cast(parentWindow->winId()); [parentView addSubview:m_view]; } else if (isQtApplication()) { - [rootViewController().view addSubview:m_view]; + [qiosViewController().view addSubview:m_view]; } } diff --git a/src/plugins/platforms/ios/qtmain.mm b/src/plugins/platforms/ios/qtmain.mm index 916224f936..19c98f2c59 100644 --- a/src/plugins/platforms/ios/qtmain.mm +++ b/src/plugins/platforms/ios/qtmain.mm @@ -56,7 +56,8 @@ extern int qt_main(int argc, char *argv[]); - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; - self.window.rootViewController = [[[QIOSViewController alloc] init] autorelease]; + self.qiosViewController = [[[QIOSViewController alloc] init] autorelease]; + self.window.rootViewController = self.qiosViewController; #ifdef QT_DEBUG self.window.backgroundColor = [UIColor cyanColor];