Skip to content

Commit 6bc378e

Browse files
bruvzglawnjelly
authored andcommitted
[iOS, 3.x] Switch window creation to UIScene.
(cherry picked from commit ec5920e)
1 parent 9ca84aa commit 6bc378e

File tree

7 files changed

+269
-30
lines changed

7 files changed

+269
-30
lines changed

misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,19 @@
5959
$additional_plist_content
6060
$plist_launch_screen_name
6161
<key>CADisableMinimumFrameDurationOnPhone</key><true/>
62+
<key>UIApplicationSceneManifest</key>
63+
<dict>
64+
<key>UIApplicationSupportsMultipleScenes</key><false/>
65+
<key>UISceneConfigurations</key>
66+
<dict>
67+
<key>UIWindowSceneSessionRoleApplication</key>
68+
<array>
69+
<dict>
70+
<key>UISceneConfigurationName</key>
71+
<string>Default Configuration</string>
72+
</dict>
73+
</array>
74+
</dict>
75+
</dict>
6276
</dict>
6377
</plist>

platform/iphone/SCsub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ iphone_lib = [
1414
"tts_ios.mm",
1515
"display_layer.mm",
1616
"godot_app_delegate.m",
17+
"godot_scene_delegate.m",
1718
"godot_view_renderer.mm",
1819
"device_metrics.m",
1920
"keyboard_input_view.mm",

platform/iphone/app_delegate.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232

3333
@class ViewController;
3434

35-
@interface AppDelegate : NSObject <UIApplicationDelegate>
35+
@interface AppDelegate : NSObject <UIApplicationDelegate, UIWindowSceneDelegate>
36+
37+
+ (AppDelegate *)getSingleton;
3638

3739
@property(strong, nonatomic) UIWindow *window;
3840
@property(strong, class, readonly, nonatomic) ViewController *viewController;

platform/iphone/app_delegate.mm

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,37 @@ + (ViewController *)viewController {
6464
return mainViewController;
6565
}
6666

67-
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
68-
// Create a full-screen window
69-
CGRect windowBounds = [[UIScreen mainScreen] bounds];
70-
self.window = [[UIWindow alloc] initWithFrame:windowBounds];
67+
static AppDelegate *delegate_singleton = nil;
68+
69+
+ (AppDelegate *)getSingleton {
70+
if (!delegate_singleton) {
71+
delegate_singleton = [AppDelegate new];
72+
}
73+
return delegate_singleton;
74+
}
75+
76+
- (void)createViewController {
77+
ViewController *viewController = [[ViewController alloc] init];
78+
viewController.godotView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
79+
viewController.godotView.renderingInterval = 1.0 / kRenderingFrequency;
80+
81+
self.window.rootViewController = viewController;
82+
83+
// Show the window
84+
[self.window makeKeyAndVisible];
85+
86+
mainViewController = viewController;
87+
}
88+
89+
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0), tvos(13.0), visionos(1.0)) {
90+
if ([scene isKindOfClass:[UIWindowScene class]]) {
91+
UIWindowScene *window_scene = (UIWindowScene *)scene;
92+
self.window = [[UIWindow alloc] initWithWindowScene:window_scene];
93+
[self createViewController];
94+
}
95+
}
7196

97+
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
7298
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
7399
NSUserDomainMask, YES);
74100
NSString *documentsDirectory = [paths objectAtIndex:0];
@@ -83,27 +109,21 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
83109
return FALSE;
84110
}
85111

86-
// WARNING: We must *always* create the GodotView after we have constructed the
87-
// OS with iphone_main. This allows the GodotView to access project settings so
88-
// it can properly initialize the OpenGL context
89-
90-
ViewController *viewController = [[ViewController alloc] init];
91-
viewController.godotView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
92-
viewController.godotView.renderingInterval = 1.0 / kRenderingFrequency;
93-
94-
self.window.rootViewController = viewController;
95-
96-
// Show the window
97-
[self.window makeKeyAndVisible];
112+
if (@available(iOS 13, tvOS 13, *)) {
113+
// NOP
114+
} else {
115+
// Create a full-screen window
116+
CGRect windowBounds = [[UIScreen mainScreen] bounds];
117+
self.window = [[UIWindow alloc] initWithFrame:windowBounds];
118+
[self createViewController];
119+
}
98120

