summaryrefslogtreecommitdiff
path: root/platform/macos
diff options
context:
space:
mode:
Diffstat (limited to 'platform/macos')
-rw-r--r--platform/macos/display_server_macos.mm31
-rw-r--r--platform/macos/godot_button_view.h3
-rw-r--r--platform/macos/godot_button_view.mm23
-rw-r--r--platform/macos/godot_window.h2
-rw-r--r--platform/macos/godot_window.mm13
-rw-r--r--platform/macos/godot_window_delegate.h2
-rw-r--r--platform/macos/godot_window_delegate.mm56
7 files changed, 103 insertions, 27 deletions
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 004bb7dcd1..34723c7d4b 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -2664,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) {
@@ -2687,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];
@@ -2695,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];
@@ -2741,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.
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];