blob: 380c5a588e6ab4c1f5b83336b6ae422e4a23762b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qiosapplicationdelegate.h"
#include "qiosglobal.h"
#include "qiosintegration.h"
#include "qiosservices.h"
#include "qiosviewcontroller.h"
#include "qioswindow.h"
#include "qiosscreen.h"
#include "quiwindow.h"
#include <qpa/qplatformintegration.h>
#include <QtCore/QtCore>
@interface QIOSWindowSceneDelegate : NSObject<UIWindowSceneDelegate>
@property (nullable, nonatomic, strong) UIWindow *window;
@end
@implementation QIOSApplicationDelegate
- (UISceneConfiguration *)application:(UIApplication *)application
configurationForConnectingSceneSession:(UISceneSession *)session
options:(UISceneConnectionOptions *)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;
}
return sceneConfig;
}
@end
@implementation QIOSWindowSceneDelegate
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions
{
qCDebug(lcQpaWindowScene) << "Connecting" << scene << "to" << session;
// Handle connection options, even if we return early
const auto handleConnectionOptions = qScopeGuard([&]{
if (connectionOptions.URLContexts.count > 0)
[self scene:scene openURLContexts:connectionOptions.URLContexts];
// Handle universal link (https) application cold-launch case
for (NSUserActivity *activity in connectionOptions.userActivities)
[self scene:scene continueUserActivity:activity];
});
#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];
self.window = [window 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;
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
{
qCDebug(lcQpaWindowScene) << "Handling openURLContexts for scene" << scene;
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
Q_ASSERT(iosIntegration);
QIOSServices *iosServices = static_cast<QIOSServices *>(iosIntegration->services());
for (UIOpenURLContext *urlContext in URLContexts) {
QUrl url = QUrl::fromNSURL(urlContext.URL);
if (url.isLocalFile())
QWindowSystemInterface::handleFileOpenEvent(url);
else
iosServices->handleUrl(url);
}
}
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
{
qCDebug(lcQpaWindowScene) << "Handling user activity for scene" << scene;
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
QIOSIntegration *iosIntegration = QIOSIntegration::instance();
Q_ASSERT(iosIntegration);
QIOSServices *iosServices = static_cast<QIOSServices *>(iosIntegration->services());
iosServices->handleUrl(QUrl::fromNSURL(userActivity.webpageURL));
}
}
@end
|