99121
[[NSNotificationCenter defaultCenter]
100122
addObserver:self
101123
selector:@selector(onAudioInterruption:)
102124
name:AVAudioSessionInterruptionNotification
103125
object:[AVAudioSession sharedInstance]];
104126

105-
mainViewController = viewController;
106-
107127
int sessionCategorySetting = GLOBAL_GET("audio/general/ios/session_category");
108128

109129
// Initialize with default Ambient category.
@@ -166,22 +186,42 @@ - (void)applicationWillTerminate:(UIApplication *)application {
166186
// if you open the app list without switching to another app or open/close the
167187
// notification panel by swiping from the upper part of the screen.
168188

189+
- (void)sceneDidDisconnect:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0), visionos(1.0)) {
190+
OSIPhone::get_singleton()->on_focus_out();
191+
}
192+
169193
- (void)applicationWillResignActive:(UIApplication *)application {
170194
OSIPhone::get_singleton()->on_focus_out();
171195
}
172196

197+
- (void)sceneWillResignActive:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0), visionos(1.0)) {
198+
OSIPhone::get_singleton()->on_focus_out();
199+
}
200+
173201
- (void)applicationDidBecomeActive:(UIApplication *)application {
174202
OSIPhone::get_singleton()->on_focus_in();
175203
}
176204

205+
- (void)sceneDidBecomeActive:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0), visionos(1.0)) {
206+
OSIPhone::get_singleton()->on_focus_in();
207+
}
208+
177209
- (void)applicationDidEnterBackground:(UIApplication *)application {
178210
OSIPhone::get_singleton()->on_enter_background();
179211
}
180212

213+
- (void)sceneDidEnterBackground:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0), visionos(1.0)) {
214+
OSIPhone::get_singleton()->on_enter_background();
215+
}
216+
181217
- (void)applicationWillEnterForeground:(UIApplication *)application {
182218
OSIPhone::get_singleton()->on_exit_background();
183219
}
184220

221+
- (void)sceneWillEnterForeground:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0), visionos(1.0)) {
222+
OSIPhone::get_singleton()->on_exit_background();
223+
}
224+
185225
- (void)dealloc {
186226
self.window = nil;
187227
}

platform/iphone/godot_app_delegate.m

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#import "godot_app_delegate.h"
3232

3333
#import "app_delegate.h"
34+
#import "godot_scene_delegate.h"
3435

3536
@interface GodotApplicalitionDelegate ()
3637

@@ -46,7 +47,7 @@ @implementation GodotApplicalitionDelegate
4647

4748
+ (void)load {
4849
services = [NSMutableArray new];
49-
[services addObject:[AppDelegate new]];
50+
[services addObject:[AppDelegate getSingleton]];
5051
}
5152

