diff options
Diffstat (limited to 'src/plugins/platforms/ios/qiosapplicationdelegate.mm')
-rw-r--r-- | src/plugins/platforms/ios/qiosapplicationdelegate.mm | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/src/plugins/platforms/ios/qiosapplicationdelegate.mm b/src/plugins/platforms/ios/qiosapplicationdelegate.mm index 088d48fc9ff..990409f2d17 100644 --- a/src/plugins/platforms/ios/qiosapplicationdelegate.mm +++ b/src/plugins/platforms/ios/qiosapplicationdelegate.mm @@ -16,19 +16,28 @@ #include <QtCore/QtCore> @interface QIOSWindowSceneDelegate : NSObject<UIWindowSceneDelegate> +@property (nullable, nonatomic, strong) UIWindow *window; @end @implementation QIOSApplicationDelegate - (UISceneConfiguration *)application:(UIApplication *)application - configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession + configurationForConnectingSceneSession:(UISceneSession *)session options:(UISceneConnectionOptions *)options { - qCDebug(lcQpaWindowScene) << "Configuring scene for" << connectingSceneSession - << "with options" << options; + qCDebug(lcQpaWindowScene) << "Configuring scene for" << session << "with options" << options; + + auto *sceneConfig = session.configuration; + + if ([sceneConfig.role hasPrefix:@"CPTemplateApplication"]) { + qCDebug(lcQpaWindowScene) << "Not touching CarPlay scene with role" << sceneConfig.role + << "and existing delegate class" << sceneConfig.delegateClass; + // FIXME: Consider ignoring any scene with an existing sceneClass, delegateClass, or + // storyboard. But for visionOS the default delegate is SwiftUI.AppSceneDelegate. + } else { + sceneConfig.delegateClass = QIOSWindowSceneDelegate.class; + } - auto *sceneConfig = connectingSceneSession.configuration; - sceneConfig.delegateClass = QIOSWindowSceneDelegate.class; return sceneConfig; } @@ -40,27 +49,53 @@ { qCDebug(lcQpaWindowScene) << "Connecting" << scene << "to" << session; - Q_ASSERT([scene isKindOfClass:UIWindowScene.class]); + // Handle URL contexts, even if we return early + const auto handleUrlContexts = qScopeGuard([&]{ + if (connectionOptions.URLContexts.count > 0) + [self scene:scene openURLContexts:connectionOptions.URLContexts]; + }); + +#if defined(Q_OS_VISIONOS) + // CPImmersiveScene is a UIWindowScene, most likely so it can handle its internal + // CPSceneLayerEventWindow and UITextEffectsWindow, but we don't want a QUIWindow + // for these scenes, so bail out early. + if ([scene.session.role isEqualToString:@"CPSceneSessionRoleImmersiveSpaceApplication"]) { + qCDebug(lcQpaWindowScene) << "Skipping UIWindow creation for immersive scene"; + return; + } +#endif + + if (![scene isKindOfClass:UIWindowScene.class]) { + qCWarning(lcQpaWindowScene) << "Unexpectedly encountered non-window scene"; + return; + } + UIWindowScene *windowScene = static_cast<UIWindowScene*>(scene); QUIWindow *window = [[QUIWindow alloc] initWithWindowScene:windowScene]; + window.rootViewController = [[[QIOSViewController alloc] initWithWindow:window] autorelease]; - QIOSScreen *screen = [&]{ - for (auto *screen : qGuiApp->screens()) { - auto *platformScreen = static_cast<QIOSScreen*>(screen->handle()); -#if !defined(Q_OS_VISIONOS) - if (platformScreen->uiScreen() == windowScene.screen) -#endif - return platformScreen; - } - Q_UNREACHABLE(); - }(); + self.window = [window autorelease]; +} - window.rootViewController = [[[QIOSViewController alloc] - initWithWindow:window andScreen:screen] autorelease]; +- (void)windowScene:(UIWindowScene *)windowScene + didUpdateCoordinateSpace:(id<UICoordinateSpace>)previousCoordinateSpace + interfaceOrientation:(UIInterfaceOrientation)previousInterfaceOrientation + traitCollection:(UITraitCollection *)previousTraitCollection +{ + qCDebug(lcQpaWindowScene) << "Scene" << windowScene << "did update properties"; + if (!self.window) + return; - if (connectionOptions.URLContexts.count > 0) - [self scene:scene openURLContexts:connectionOptions.URLContexts]; + Q_ASSERT([self.window isKindOfClass:QUIWindow.class]); + auto *viewController = static_cast<QIOSViewController*>(self.window.rootViewController); + [viewController updatePlatformScreen]; +} + +- (void)sceneDidDisconnect:(UIScene *)scene +{ + qCDebug(lcQpaWindowScene) << "Disconnecting" << scene; + self.window = nil; } - (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts |