blob: 990409f2d176896300fc449871920aed8b625042 (
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
|
// 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
#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 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];
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)
iosServices->handleUrl(QUrl::fromNSURL(urlContext.URL));
}
- (void)scene:(UIScene *)scene continueUserActivity:(NSUserActivity *)userActivity
{
qCDebug(lcQpaWindowScene) << "Handling continueUserActivity 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
|