diff options
Diffstat (limited to 'platform/macos')
-rw-r--r-- | platform/macos/detect.py | 4 | ||||
-rw-r--r-- | platform/macos/display_server_macos.h | 6 | ||||
-rw-r--r-- | platform/macos/display_server_macos.mm | 67 | ||||
-rw-r--r-- | platform/macos/export/codesign.h | 6 | ||||
-rw-r--r-- | platform/macos/export/lipo.h | 4 | ||||
-rw-r--r-- | platform/macos/export/macho.h | 4 | ||||
-rw-r--r-- | platform/macos/export/plist.h | 4 | ||||
-rw-r--r-- | platform/macos/godot_button_view.h | 3 | ||||
-rw-r--r-- | platform/macos/godot_button_view.mm | 23 | ||||
-rw-r--r-- | platform/macos/godot_window.h | 2 | ||||
-rw-r--r-- | platform/macos/godot_window.mm | 13 | ||||
-rw-r--r-- | platform/macos/godot_window_delegate.h | 2 | ||||
-rw-r--r-- | platform/macos/godot_window_delegate.mm | 56 |
13 files changed, 149 insertions, 45 deletions
diff --git a/platform/macos/detect.py b/platform/macos/detect.py index 834ac935d8..58d9c0e99f 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -88,9 +88,9 @@ def configure(env): if env["target"] == "release": if env["optimize"] == "speed": # optimize for speed (default) - env.Prepend(CCFLAGS=["-O3", "-fomit-frame-pointer", "-ftree-vectorize"]) + env.Prepend(CCFLAGS=["-O3"]) elif env["optimize"] == "size": # optimize for size - env.Prepend(CCFLAGS=["-Os", "-ftree-vectorize"]) + env.Prepend(CCFLAGS=["-Os"]) if env["arch"] != "arm64": env.Prepend(CCFLAGS=["-msse2"]) diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index a27e0d5efa..e72273a681 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -179,6 +179,12 @@ private: IOPMAssertionID screen_keep_on_assertion = kIOPMNullAssertionID; + struct MenuCall { + Variant tag; + Callable callback; + }; + Vector<MenuCall> deferred_menu_calls; + const NSMenu *_get_menu_root(const String &p_menu_root) const; NSMenu *_get_menu_root(const String &p_menu_root); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index e1d0d99165..1914c5f35d 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -565,11 +565,11 @@ void DisplayServerMacOS::menu_callback(id p_sender) { } if (value->callback != Callable()) { - Variant tag = value->meta; - Variant *tagp = &tag; - Variant ret; - Callable::CallError ce; - value->callback.callp((const Variant **)&tagp, 1, ret, ce); + MenuCall mc; + mc.tag = value->meta; + mc.callback = value->callback; + deferred_menu_calls.push_back(mc); + // Do not run callback from here! If it is opening a new window or calling process_events, it will corrupt OS event queue and crash. } } } @@ -2213,7 +2213,9 @@ void DisplayServerMacOS::show_window(WindowID p_id) { WindowData &wd = windows[p_id]; popup_open(p_id); - if (wd.no_focus || wd.is_popup) { + if ([wd.window_object isMiniaturized]) { + return; + } else if (wd.no_focus || wd.is_popup) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -2370,6 +2372,10 @@ void DisplayServerMacOS::window_set_position(const Point2i &p_position, WindowID ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; + if ([wd.window_object isZoomed]) { + return; + } + Point2i position = p_position; // OS X native y-coordinate relative to _get_screens_origin() is negative, // Godot passes a positive value. @@ -2494,6 +2500,10 @@ void DisplayServerMacOS::window_set_size(const Size2i p_size, WindowID p_window) ERR_FAIL_COND(!windows.has(p_window)); WindowData &wd = windows[p_window]; + if ([wd.window_object isZoomed]) { + return; + } + Size2i size = p_size / screen_get_max_scale(); NSPoint top_left; @@ -2654,21 +2664,17 @@ Vector2i DisplayServerMacOS::window_get_safe_title_margins(WindowID p_window) co ERR_FAIL_COND_V(!windows.has(p_window), Vector2i()); const WindowData &wd = windows[p_window]; - float max_x = 0.f; - NSButton *cb = [wd.window_object standardWindowButton:NSWindowCloseButton]; - if (cb) { - max_x = MAX(max_x, [cb frame].origin.x + [cb frame].size.width); - } - NSButton *mb = [wd.window_object standardWindowButton:NSWindowMiniaturizeButton]; - if (mb) { - max_x = MAX(max_x, [mb frame].origin.x + [mb frame].size.width); - } - NSButton *zb = [wd.window_object standardWindowButton:NSWindowZoomButton]; - if (zb) { - max_x = MAX(max_x, [zb frame].origin.x + [zb frame].size.width); + if (!wd.window_button_view) { + return Vector2i(); } - return Vector2i(max_x * screen_get_max_scale(), 0); + float max_x = wd.wb_offset.x + [wd.window_button_view frame].size.width; + + if ([wd.window_object windowTitlebarLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft) { + return Vector2i(0, max_x * screen_get_max_scale()); + } else { + return Vector2i(max_x * screen_get_max_scale(), 0); + } } void DisplayServerMacOS::window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled) { @@ -2677,7 +2683,11 @@ void DisplayServerMacOS::window_set_custom_window_buttons(WindowData &p_wd, bool p_wd.window_button_view = nil; } if (p_enabled) { - float window_buttons_spacing = NSMinX([[p_wd.window_object standardWindowButton:NSWindowMiniaturizeButton] frame]) - NSMinX([[p_wd.window_object standardWindowButton:NSWindowCloseButton] frame]); + float cb_frame = NSMinX([[p_wd.window_object standardWindowButton:NSWindowCloseButton] frame]); + float mb_frame = NSMinX([[p_wd.window_object standardWindowButton:NSWindowMiniaturizeButton] frame]); + bool is_rtl = ([p_wd.window_object windowTitlebarLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft); + + float window_buttons_spacing = (is_rtl) ? (cb_frame - mb_frame) : (mb_frame - cb_frame); [p_wd.window_object setTitleVisibility:NSWindowTitleHidden]; [[p_wd.window_object standardWindowButton:NSWindowZoomButton] setHidden:YES]; @@ -2685,7 +2695,7 @@ void DisplayServerMacOS::window_set_custom_window_buttons(WindowData &p_wd, bool [[p_wd.window_object standardWindowButton:NSWindowCloseButton] setHidden:YES]; p_wd.window_button_view = [[GodotButtonView alloc] initWithFrame:NSZeroRect]; - [p_wd.window_button_view initButtons:window_buttons_spacing offset:NSMakePoint(p_wd.wb_offset.x, p_wd.wb_offset.y)]; + [p_wd.window_button_view initButtons:window_buttons_spacing offset:NSMakePoint(p_wd.wb_offset.x, p_wd.wb_offset.y) rtl:is_rtl]; [p_wd.window_view addSubview:p_wd.window_button_view]; } else { [p_wd.window_object setTitleVisibility:NSWindowTitleVisible]; @@ -2731,6 +2741,7 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win } } [wd.window_object setFrame:rect display:YES]; + send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); } break; case WINDOW_FLAG_BORDERLESS: { // OrderOut prevents a lose focus bug with the window. @@ -2750,7 +2761,9 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win } _update_window_style(wd); if ([wd.window_object isVisible]) { - if (wd.no_focus || wd.is_popup) { + if ([wd.window_object isMiniaturized]) { + return; + } else if (wd.no_focus || wd.is_popup) { [wd.window_object orderFront:nil]; } else { [wd.window_object makeKeyAndOrderFront:nil]; @@ -3267,6 +3280,16 @@ void DisplayServerMacOS::process_events() { [NSApp sendEvent:event]; } + // Process "menu_callback"s. + for (MenuCall &E : deferred_menu_calls) { + Variant tag = E.tag; + Variant *tagp = &tag; + Variant ret; + Callable::CallError ce; + E.callback.callp((const Variant **)&tagp, 1, ret, ce); + } + deferred_menu_calls.clear(); + if (!drop_events) { _process_key_events(); Input::get_singleton()->flush_buffered_events(); diff --git a/platform/macos/export/codesign.h b/platform/macos/export/codesign.h index fea7b117d0..01e97bca81 100644 --- a/platform/macos/export/codesign.h +++ b/platform/macos/export/codesign.h @@ -28,6 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#ifndef MACOS_CODESIGN_H +#define MACOS_CODESIGN_H + // macOS code signature creation utility. // // Current implementation has the following limitation: @@ -38,9 +41,6 @@ // - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported). // - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only. -#ifndef MACOS_CODESIGN_H -#define MACOS_CODESIGN_H - #include "core/crypto/crypto_core.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" diff --git a/platform/macos/export/lipo.h b/platform/macos/export/lipo.h index 516ef99860..6378f9899c 100644 --- a/platform/macos/export/lipo.h +++ b/platform/macos/export/lipo.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Universal / Universal 2 fat binary file creator and extractor. - #ifndef MACOS_LIPO_H #define MACOS_LIPO_H +// Universal / Universal 2 fat binary file creator and extractor. + #include "core/io/file_access.h" #include "core/object/ref_counted.h" #include "modules/modules_enabled.gen.h" // For regex. diff --git a/platform/macos/export/macho.h b/platform/macos/export/macho.h index 7ef0d9067e..0d42a7013f 100644 --- a/platform/macos/export/macho.h +++ b/platform/macos/export/macho.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Mach-O binary object file format parser and editor. - #ifndef MACOS_MACHO_H #define MACOS_MACHO_H +// Mach-O binary object file format parser and editor. + #include "core/crypto/crypto.h" #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" diff --git a/platform/macos/export/plist.h b/platform/macos/export/plist.h index 79cb928d0a..b3c51a9635 100644 --- a/platform/macos/export/plist.h +++ b/platform/macos/export/plist.h @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -// Property list file format (application/x-plist) parser, property list ASN-1 serialization. - #ifndef MACOS_PLIST_H #define MACOS_PLIST_H +// Property list file format (application/x-plist) parser, property list ASN-1 serialization. + #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" #include "modules/modules_enabled.gen.h" // For regex. diff --git a/platform/macos/godot_button_view.h b/platform/macos/godot_button_view.h index e41910878d..e7627a9e9b 100644 --- a/platform/macos/godot_button_view.h +++ b/platform/macos/godot_button_view.h @@ -41,9 +41,10 @@ NSPoint offset; CGFloat spacing; bool mouse_in_group; + bool rtl; } -- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset; +- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset rtl:(bool)is_rtl; - (void)displayButtons; @end diff --git a/platform/macos/godot_button_view.mm b/platform/macos/godot_button_view.mm index ae04c02bd5..9106f0b0db 100644 --- a/platform/macos/godot_button_view.mm +++ b/platform/macos/godot_button_view.mm @@ -39,15 +39,17 @@ offset = NSMakePoint(8, 8); spacing = 20; mouse_in_group = false; + rtl = false; return self; } -- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset { +- (void)initButtons:(CGFloat)button_spacing offset:(NSPoint)button_offset rtl:(bool)is_rtl { spacing = button_spacing; + rtl = is_rtl; NSButton *close_button = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:NSWindowStyleMaskTitled]; - [close_button setFrameOrigin:NSMakePoint(0, 0)]; + [close_button setFrameOrigin:NSMakePoint(rtl ? spacing * 2 : 0, 0)]; [self addSubview:close_button]; NSButton *miniaturize_button = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:NSWindowStyleMaskTitled]; @@ -55,13 +57,17 @@ [self addSubview:miniaturize_button]; NSButton *zoom_button = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:NSWindowStyleMaskTitled]; - [zoom_button setFrameOrigin:NSMakePoint(spacing * 2, 0)]; + [zoom_button setFrameOrigin:NSMakePoint(rtl ? 0 : spacing * 2, 0)]; [self addSubview:zoom_button]; offset.y = button_offset.y - zoom_button.frame.size.height / 2; offset.x = button_offset.x - zoom_button.frame.size.width / 2; - [self setFrameSize:NSMakeSize(zoom_button.frame.origin.x + zoom_button.frame.size.width, zoom_button.frame.size.height)]; + if (rtl) { + [self setFrameSize:NSMakeSize(close_button.frame.origin.x + close_button.frame.size.width, close_button.frame.size.height)]; + } else { + [self setFrameSize:NSMakeSize(zoom_button.frame.origin.x + zoom_button.frame.size.width, zoom_button.frame.size.height)]; + } [self displayButtons]; } @@ -70,8 +76,13 @@ return; } - [self setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; - [self setFrameOrigin:NSMakePoint(offset.x, self.window.frame.size.height - self.frame.size.height - offset.y)]; + if (rtl) { + [self setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; + [self setFrameOrigin:NSMakePoint(self.window.frame.size.width - self.frame.size.width - offset.x, self.window.frame.size.height - self.frame.size.height - offset.y)]; + } else { + [self setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin]; + [self setFrameOrigin:NSMakePoint(offset.x, self.window.frame.size.height - self.frame.size.height - offset.y)]; + } } - (BOOL)_mouseInGroup:(NSButton *)button { diff --git a/platform/macos/godot_window.h b/platform/macos/godot_window.h index 9fc5599e86..d3653fda82 100644 --- a/platform/macos/godot_window.h +++ b/platform/macos/godot_window.h @@ -38,9 +38,11 @@ @interface GodotWindow : NSWindow { DisplayServer::WindowID window_id; + NSTimeInterval anim_duration; } - (void)setWindowID:(DisplayServer::WindowID)wid; +- (void)setAnimDuration:(NSTimeInterval)duration; @end diff --git a/platform/macos/godot_window.mm b/platform/macos/godot_window.mm index e205e7546d..bc51da4f72 100644 --- a/platform/macos/godot_window.mm +++ b/platform/macos/godot_window.mm @@ -37,9 +37,22 @@ - (id)init { self = [super init]; window_id = DisplayServer::INVALID_WINDOW_ID; + anim_duration = -1.0f; return self; } +- (void)setAnimDuration:(NSTimeInterval)duration { + anim_duration = duration; +} + +- (NSTimeInterval)animationResizeTime:(NSRect)newFrame { + if (anim_duration > 0) { + return anim_duration; + } else { + return [super animationResizeTime:newFrame]; + } +} + - (void)setWindowID:(DisplayServerMacOS::WindowID)wid { window_id = wid; } diff --git a/platform/macos/godot_window_delegate.h b/platform/macos/godot_window_delegate.h index 98c226aa2f..01cc13a016 100644 --- a/platform/macos/godot_window_delegate.h +++ b/platform/macos/godot_window_delegate.h @@ -38,6 +38,8 @@ @interface GodotWindowDelegate : NSObject <NSWindowDelegate> { DisplayServer::WindowID window_id; + NSRect old_frame; + NSWindowStyleMask old_style_mask; } - (void)setWindowID:(DisplayServer::WindowID)wid; diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index 94d40924b2..279fd2a359 100644 --- a/platform/macos/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -32,6 +32,7 @@ #include "display_server_macos.h" #include "godot_button_view.h" +#include "godot_window.h" @implementation GodotWindowDelegate @@ -69,6 +70,26 @@ ds->window_destroy(window_id); } +- (NSArray<NSWindow *> *)customWindowsToEnterFullScreenForWindow:(NSWindow *)window { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return nullptr; + } + + old_frame = [window frame]; + old_style_mask = [window styleMask]; + + NSMutableArray<NSWindow *> *windows = [[NSMutableArray alloc] init]; + [windows addObject:window]; + + return windows; +} + +- (void)window:(NSWindow *)window startCustomAnimationToEnterFullScreenWithDuration:(NSTimeInterval)duration { + [(GodotWindow *)window setAnimDuration:duration]; + [window setFrame:[[window screen] frame] display:YES animate:YES]; +} + - (void)windowDidEnterFullScreen:(NSNotification *)notification { DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds || !ds->has_window(window_id)) { @@ -81,6 +102,7 @@ // Reset window size limits. [wd.window_object setContentMinSize:NSMakeSize(0, 0)]; [wd.window_object setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; + [(GodotWindow *)wd.window_object setAnimDuration:-1.0f]; // Reset custom window buttons. if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) { @@ -89,6 +111,33 @@ // Force window resize event. [self windowDidResize:notification]; + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); +} + +- (NSArray<NSWindow *> *)customWindowsToExitFullScreenForWindow:(NSWindow *)window { + DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); + if (!ds || !ds->has_window(window_id)) { + return nullptr; + } + + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + + // Restore custom window buttons. + if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) { + ds->window_set_custom_window_buttons(wd, true); + } + + ds->send_window_event(wd, DisplayServerMacOS::WINDOW_EVENT_TITLEBAR_CHANGE); + + NSMutableArray<NSWindow *> *windows = [[NSMutableArray alloc] init]; + [windows addObject:wd.window_object]; + return windows; +} + +- (void)window:(NSWindow *)window startCustomAnimationToExitFullScreenWithDuration:(NSTimeInterval)duration { + [(GodotWindow *)window setAnimDuration:duration]; + [window setStyleMask:old_style_mask]; + [window setFrame:old_frame display:YES animate:YES]; } - (void)windowDidExitFullScreen:(NSNotification *)notification { @@ -100,6 +149,8 @@ DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); wd.fullscreen = false; + [(GodotWindow *)wd.window_object setAnimDuration:-1.0f]; + // Set window size limits. const float scale = ds->screen_get_max_scale(); if (wd.min_size != Size2i()) { @@ -111,11 +162,6 @@ [wd.window_object setContentMaxSize:NSMakeSize(size.x, size.y)]; } - // Restore custom window buttons. - if ([wd.window_object styleMask] & NSWindowStyleMaskFullSizeContentView) { - ds->window_set_custom_window_buttons(wd, true); - } - // Restore resizability state. if (wd.resize_disabled) { [wd.window_object setStyleMask:[wd.window_object styleMask] & ~NSWindowStyleMaskResizable]; |