From 798a644dd56257cea2803d03fb49aa7118e7df41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Fri, 30 May 2025 00:13:53 +0300 Subject: [PATCH] [macOS] Fix borderless window maximization. --- platform/macos/display_server_macos.h | 3 ++- platform/macos/display_server_macos.mm | 19 +++++++++++++++++-- platform/macos/godot_window_delegate.mm | 10 ++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 72e08ceb9c5..33118963e69 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -111,7 +111,8 @@ public: Size2i size; Vector2i wb_offset = Vector2i(14, 14); - NSRect last_frame_rect; + NSRect last_frame_rect = NSMakeRect(0, 0, 0, 0); + NSRect pre_zoom_rect = NSMakeRect(0, 0, 0, 0); bool im_active = false; Size2i im_position; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 9ab14ffbca3..9892ee511cf 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -2537,7 +2537,13 @@ void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { } break; case WINDOW_MODE_MAXIMIZED: { if (NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { - [wd.window_object zoom:nil]; + if (wd.borderless) { + if (wd.pre_zoom_rect.size.width > 0 && wd.pre_zoom_rect.size.height > 0) { + [wd.window_object setFrame:wd.pre_zoom_rect display:NO animate:YES]; + } + } else { + [wd.window_object zoom:nil]; + } } } break; } @@ -2570,7 +2576,12 @@ void DisplayServerMacOS::window_set_mode(WindowMode p_mode, WindowID p_window) { } break; case WINDOW_MODE_MAXIMIZED: { if (!NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { - [wd.window_object zoom:nil]; + wd.pre_zoom_rect = [wd.window_object frame]; + if (wd.borderless) { + [wd.window_object setFrame:[[wd.window_object screen] visibleFrame] display:NO animate:YES]; + } else { + [wd.window_object zoom:nil]; + } } } break; } @@ -2770,6 +2781,7 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win [wd.window_object orderOut:nil]; } wd.borderless = p_enabled; + bool was_maximized = (NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])); if (p_enabled) { [wd.window_object setStyleMask:NSWindowStyleMaskBorderless]; [wd.window_object setHasShadow:NO]; @@ -2800,6 +2812,9 @@ void DisplayServerMacOS::window_set_flag(WindowFlags p_flag, bool p_enabled, Win [wd.window_object makeKeyAndOrderFront:nil]; } } + if (was_maximized) { + [wd.window_object setFrame:[[wd.window_object screen] visibleFrame] display:NO]; + } } break; case WINDOW_FLAG_ALWAYS_ON_TOP: { wd.on_top = p_enabled; diff --git a/platform/macos/godot_window_delegate.mm b/platform/macos/godot_window_delegate.mm index 8c105c375d8..4d7ffe9331c 100644 --- a/platform/macos/godot_window_delegate.mm +++ b/platform/macos/godot_window_delegate.mm @@ -208,6 +208,16 @@ [self windowDidResize:notification]; } +- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame { + if (ds->has_window(window_id)) { + DisplayServerMacOS::WindowData &wd = ds->get_window(window_id); + if (!wd.borderless && !(NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame]))) { + wd.pre_zoom_rect = [wd.window_object frame]; + } + } + return YES; +} + - (void)windowDidChangeBackingProperties:(NSNotification *)notification { if (!ds->has_window(window_id)) { return;