5253
+ (void)addService:(ApplicationDelegateService *)service {
@@ -63,15 +64,29 @@ + (void)addService:(ApplicationDelegateService *)service {
6364
- (UIWindow *)window {
6465
UIWindow *result = nil;
6566

66-
for (ApplicationDelegateService *service in services) {
67-
if (![service respondsToSelector:_cmd]) {
68-
continue;
67+
if (@available(iOS 13, tvOS 13, *)) {
68+
for (SceneDelegateService *service in [SceneDelegate services]) {
69+
if (![service respondsToSelector:_cmd]) {
70+
continue;
71+
}
72+
73+
UIWindow *value = [service window];
74+
75+
if (value) {
76+
result = value;
77+
}
6978
}
79+
} else {
80+
for (ApplicationDelegateService *service in services) {
81+
if (![service respondsToSelector:_cmd]) {
82+
continue;
83+
}
7084

71-
UIWindow *value = [service window];
85+
UIWindow *value = [service window];
7286

73-
if (value) {
74-
result = value;
87+
if (value) {
88+
result = value;
89+
}
7590
}
7691
}
7792

@@ -456,12 +471,15 @@ - (void)application:(UIApplication *)application userDidAcceptCloudKitShareWithM
456471
}
457472
}
458473

459-
/* Handled By Info.plist file for now
460-
461474
// MARK: Interface Geometry
462475

463-
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {}
476+
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0), tvos(13.0)) {
477+
UISceneConfiguration *config = [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
478+
config.delegateClass = [SceneDelegate class];
479+
return config;
480+
}
464481

465-
*/
482+
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions API_AVAILABLE(ios(13.0), tvos(13.0)) {
483+
}
466484

467485
@end
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**************************************************************************/
2+
/* godot_scene_delegate.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#import <UIKit/UIKit.h>
32+
33+
typedef NSObject<UIWindowSceneDelegate> SceneDelegateService API_AVAILABLE(ios(13.0), tvos(13.0));
34+
35+
API_AVAILABLE(ios(13.0), tvos(13.0))
36+
@interface SceneDelegate : NSObject <UIWindowSceneDelegate>
37+
38+
@property(class, readonly, strong) NSArray<SceneDelegateService *> *services;
39+
40+
+ (void)addService:(SceneDelegateService *)service;
41+
42+
@end
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/**************************************************************************/
2+
/* godot_scene_delegate.m */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#import "godot_scene_delegate.h"
32+
33+
#import "app_delegate.h"
34+
35+
@implementation SceneDelegate
36+
37+
API_AVAILABLE(ios(13.0), tvos(13.0))
38+
static NSMutableArray<SceneDelegateService *> *services = nil;
39+
40+
+ (NSArray<SceneDelegateService *> *)services API_AVAILABLE(ios(13.0), tvos(13.0)) {
41+
return services;
42+
}
43+
44+
+ (void)load {
45+
if (@available(iOS 13, tvOS 13, *)) {
46+
services = [NSMutableArray new];
47+
[services addObject:[AppDelegate getSingleton]];
48+
}
49+
}
50+
51+
+ (void)addService:(SceneDelegateService *)service API_AVAILABLE(ios(13.0), tvos(13.0)) {
52+
if (!services || !service) {
53+
return;
54+
}
55+
[services addObject:service];
56+
}
57+
58+
// MARK: Scene
59+
60+
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions API_AVAILABLE(ios(13.0), tvos(13.0)) {
61+
for (SceneDelegateService *service in services) {
62+
if (![service respondsToSelector:_cmd]) {
63+
continue;
64+
}
65+
66+
[service scene:scene willConnectToSession:session options:connectionOptions];
67+
}
68+
}
69+
70+
// MARK: Life-Cycle
71+
72+
- (void)sceneDidDisconnect:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0)) {
73+
for (SceneDelegateService *service in services) {
74+
if (![service respondsToSelector:_cmd]) {
75+
continue;
76+
}
77+
78+
[service sceneDidDisconnect:scene];
79+
}
80+
}
81+
82+
- (void)sceneDidBecomeActive:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0)) {
83+
for (SceneDelegateService *service in services) {
84+
if (![service respondsToSelector:_cmd]) {
85+
continue;
86+
}
87+
88+
[service sceneDidBecomeActive:scene];
89+
}
90+
}
91+
92+
- (void)sceneWillResignActive:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0)) {
93+
for (SceneDelegateService *service in services) {
94+
if (![service respondsToSelector:_cmd]) {
95+
continue;
96+
}
97+
98+
[service sceneWillResignActive:scene];
99+
}
100+
}
101+
102+
- (void)sceneDidEnterBackground:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0)) {
103+
for (SceneDelegateService *service in services) {
104+
if (![service respondsToSelector:_cmd]) {
105+
continue;
106+
}
107+
108+
[service sceneDidEnterBackground:scene];
109+
}
110+
}
111+
112+
- (void)sceneWillEnterForeground:(UIScene *)scene API_AVAILABLE(ios(13.0), tvos(13.0)) {
113+
for (SceneDelegateService *service in services) {
114+
if (![service respondsToSelector:_cmd]) {
115+
continue;
116+
}
117+
118+
[service sceneWillEnterForeground:scene];
119+
}
120+
}
121+
122+
@end

0 commit comments

Comments
 (0)