diff options
Diffstat (limited to 'platform/osx')
-rw-r--r-- | platform/osx/crash_handler_osx.mm | 16 | ||||
-rw-r--r-- | platform/osx/detect.py | 6 | ||||
-rw-r--r-- | platform/osx/display_server_osx.h | 18 | ||||
-rw-r--r-- | platform/osx/display_server_osx.mm | 203 | ||||
-rw-r--r-- | platform/osx/export/codesign.cpp | 11 | ||||
-rw-r--r-- | platform/osx/export/codesign.h | 1 | ||||
-rw-r--r-- | platform/osx/export/export_plugin.cpp | 31 | ||||
-rw-r--r-- | platform/osx/export/export_plugin.h | 1 | ||||
-rw-r--r-- | platform/osx/godot_application_delegate.mm | 4 | ||||
-rw-r--r-- | platform/osx/godot_content_view.mm | 6 | ||||
-rw-r--r-- | platform/osx/godot_main_osx.mm | 4 | ||||
-rw-r--r-- | platform/osx/godot_window.mm | 4 | ||||
-rw-r--r-- | platform/osx/godot_window_delegate.mm | 16 | ||||
-rw-r--r-- | platform/osx/joypad_osx.cpp | 14 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 16 | ||||
-rw-r--r-- | platform/osx/osx_terminal_logger.mm | 5 |
17 files changed, 301 insertions, 56 deletions
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 16be941308..06ed91907c 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -33,7 +33,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "main/main.h" #include <string.h> @@ -90,14 +89,15 @@ static void handle_crash(int sig) { fprintf(stderr, "\n================================================================\n"); fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); - if (OS::get_singleton()->get_main_loop()) + if (OS::get_singleton()->get_main_loop()) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH); + } // Print the engine version just before, so that people are reminded to include the version in backtrace reports. - if (String(VERSION_HASH).length() != 0) { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + if (String(VERSION_HASH).is_empty()) { + fprintf(stderr, "Engine version: %s\n", VERSION_FULL_NAME); } else { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + fprintf(stderr, "Engine version: %s (%s)\n", VERSION_FULL_NAME, VERSION_HASH); } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); char **strings = backtrace_symbols(bt_buffer, size); @@ -120,8 +120,9 @@ static void handle_crash(int sig) { snprintf(fname, 1024, "%s", demangled); } - if (demangled) + if (demangled) { free(demangled); + } } } @@ -178,8 +179,9 @@ CrashHandler::~CrashHandler() { } void CrashHandler::disable() { - if (disabled) + if (disabled) { return; + } #ifdef CRASH_HANDLER_ENABLED signal(SIGSEGV, nullptr); diff --git a/platform/osx/detect.py b/platform/osx/detect.py index e7fe37d4b5..0ff93bedb4 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -78,9 +78,9 @@ def configure(env): env["osxcross"] = True if env["arch"] == "arm64": - print("Building for macOS 11.00+, platform arm64.") - env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.00"]) - env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.00"]) + print("Building for macOS 11.0+, platform arm64.") + env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) + env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"]) else: print("Building for macOS 10.12+, platform x86_64.") env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"]) diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h index eaf03d298e..cc9ac162ea 100644 --- a/platform/osx/display_server_osx.h +++ b/platform/osx/display_server_osx.h @@ -95,6 +95,7 @@ public: ObjectID instance_id; WindowID transient_parent = INVALID_WINDOW_ID; + bool exclusive = false; Set<WindowID> transient_children; bool layered_window = false; @@ -103,8 +104,14 @@ public: bool borderless = false; bool resize_disabled = false; bool no_focus = false; + bool is_popup = false; + + Rect2i parent_safe_rect; }; + List<WindowID> popup_list; + uint64_t time_since_popup = 0; + private: #if defined(GLES3_ENABLED) GLManager_OSX *gl_manager = nullptr; @@ -153,6 +160,7 @@ private: float display_max_scale = 1.f; Point2i origin; bool displays_arrangement_dirty = true; + bool is_resizing = false; CursorShape cursor_shape = CURSOR_ARROW; NSCursor *cursors[CURSOR_MAX]; @@ -196,6 +204,11 @@ public: void push_to_key_event_buffer(const KeyEvent &p_event); void update_im_text(const Point2i &p_selection, const String &p_text); void set_last_focused_window(WindowID p_window); + void mouse_process_popups(bool p_close = false); + void popup_open(WindowID p_window); + void popup_close(WindowID p_window); + void set_is_resizing(bool p_is_resizing); + bool get_is_resizing() const; void window_update(WindowID p_window); void window_destroy(WindowID p_window); @@ -258,6 +271,10 @@ public: virtual void show_window(WindowID p_id) override; virtual void delete_sub_window(WindowID p_id) override; + virtual WindowID window_get_active_popup() const override; + virtual void window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) override; + virtual Rect2i window_get_popup_safe_rect(WindowID p_window) const override; + virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override; @@ -274,6 +291,7 @@ public: virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override; virtual void window_set_transient(WindowID p_window, WindowID p_parent) override; + virtual void window_set_exclusive(WindowID p_window, bool p_exclusive) override; virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override; virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 2691664b96..a4cd8f58bd 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -324,27 +324,39 @@ void DisplayServerOSX::_dispatch_input_event(const Ref<InputEvent> &p_event) { Variant ret; Callable::CallError ce; + { + List<WindowID>::Element *E = popup_list.front(); + if (E && Object::cast_to<InputEventKey>(*p_event)) { + // Redirect keyboard input to active popup. + if (windows.has(E->get())) { + Callable callable = windows[E->get()].input_event_callback; + if (callable.is_valid()) { + callable.call((const Variant **)&evp, 1, ret, ce); + } + } + in_dispatch_input_event = false; + return; + } + } + Ref<InputEventFromWindow> event_from_window = p_event; if (event_from_window.is_valid() && event_from_window->get_window_id() != INVALID_WINDOW_ID) { // Send to a window. if (windows.has(event_from_window->get_window_id())) { Callable callable = windows[event_from_window->get_window_id()].input_event_callback; - if (callable.is_null()) { - return; + if (callable.is_valid()) { + callable.call((const Variant **)&evp, 1, ret, ce); } - callable.call((const Variant **)&evp, 1, ret, ce); } } else { // Send to all windows. - for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) { - Callable callable = E->get().input_event_callback; - if (callable.is_null()) { - continue; + for (KeyValue<WindowID, WindowData> &E : windows) { + Callable callable = E.value.input_event_callback; + if (callable.is_valid()) { + callable.call((const Variant **)&evp, 1, ret, ce); } - callable.call((const Variant **)&evp, 1, ret, ce); } } - in_dispatch_input_event = false; } } @@ -513,6 +525,9 @@ DisplayServerOSX::WindowData &DisplayServerOSX::get_window(WindowID p_window) { } void DisplayServerOSX::send_event(NSEvent *p_event) { + if ([p_event type] == NSEventTypeLeftMouseDown || [p_event type] == NSEventTypeRightMouseDown || [p_event type] == NSEventTypeOtherMouseDown) { + mouse_process_popups(); + } // Special case handling of command-period, which is traditionally a special // shortcut in macOS and doesn't arrive at our regular keyDown handler. if ([p_event type] == NSEventTypeKeyDown) { @@ -584,6 +599,14 @@ void DisplayServerOSX::set_last_focused_window(WindowID p_window) { last_focused_window = p_window; } +void DisplayServerOSX::set_is_resizing(bool p_is_resizing) { + is_resizing = p_is_resizing; +} + +bool DisplayServerOSX::get_is_resizing() const { + return is_resizing; +} + void DisplayServerOSX::window_update(WindowID p_window) { #if defined(GLES3_ENABLED) if (gl_manager) { @@ -790,8 +813,9 @@ String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root, const NSMenu *sub_menu = [menu_item submenu]; if (sub_menu) { for (Map<String, NSMenu *>::Element *E = submenu.front(); E; E = E->next()) { - if (E->get() == sub_menu) + if (E->get() == sub_menu) { return E->key(); + } } } } @@ -1335,7 +1359,7 @@ float DisplayServerOSX::screen_get_refresh_rate(int p_screen) const { const double displayRefreshRate = CGDisplayModeGetRefreshRate(displayMode); return (float)displayRefreshRate; } - ERR_PRINT("An error occured while trying to get the screen refresh rate."); + ERR_PRINT("An error occurred while trying to get the screen refresh rate."); return SCREEN_REFRESH_RATE_FALLBACK; } @@ -1365,7 +1389,8 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, V void DisplayServerOSX::show_window(WindowID p_id) { WindowData &wd = windows[p_id]; - if (wd.no_focus) { + popup_open(p_id); + if (wd.no_focus || wd.is_popup) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -1471,6 +1496,24 @@ void DisplayServerOSX::window_set_current_screen(int p_screen, WindowID p_window } } +void DisplayServerOSX::window_set_exclusive(WindowID p_window, bool p_exclusive) { + _THREAD_SAFE_METHOD_ + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd = windows[p_window]; + if (wd.exclusive != p_exclusive) { + wd.exclusive = p_exclusive; + if (wd.transient_parent != INVALID_WINDOW_ID) { + WindowData &wd_parent = windows[wd.transient_parent]; + if (wd.exclusive) { + ERR_FAIL_COND_MSG([[wd_parent.window_object childWindows] count] > 0, "Transient parent has another exclusive child."); + [wd_parent.window_object addChildWindow:wd.window_object ordered:NSWindowAbove]; + } else { + [wd_parent.window_object removeChildWindow:wd.window_object]; + } + } + } +} + Point2i DisplayServerOSX::window_get_position(WindowID p_window) const { _THREAD_SAFE_METHOD_ @@ -1541,8 +1584,11 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent wd_window.transient_parent = INVALID_WINDOW_ID; wd_parent.transient_children.erase(p_window); - [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + + if (wd_window.exclusive) { + [wd_parent.window_object removeChildWindow:wd_window.window_object]; + } } else { ERR_FAIL_COND(!windows.has(p_parent)); ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent"); @@ -1550,8 +1596,11 @@ void DisplayServerOSX::window_set_transient(WindowID p_window, WindowID p_parent wd_window.transient_parent = p_parent; wd_parent.transient_children.insert(p_window); - [wd_window.window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary]; + + if (wd_window.exclusive) { + [wd_parent.window_object addChildWindow:wd_window.window_object ordered:NSWindowAbove]; + } } } @@ -1784,7 +1833,7 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } _update_window_style(wd); if ([wd.window_object isVisible]) { - if (wd.no_focus) { + if (wd.no_focus || wd.is_popup) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -1813,6 +1862,11 @@ void DisplayServerOSX::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo case WINDOW_FLAG_NO_FOCUS: { wd.no_focus = p_enabled; } break; + case WINDOW_FLAG_POPUP: { + ERR_FAIL_COND_MSG(p_window == MAIN_WINDOW_ID, "Main window can't be popup."); + ERR_FAIL_COND_MSG([wd.window_object isVisible] && (wd.is_popup != p_enabled), "Pupup flag can't changed while window is opened."); + wd.is_popup = p_enabled; + } break; default: { } } @@ -1844,6 +1898,9 @@ bool DisplayServerOSX::window_get_flag(WindowFlags p_flag, WindowID p_window) co case WINDOW_FLAG_NO_FOCUS: { return wd.no_focus; } break; + case WINDOW_FLAG_POPUP: { + return wd.is_popup; + } break; default: { } } @@ -1863,7 +1920,7 @@ void DisplayServerOSX::window_move_to_foreground(WindowID p_window) { const WindowData &wd = windows[p_window]; [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; - if (wd.no_focus) { + if (wd.no_focus || wd.is_popup) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -2421,6 +2478,120 @@ void DisplayServerOSX::register_osx_driver() { register_create_function("osx", create_func, get_rendering_drivers_func); } +DisplayServer::WindowID DisplayServerOSX::window_get_active_popup() const { + const List<WindowID>::Element *E = popup_list.back(); + if (E) { + return E->get(); + } else { + return INVALID_WINDOW_ID; + } +} + +void DisplayServerOSX::window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect) { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd = windows[p_window]; + wd.parent_safe_rect = p_rect; +} + +Rect2i DisplayServerOSX::window_get_popup_safe_rect(WindowID p_window) const { + _THREAD_SAFE_METHOD_ + + ERR_FAIL_COND_V(!windows.has(p_window), Rect2i()); + const WindowData &wd = windows[p_window]; + return wd.parent_safe_rect; +} + +void DisplayServerOSX::popup_open(WindowID p_window) { + WindowData &wd = windows[p_window]; + if (wd.is_popup) { + bool was_empty = popup_list.is_empty(); + // Close all popups, up to current popup parent, or every popup if new window is not transient. + List<WindowID>::Element *E = popup_list.back(); + while (E) { + if (wd.transient_parent != E->get() || wd.transient_parent == INVALID_WINDOW_ID) { + send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + List<WindowID>::Element *F = E->prev(); + popup_list.erase(E); + E = F; + } else { + break; + } + } + + if (was_empty && popup_list.is_empty()) { + // Inform OS that popup was opened, to close other native popups. + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.HIToolbox.beginMenuTrackingNotification" object:@"org.godotengine.godot.popup_window"]; + } + time_since_popup = OS::get_singleton()->get_ticks_msec(); + popup_list.push_back(p_window); + } +} + +void DisplayServerOSX::popup_close(WindowID p_window) { + bool was_empty = popup_list.is_empty(); + List<WindowID>::Element *E = popup_list.find(p_window); + while (E) { + send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + List<WindowID>::Element *F = E->next(); + popup_list.erase(E); + E = F; + } + if (!was_empty && popup_list.is_empty()) { + // Inform OS that all popups are closed. + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.HIToolbox.endMenuTrackingNotification" object:@"org.godotengine.godot.popup_window"]; + } +} + +void DisplayServerOSX::mouse_process_popups(bool p_close) { + _THREAD_SAFE_METHOD_ + + bool was_empty = popup_list.is_empty(); + if (p_close) { + // Close all popups. + List<WindowID>::Element *E = popup_list.front(); + while (E) { + send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + List<WindowID>::Element *F = E->next(); + popup_list.erase(E); + E = F; + } + if (!was_empty) { + // Inform OS that all popups are closed. + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.HIToolbox.endMenuTrackingNotification" object:@"org.godotengine.godot.popup_window"]; + } + } else { + uint64_t delta = OS::get_singleton()->get_ticks_msec() - time_since_popup; + if (delta < 250) { + return; + } + + Point2i pos = mouse_get_position(); + List<WindowID>::Element *E = popup_list.back(); + while (E) { + // Popup window area. + Rect2i win_rect = Rect2i(window_get_position(E->get()), window_get_size(E->get())); + // Area of the parent window, which responsible for opening sub-menu. + Rect2i safe_rect = window_get_popup_safe_rect(E->get()); + if (win_rect.has_point(pos)) { + break; + } else if (safe_rect != Rect2i() && safe_rect.has_point(pos)) { + break; + } else { + send_window_event(windows[E->get()], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST); + List<WindowID>::Element *F = E->prev(); + popup_list.erase(E); + E = F; + } + } + if (!was_empty && popup_list.is_empty()) { + // Inform OS that all popups are closed. + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.HIToolbox.endMenuTrackingNotification" object:@"org.godotengine.godot.popup_window"]; + } + } +} + DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); diff --git a/platform/osx/export/codesign.cpp b/platform/osx/export/codesign.cpp index 8ea6ff519d..1a2ad2bee6 100644 --- a/platform/osx/export/codesign.cpp +++ b/platform/osx/export/codesign.cpp @@ -35,7 +35,9 @@ #include "plist.h" #include "core/os/os.h" +#include "editor/editor_paths.h" #include "editor/editor_settings.h" + #include "modules/modules_enabled.gen.h" // For regex. #include <ctime> @@ -1359,9 +1361,12 @@ Error CodeSign::_codesign_file(bool p_use_hardened_runtime, bool p_force, const // Generate common signature structures. if (id.is_empty()) { - Ref<Crypto> crypto = Ref<Crypto>(Crypto::create()); - PackedByteArray uuid = crypto->generate_random_bytes(16); - id = (String("a-55554944") /*a-UUID*/ + String::hex_encode_buffer(uuid.ptr(), 16)); + CryptoCore::RandomGenerator rng; + ERR_FAIL_COND_V_MSG(rng.init(), FAILED, "Failed to initialize random number generator."); + uint8_t uuid[16]; + Error err = rng.get_random_bytes(uuid, 16); + ERR_FAIL_COND_V_MSG(err, err, "Failed to generate UUID."); + id = (String("a-55554944") /*a-UUID*/ + String::hex_encode_buffer(uuid, 16)); } CharString uuid_str = id.utf8(); print_verbose(vformat("CodeSign: Used bundle ID: %s", id)); diff --git a/platform/osx/export/codesign.h b/platform/osx/export/codesign.h index 927df79281..e5e9be5c28 100644 --- a/platform/osx/export/codesign.h +++ b/platform/osx/export/codesign.h @@ -41,7 +41,6 @@ #ifndef CODESIGN_H #define CODESIGN_H -#include "core/crypto/crypto.h" #include "core/crypto/crypto_core.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp index f0b58efb63..4d0fc9add6 100644 --- a/platform/osx/export/export_plugin.cpp +++ b/platform/osx/export/export_plugin.cpp @@ -28,10 +28,14 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "modules/modules_enabled.gen.h" // For regex. +#include "export_plugin.h" #include "codesign.h" -#include "export_plugin.h" + +#include "editor/editor_node.h" +#include "editor/editor_paths.h" + +#include "modules/modules_enabled.gen.h" // For regex. void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { if (p_preset->get("texture_format/s3tc")) { @@ -437,7 +441,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset print_line(TTR("Note: The notarization process generally takes less than an hour. When the process is completed, you'll receive an email.")); print_line(" " + TTR("You can check progress manually by opening a Terminal and running the following command:")); print_line(" \"xcrun altool --notarization-history 0 -u <your email> -p <app-specific pwd>\""); - print_line(" " + TTR("Run the following command to staple notarization ticket to the exported application (optional):")); + print_line(" " + TTR("Run the following command to staple the notarization ticket to the exported application (optional):")); print_line(" \"xcrun stapler staple <app path>\""); } @@ -783,6 +787,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p String fname = tmp_app_path_name + "/Contents/Resources/en.lproj"; tmp_app_dir->make_dir_recursive(fname); FileAccessRef f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE); + f->store_line("CFBundleDisplayName = \"" + ProjectSettings::get_singleton()->get("application/config/name").operator String() + "\";"); } for (const String &E : translations) { @@ -791,6 +796,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p String fname = tmp_app_path_name + "/Contents/Resources/" + tr->get_locale() + ".lproj"; tmp_app_dir->make_dir_recursive(fname); FileAccessRef f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE); + String prop = "application/config/name_" + tr->get_locale(); + if (ProjectSettings::get_singleton()->has_setting(prop)) { + f->store_line("CFBundleDisplayName = \"" + ProjectSettings::get_singleton()->get(prop).operator String() + "\";"); + } } } } @@ -822,7 +831,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (((info.external_fa >> 16L) & 0120000) == 0120000) { #ifndef UNIX_ENABLED - WARN_PRINT(vformat("Relative symlinks are not supported on this OS, exported project might be broken!")); + WARN_PRINT(vformat("Relative symlinks are not supported on this OS, the exported project might be broken!")); #endif // Handle symlinks in the archive. file = tmp_app_path_name.plus_file(file); @@ -1126,7 +1135,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p ad_hoc = (sign_identity == "" || sign_identity == "-"); bool lib_validation = p_preset->get("codesign/entitlements/disable_library_validation"); if ((!dylibs_found.is_empty() || !shared_objects.is_empty()) && sign_enabled && ad_hoc && !lib_validation) { - ERR_PRINT("Application with an ad-hoc signature require 'Disable Library Validation' entitlement to load dynamic libraries."); + ERR_PRINT("Ad-hoc signed applications require the 'Disable Library Validation' entitlement to load dynamic libraries."); err = ERR_CANT_CREATE; } } @@ -1205,7 +1214,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p bool noto_enabled = p_preset->get("notarization/enable"); if (err == OK && noto_enabled) { if (export_format == "app") { - WARN_PRINT("Notarization require app to be archived first, select DMG or ZIP export format instead."); + WARN_PRINT("Notarization requires the app to be archived first, select the DMG or ZIP export format instead."); } else { if (ep.step(TTR("Sending archive for notarization"), 4)) { return ERR_SKIP; @@ -1402,7 +1411,7 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset if (noto_enabled) { if (ad_hoc) { - err += TTR("Notarization: Notarization with the ad-hoc signature is not supported.") + "\n"; + err += TTR("Notarization: Notarization with an ad-hoc signature is not supported.") + "\n"; valid = false; } if (!sign_enabled) { @@ -1426,9 +1435,9 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset valid = false; } } else { - err += TTR("Warning: Notarization is disabled. Exported project will be blocked by Gatekeeper, if it's downloaded from an unknown source.") + "\n"; + err += TTR("Warning: Notarization is disabled. The exported project will be blocked by Gatekeeper if it's downloaded from an unknown source.") + "\n"; if (!sign_enabled) { - err += TTR("Code signing is disabled. Exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n"; + err += TTR("Code signing is disabled. The exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n"; } else { if ((bool)p_preset->get("codesign/hardened_runtime") && ad_hoc) { err += TTR("Hardened Runtime is not compatible with ad-hoc signature, and will be disabled!") + "\n"; @@ -1439,9 +1448,9 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset } } #else - err += TTR("Warning: Notarization is not supported on this OS. Exported project will be blocked by Gatekeeper, if it's downloaded from an unknown source.") + "\n"; + err += TTR("Warning: Notarization is not supported from this OS. The exported project will be blocked by Gatekeeper if it's downloaded from an unknown source.") + "\n"; if (!sign_enabled) { - err += TTR("Code signing is disabled. Exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n"; + err += TTR("Code signing is disabled. The exported project will not run on Macs with enabled Gatekeeper and Apple Silicon powered Macs.") + "\n"; } #endif diff --git a/platform/osx/export/export_plugin.h b/platform/osx/export/export_plugin.h index 931ce7e41a..b85e9d662c 100644 --- a/platform/osx/export/export_plugin.h +++ b/platform/osx/export/export_plugin.h @@ -40,7 +40,6 @@ #include "core/os/os.h" #include "core/version.h" #include "editor/editor_export.h" -#include "editor/editor_node.h" #include "editor/editor_settings.h" #include "platform/osx/logo.gen.h" diff --git a/platform/osx/godot_application_delegate.mm b/platform/osx/godot_application_delegate.mm index be284ba543..dc82075c44 100644 --- a/platform/osx/godot_application_delegate.mm +++ b/platform/osx/godot_application_delegate.mm @@ -68,6 +68,10 @@ } - (void)applicationDidResignActive:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->mouse_process_popups(true); + } if (OS::get_singleton()->get_main_loop()) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT); } diff --git a/platform/osx/godot_content_view.mm b/platform/osx/godot_content_view.mm index 4e831e1ccc..e96f0a8098 100644 --- a/platform/osx/godot_content_view.mm +++ b/platform/osx/godot_content_view.mm @@ -117,6 +117,10 @@ } } +- (void)doCommandBySelector:(SEL)aSelector { + [self tryToPerform:aSelector with:self]; +} + - (void)unmarkText { ime_input_event_in_progress = false; [[marked_text mutableString] setString:@""]; @@ -277,7 +281,7 @@ } DisplayServerOSX::WindowData &wd = ds->get_window(window_id); - return !wd.no_focus; + return !wd.no_focus && !wd.is_popup; } - (BOOL)acceptsFirstResponder { diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 7fabfaa1b7..f3db363151 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -49,7 +49,7 @@ int main(int argc, char **argv) { first_arg = i + 2; } printf("%i: %s\n", i, argv[i]); - }; + } #ifdef DEBUG_ENABLED // Lets report the path we made current after all that. @@ -84,4 +84,4 @@ int main(int argc, char **argv) { Main::cleanup(); return os.get_exit_code(); -}; +} diff --git a/platform/osx/godot_window.mm b/platform/osx/godot_window.mm index 772a2ddb9f..d43853a94b 100644 --- a/platform/osx/godot_window.mm +++ b/platform/osx/godot_window.mm @@ -52,7 +52,7 @@ } DisplayServerOSX::WindowData &wd = ds->get_window(window_id); - return !wd.no_focus; + return !wd.no_focus && !wd.is_popup; } - (BOOL)canBecomeMainWindow { @@ -63,7 +63,7 @@ } DisplayServerOSX::WindowData &wd = ds->get_window(window_id); - return !wd.no_focus; + return !wd.no_focus && !wd.is_popup; } @end diff --git a/platform/osx/godot_window_delegate.mm b/platform/osx/godot_window_delegate.mm index 1742be987d..9f49a6a4e9 100644 --- a/platform/osx/godot_window_delegate.mm +++ b/platform/osx/godot_window_delegate.mm @@ -54,6 +54,8 @@ return; } + ds->popup_close(window_id); + DisplayServerOSX::WindowData &wd = ds->get_window(window_id); while (wd.transient_children.size()) { ds->window_set_transient(wd.transient_children.front()->get(), DisplayServerOSX::INVALID_WINDOW_ID); @@ -147,6 +149,20 @@ } } +- (void)windowWillStartLiveResize:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->set_is_resizing(true); + } +} + +- (void)windowDidEndLiveResize:(NSNotification *)notification { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (ds) { + ds->set_is_resizing(false); + } +} + - (void)windowDidResize:(NSNotification *)notification { DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index d518206f04..7d31ede61d 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -322,10 +322,11 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) { // Bluetooth device. String guid = "05000000"; for (int i = 0; i < 12; i++) { - if (i < name.size()) + if (i < name.size()) { guid += _hex_str(name[i]); - else + } else { guid += "00"; + } } input->joy_connection_changed(id, true, name, guid); } @@ -381,8 +382,9 @@ bool joypad::check_ff_features() { if (ret == FF_OK && (features.supportedEffects & FFCAP_ET_CONSTANTFORCE)) { uint32_t val; ret = FFDeviceGetForceFeedbackProperty(ff_device, FFPROP_FFGAIN, &val, sizeof(val)); - if (ret != FF_OK) + if (ret != FF_OK) { return false; + } int num_axes = features.numFfAxes; ff_axes = (DWORD *)memalloc(sizeof(DWORD) * num_axes); ff_directions = (LONG *)memalloc(sizeof(LONG) * num_axes); @@ -509,16 +511,18 @@ void JoypadOSX::joypad_vibration_stop(int p_id, uint64_t p_timestamp) { int JoypadOSX::get_joy_index(int p_id) const { for (int i = 0; i < device_list.size(); i++) { - if (device_list[i].id == p_id) + if (device_list[i].id == p_id) { return i; + } } return -1; } int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const { for (int i = 0; i < device_list.size(); i++) { - if (device_list[i].device_ref == p_device) + if (device_list[i].device_ref == p_device) { return i; + } } return -1; } diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 5bb5b3320e..53c5c8bd90 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -102,6 +102,7 @@ public: virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override; virtual String get_unique_id() const override; + virtual String get_processor_name() const override; virtual bool _check_internal_feature_support(const String &p_feature) override; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 9288e658cf..7e0cf9f9cc 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -42,6 +42,8 @@ #include <dlfcn.h> #include <libproc.h> #include <mach-o/dyld.h> +#include <os/log.h> +#include <sys/sysctl.h> _FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) { // Append framework executable name, or return as is if p_path is not a framework. @@ -56,7 +58,8 @@ _FORCE_INLINE_ String OS_OSX::get_framework_executable(const String &p_path) { void OS_OSX::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopActivity p_activiy, void *p_context) { // Prevent main loop from sleeping and redraw window during resize / modal popups. - if (get_singleton()->get_main_loop()) { + DisplayServerOSX *ds = (DisplayServerOSX *)DisplayServer::get_singleton(); + if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD || !ds->get_is_resizing())) { Main::force_redraw(); if (!Main::is_iterating()) { // Avoid cyclic loop. Main::iteration(); @@ -72,6 +75,15 @@ void OS_OSX::initialize() { initialize_core(); } +String OS_OSX::get_processor_name() const { + char buffer[256]; + size_t buffer_len = 256; + if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, NULL, 0) == 0) { + return String::utf8(buffer, buffer_len); + } + ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string.")); +} + void OS_OSX::initialize_core() { OS_Unix::initialize_core(); @@ -430,7 +442,7 @@ void OS_OSX::run() { } @catch (NSException *exception) { ERR_PRINT("NSException: " + String::utf8([exception reason].UTF8String)); } - }; + } main_loop->finalize(); } diff --git a/platform/osx/osx_terminal_logger.mm b/platform/osx/osx_terminal_logger.mm index c1dca111a7..48e26f42bf 100644 --- a/platform/osx/osx_terminal_logger.mm +++ b/platform/osx/osx_terminal_logger.mm @@ -40,10 +40,11 @@ void OSXTerminalLogger::log_error(const char *p_function, const char *p_file, in } const char *err_details; - if (p_rationale && p_rationale[0]) + if (p_rationale && p_rationale[0]) { err_details = p_rationale; - else + } else { err_details = p_code; + } switch (p_type) { case ERR_WARNING: |