Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qiosapplicationdelegate.mm
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include "qiosglobal.h"
9#include "qiosservices.h"
11#include "qioswindow.h"
12#include "qiosscreen.h"
13#include "quiwindow.h"
14
15#include <qpa/qplatformintegration.h>
16
17#include <QtCore/QtCore>
18
19@interface QIOSWindowSceneDelegate : NSObject<UIWindowSceneDelegate>
20@property (nullable, nonatomic, strong) UIWindow *window;
21@end
22
23@implementation QIOSApplicationDelegate
24
25- (UISceneConfiguration *)application:(UIApplication *)application
26 configurationForConnectingSceneSession:(UISceneSession *)session
27 options:(UISceneConnectionOptions *)options
28{
29 qCDebug(lcQpaWindowScene) << "Configuring scene for" << session << "with options" << options;
30
31 auto *sceneConfig = session.configuration;
32
33 if ([sceneConfig.role hasPrefix:@"CPTemplateApplication"]) {
34 qCDebug(lcQpaWindowScene) << "Not touching CarPlay scene with role" << sceneConfig.role
35 << "and existing delegate class" << sceneConfig.delegateClass;
36 // FIXME: Consider ignoring any scene with an existing sceneClass, delegateClass, or
37 // storyboard. But for visionOS the default delegate is SwiftUI.AppSceneDelegate.
38 } else {
39 sceneConfig.delegateClass = QIOSWindowSceneDelegate.class;
40 }
41
42 return sceneConfig;
43}
44
45@end
46
47@implementation QIOSWindowSceneDelegate
48
49- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
50{
51 qCDebug(lcQpaWindowScene) << "Connecting" << scene << "to" << session;
52
53 // Handle connection options, even if we return early
54 const auto handleConnectionOptions = qScopeGuard([&]{
55 if (connectionOptions.URLContexts.count > 0)
56 [self scene:scene openURLContexts:connectionOptions.URLContexts];
57 // Handle universal link (https) application cold-launch case
58 for (NSUserActivity *activity in connectionOptions.userActivities)
59 [self scene:scene continueUserActivity:activity];
60 });
61
62#if defined(Q_OS_VISIONOS)
63 // CPImmersiveScene is a UIWindowScene, most likely so it can handle its internal
64 // CPSceneLayerEventWindow and UITextEffectsWindow, but we don't want a QUIWindow
65 // for these scenes, so bail out early.
66 if ([scene.session.role isEqualToString:@"CPSceneSessionRoleImmersiveSpaceApplication"]) {
67 qCDebug(lcQpaWindowScene) << "Skipping UIWindow creation for immersive scene";
68 return;
69 }
70#endif
71
72 if (![scene isKindOfClass:UIWindowScene.class]) {
73 qCWarning(lcQpaWindowScene) << "Unexpectedly encountered non-window scene";
74 return;
75 }
76
77 UIWindowScene *windowScene = static_cast<UIWindowScene*>(scene);
78
79 QUIWindow *window = [[QUIWindow alloc] initWithWindowScene:windowScene];
80 window.rootViewController = [[[QIOSViewController alloc] initWithWindow:window] autorelease];
81
82 self.window = [window autorelease];
83}
84
85- (void)windowScene:(UIWindowScene *)windowScene
86 didUpdateCoordinateSpace:(id<UICoordinateSpace>)previousCoordinateSpace
87 interfaceOrientation:(UIInterfaceOrientation)previousInterfaceOrientation
88 traitCollection:(UITraitCollection *)previousTraitCollection
89{
90 qCDebug(lcQpaWindowScene) << "Scene" << windowScene << "did update properties";
91 if (!self.window)
92 return;
93
94 Q_ASSERT([self.window isKindOfClass:QUIWindow.class]);
95 auto *viewController = static_cast<QIOSViewController*>(self.window.rootViewController);
96 [viewController updatePlatformScreen];
97}
98
99- (void)sceneDidDisconnect:(UIScene *)scene
100{
101 qCDebug(lcQpaWindowScene) << "Disconnecting" << scene;
102 self.window = nil;
103}
104
105- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts
106{
107 qCDebug(lcQpaWindowScene) << "Handling openURLContexts for scene" << scene;
108
109 QIOSIntegration *iosIntegration = QIOSIntegration::instance();
110 Q_ASSERT(iosIntegration);
111
112 QIOSServices *iosServices = static_cast<QIOSServices *>(iosIntegration->services());
113
114 for (UIOpenURLContext *urlContext in URLContexts)
115 iosServices->handleUrl(QUrl::fromNSURL(urlContext.URL));
116}
117
118- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
119{
120 qCDebug(lcQpaWindowScene) << "Handling user activity for scene" << scene;
121
122 if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
123 QIOSIntegration *iosIntegration = QIOSIntegration::instance();
124 Q_ASSERT(iosIntegration);
125
126 QIOSServices *iosServices = static_cast<QIOSServices *>(iosIntegration->services());
127 iosServices->handleUrl(QUrl::fromNSURL(userActivity.webpageURL));
128 }
129}
130
131@end