summaryrefslogtreecommitdiffstats
path: root/platform/ios
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios')
-rw-r--r--platform/ios/app_delegate.mm20
-rw-r--r--platform/ios/detect.py5
-rw-r--r--platform/ios/display_server_ios.h8
-rw-r--r--platform/ios/display_server_ios.mm10
-rw-r--r--platform/ios/export/export_plugin.cpp36
-rw-r--r--platform/ios/export/export_plugin.h4
-rw-r--r--platform/ios/godot_view.mm17
-rw-r--r--platform/ios/os_ios.h9
-rw-r--r--platform/ios/os_ios.mm34
9 files changed, 125 insertions, 18 deletions
diff --git a/platform/ios/app_delegate.mm b/platform/ios/app_delegate.mm
index 8a16f8fcc1..5a0c57be93 100644
--- a/platform/ios/app_delegate.mm
+++ b/platform/ios/app_delegate.mm
@@ -105,11 +105,17 @@ static ViewController *mainViewController = nil;
// Initialize with default Ambient category.
AVAudioSessionCategory category = AVAudioSessionCategoryAmbient;
+ AVAudioSessionCategoryOptions options = 0;
+
+ if (GLOBAL_GET("audio/general/ios/mix_with_others")) {
+ options |= AVAudioSessionCategoryOptionMixWithOthers;
+ }
if (sessionCategorySetting == SESSION_CATEGORY_MULTI_ROUTE) {
category = AVAudioSessionCategoryMultiRoute;
} else if (sessionCategorySetting == SESSION_CATEGORY_PLAY_AND_RECORD) {
category = AVAudioSessionCategoryPlayAndRecord;
+ options |= AVAudioSessionCategoryOptionDefaultToSpeaker;
} else if (sessionCategorySetting == SESSION_CATEGORY_PLAYBACK) {
category = AVAudioSessionCategoryPlayback;
} else if (sessionCategorySetting == SESSION_CATEGORY_RECORD) {
@@ -118,11 +124,7 @@ static ViewController *mainViewController = nil;
category = AVAudioSessionCategorySoloAmbient;
}
- if (GLOBAL_GET("audio/general/ios/mix_with_others")) {
- [[AVAudioSession sharedInstance] setCategory:category withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
- } else {
- [[AVAudioSession sharedInstance] setCategory:category error:nil];
- }
+ [[AVAudioSession sharedInstance] setCategory:category withOptions:options error:nil];
return YES;
}
@@ -167,6 +169,14 @@ static ViewController *mainViewController = nil;
OS_IOS::get_singleton()->on_focus_in();
}
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ OS_IOS::get_singleton()->on_enter_background();
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ OS_IOS::get_singleton()->on_exit_background();
+}
+
- (void)dealloc {
self.window = nil;
}
diff --git a/platform/ios/detect.py b/platform/ios/detect.py
index f8468e3d9e..4d6e3ae9ba 100644
--- a/platform/ios/detect.py
+++ b/platform/ios/detect.py
@@ -5,7 +5,7 @@ from methods import detect_darwin_sdk_path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
- from SCons import Environment
+ from SCons.Script.SConscript import SConsEnvironment
def get_name():
@@ -51,10 +51,11 @@ def get_flags():
("arch", "arm64"), # Default for convenience.
("target", "template_debug"),
("use_volk", False),
+ ("supported", ["mono"]),
]
-def configure(env: "Environment"):
+def configure(env: "SConsEnvironment"):
# Validate arch.
supported_arches = ["x86_64", "arm64"]
if env["arch"] not in supported_arches:
diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h
index 3efd2498d4..6f66783a47 100644
--- a/platform/ios/display_server_ios.h
+++ b/platform/ios/display_server_ios.h
@@ -77,6 +77,8 @@ class DisplayServerIOS : public DisplayServer {
Callable input_event_callback;
Callable input_text_callback;
+ Callable system_theme_changed;
+
int virtual_keyboard_height = 0;
void perform_event(const Ref<InputEvent> &p_event);
@@ -109,6 +111,8 @@ public:
void send_window_event(DisplayServer::WindowEvent p_event) const;
void _window_callback(const Callable &p_callable, const Variant &p_arg) const;
+ void emit_system_theme_changed();
+
// MARK: - Input
// MARK: Touches and Apple Pencil
@@ -145,6 +149,7 @@ public:
virtual bool is_dark_mode_supported() const override;
virtual bool is_dark_mode() const override;
+ virtual void set_system_theme_change_callback(const Callable &p_callable) override;
virtual Rect2i get_display_safe_area() const override;
@@ -159,8 +164,7 @@ public:
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
- virtual WindowID
- get_window_at_screen_position(const Point2i &p_position) const override;
+ virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index 2895dffdfa..ed69b91fdd 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -387,6 +387,16 @@ bool DisplayServerIOS::is_dark_mode() const {
}
}
+void DisplayServerIOS::set_system_theme_change_callback(const Callable &p_callable) {
+ system_theme_changed = p_callable;
+}
+
+void DisplayServerIOS::emit_system_theme_changed() {
+ if (system_theme_changed.is_valid()) {
+ system_theme_changed.call();
+ }
+}
+
Rect2i DisplayServerIOS::get_display_safe_area() const {
UIEdgeInsets insets = UIEdgeInsetsZero;
UIView *view = AppDelegate.viewController.godotView;
diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index f518d7607b..91d75b0629 100644
--- a/platform/ios/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -124,6 +124,16 @@ String EditorExportPlatformIOS::get_export_option_warning(const EditorExportPres
return String();
}
+void EditorExportPlatformIOS::_notification(int p_what) {
+#ifdef MACOS_ENABLED
+ if (p_what == NOTIFICATION_POSTINITIALIZE) {
+ if (EditorExport::get_singleton()) {
+ EditorExport::get_singleton()->connect_presets_runnable_updated(callable_mp(this, &EditorExportPlatformIOS::_update_preset_status));
+ }
+ }
+#endif
+}
+
bool EditorExportPlatformIOS::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const {
return true;
}
@@ -2234,7 +2244,7 @@ void EditorExportPlatformIOS::_check_for_changes_poll_thread(void *ud) {
// Enum real devices (via ios_deploy, pre Xcode 15).
String idepl = EDITOR_GET("export/ios/ios_deploy");
- if (!idepl.is_empty()) {
+ if (ea->has_runnable_preset.is_set() && !idepl.is_empty()) {
String devices;
List<String> args;
args.push_back("-c");
@@ -2272,7 +2282,7 @@ void EditorExportPlatformIOS::_check_for_changes_poll_thread(void *ud) {
}
// Enum simulators.
- if (_check_xcode_install() && (FileAccess::exists("/usr/bin/xcrun") || FileAccess::exists("/bin/xcrun"))) {
+ if (ea->has_runnable_preset.is_set() && _check_xcode_install() && (FileAccess::exists("/usr/bin/xcrun") || FileAccess::exists("/bin/xcrun"))) {
{
String devices;
List<String> args;
@@ -2310,7 +2320,7 @@ void EditorExportPlatformIOS::_check_for_changes_poll_thread(void *ud) {
}
// Enum simulators.
- {
+ if (ea->has_runnable_preset.is_set()) {
String devices;
List<String> args;
args.push_back("simctl");
@@ -2379,6 +2389,25 @@ void EditorExportPlatformIOS::_check_for_changes_poll_thread(void *ud) {
}
}
}
+
+void EditorExportPlatformIOS::_update_preset_status() {
+ const int preset_count = EditorExport::get_singleton()->get_export_preset_count();
+ bool has_runnable = false;
+
+ for (int i = 0; i < preset_count; i++) {
+ const Ref<EditorExportPreset> &preset = EditorExport::get_singleton()->get_export_preset(i);
+ if (preset->get_platform() == this && preset->is_runnable()) {
+ has_runnable = true;
+ break;
+ }
+ }
+
+ if (has_runnable) {
+ has_runnable_preset.set();
+ } else {
+ has_runnable_preset.clear();
+ }
+}
#endif
Error EditorExportPlatformIOS::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) {
@@ -2643,6 +2672,7 @@ EditorExportPlatformIOS::EditorExportPlatformIOS() {
plugins_changed.set();
devices_changed.set();
#ifdef MACOS_ENABLED
+ _update_preset_status();
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
#endif
}
diff --git a/platform/ios/export/export_plugin.h b/platform/ios/export/export_plugin.h
index edbe566dab..197f27da76 100644
--- a/platform/ios/export/export_plugin.h
+++ b/platform/ios/export/export_plugin.h
@@ -81,9 +81,11 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
#ifdef MACOS_ENABLED
Thread check_for_changes_thread;
SafeFlag quit_request;
+ SafeFlag has_runnable_preset;
static bool _check_xcode_install();
static void _check_for_changes_poll_thread(void *ud);
+ void _update_preset_status();
#endif
typedef Error (*FileHandler)(String p_file, void *p_userdata);
@@ -152,6 +154,8 @@ protected:
virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override;
virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override;
+ void _notification(int p_what);
+
public:
virtual String get_name() const override { return "iOS"; }
virtual String get_os_name() const override { return "iOS"; }
diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm
index ff8a4f8921..4b87863fc5 100644
--- a/platform/ios/godot_view.mm
+++ b/platform/ios/godot_view.mm
@@ -167,6 +167,23 @@ static const float earth_gravity = 9.80665;
}
}
+- (void)system_theme_changed {
+ DisplayServerIOS *ds = (DisplayServerIOS *)DisplayServer::get_singleton();
+ if (ds) {
+ ds->emit_system_theme_changed();
+ }
+}
+
+- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
+ if (@available(iOS 13.0, *)) {
+ [super traitCollectionDidChange:previousTraitCollection];
+
+ if ([UITraitCollection currentTraitCollection].userInterfaceStyle != previousTraitCollection.userInterfaceStyle) {
+ [self system_theme_changed];
+ }
+ }
+}
+
- (void)stopRendering {
if (!self.isActive) {
return;
diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h
index 2d985a6c0b..10ecd08a89 100644
--- a/platform/ios/os_ios.h
+++ b/platform/ios/os_ios.h
@@ -103,16 +103,16 @@ public:
virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override;
virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override;
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override;
+ virtual Error open_dynamic_library(const String &p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override;
virtual Error close_dynamic_library(void *p_library_handle) override;
- virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
+ virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String &p_name, void *&p_symbol_handle, bool p_optional = false) override;
virtual String get_name() const override;
virtual String get_distribution_name() const override;
virtual String get_version() const override;
virtual String get_model_name() const override;
- virtual Error shell_open(String p_uri) override;
+ virtual Error shell_open(const String &p_uri) override;
virtual String get_user_data_dir() const override;
@@ -129,6 +129,9 @@ public:
void on_focus_out();
void on_focus_in();
+
+ void on_enter_background();
+ void on_exit_background();
};
#endif // IOS_ENABLED
diff --git a/platform/ios/os_ios.mm b/platform/ios/os_ios.mm
index 6ac21fa9c8..23614af366 100644
--- a/platform/ios/os_ios.mm
+++ b/platform/ios/os_ios.mm
@@ -219,7 +219,7 @@ _FORCE_INLINE_ String OS_IOS::get_framework_executable(const String &p_path) {
return p_path;
}
-Error OS_IOS::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
+Error OS_IOS::open_dynamic_library(const String &p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
if (p_path.length() == 0) {
// Static xcframework.
p_library_handle = RTLD_SELF;
@@ -272,7 +272,7 @@ Error OS_IOS::close_dynamic_library(void *p_library_handle) {
return OS_Unix::close_dynamic_library(p_library_handle);
}
-Error OS_IOS::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
+Error OS_IOS::get_dynamic_library_symbol_handle(void *p_library_handle, const String &p_name, void *&p_symbol_handle, bool p_optional) {
if (p_library_handle == RTLD_SELF) {
void **ptr = OS_IOS::dynamic_symbol_lookup_table.getptr(p_name);
if (ptr) {
@@ -305,7 +305,7 @@ String OS_IOS::get_model_name() const {
return OS_Unix::get_model_name();
}
-Error OS_IOS::shell_open(String p_uri) {
+Error OS_IOS::shell_open(const String &p_uri) {
NSString *urlPath = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
NSURL *url = [NSURL URLWithString:urlPath];
@@ -601,6 +601,10 @@ void OS_IOS::on_focus_out() {
DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
}
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
+ }
+
[AppDelegate.viewController.godotView stopRendering];
audio_driver.stop();
@@ -615,10 +619,34 @@ void OS_IOS::on_focus_in() {
DisplayServerIOS::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
}
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
+ }
+
[AppDelegate.viewController.godotView startRendering];
audio_driver.start();
}
}
+void OS_IOS::on_enter_background() {
+ // Do not check for is_focused, because on_focus_out will always be fired first by applicationWillResignActive.
+
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_PAUSED);
+ }
+
+ on_focus_out();
+}
+
+void OS_IOS::on_exit_background() {
+ if (!is_focused) {
+ on_focus_in();
+
+ if (OS::get_singleton()->get_main_loop()) {
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_RESUMED);
+ }
+ }
+}
+
#endif // IOS_ENABLED