From fcd41c1d2c89f46b59fe379aa93ad7f9007db519 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 21 Feb 2025 17:59:48 -0800
Subject: [PATCH] Check desired window area when checking zoom state
isZoomed returns true if the window has the size and position that it would if it were maximized, so we need to check to see if our floating state matches that before saying we're zoomed.
This fixes calling zoom:nil on a borderless resizable window that was created with the same size as the usable desktop area, which happens to also be the maximized state.
Fixes https://github.com/libsdl-org/SDL/issues/12228
---
src/video/cocoa/SDL_cocoawindow.m | 68 +++++++++++++++++++------------
1 file changed, 41 insertions(+), 27 deletions(-)
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 06ba56ad4dd19..c49047b84454e 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -411,6 +411,27 @@ bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window)
}
}
+bool Cocoa_IsWindowZoomed(SDL_Window *window)
+{
+ SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
+ NSWindow *nswindow = data.nswindow;
+ bool zoomed = false;
+
+ // isZoomed always returns true if the window is not resizable or the window is fullscreen
+ if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed] &&
+ !(window->flags & SDL_WINDOW_FULLSCREEN) && !Cocoa_IsWindowInFullscreenSpace(window)) {
+ // If we are at our desired floating area, then we're not zoomed
+ bool floating = (window->x == window->floating.x &&
+ window->y == window->floating.y &&
+ window->w == window->floating.w &&
+ window->h == window->floating.h);
+ if (!floating) {
+ zoomed = true;
+ }
+ }
+ return zoomed;
+}
+
typedef enum CocoaMenuVisibility
{
COCOA_MENU_VISIBILITY_AUTO = 0,
@@ -692,7 +713,7 @@ static void Cocoa_SetKeyboardFocus(SDL_Window *window, bool set_active_focus)
toplevel_data.keyboard_focus = window;
if (set_active_focus && !window->is_hiding && !window->is_destroying) {
- SDL_SetKeyboardFocus(window);
+ SDL_SetKeyboardFocus(window);
}
}
@@ -1172,7 +1193,7 @@ - (void)windowDidResize:(NSNotification *)aNotification
}
if (!zoomed) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
- } else if (zoomed) {
+ } else {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
if ([self windowOperationIsPending:PENDING_OPERATION_MINIMIZE]) {
[nswindow miniaturize:nil];
@@ -1208,8 +1229,7 @@ - (void)windowDidDeminiaturize:(NSNotification *)aNotification
// Always send restored before maximized.
SDL_SendWindowEvent(_data.window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
- // isZoomed always returns true if the window is not resizable.
- if ((_data.window->flags & SDL_WINDOW_RESIZABLE) && [_data.nswindow isZoomed]) {
+ if (Cocoa_IsWindowZoomed(_data.window)) {
SDL_SendWindowEvent(_data.window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
}
@@ -2469,30 +2489,24 @@ void Cocoa_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
return;
}
- // isZoomed always returns true if the window is not resizable
- if (!(window->flags & SDL_WINDOW_RESIZABLE) || ![nswindow isZoomed]) {
- if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
- int x, y;
- NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
+ if (!Cocoa_IsWindowZoomed(window)) {
+ int x, y;
+ NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
- /* Cocoa will resize the window from the bottom-left rather than the
- * top-left when -[nswindow setContentSize:] is used, so we must set the
- * entire frame based on the new size, in order to preserve the position.
- */
- SDL_RelativeToGlobalForWindow(window, window->floating.x, window->floating.y, &x, &y);
- rect.origin.x = x;
- rect.origin.y = y;
- rect.size.width = window->pending.w;
- rect.size.height = window->pending.h;
- ConvertNSRect(&rect);
+ /* Cocoa will resize the window from the bottom-left rather than the
+ * top-left when -[nswindow setContentSize:] is used, so we must set the
+ * entire frame based on the new size, in order to preserve the position.
+ */
+ SDL_RelativeToGlobalForWindow(window, window->floating.x, window->floating.y, &x, &y);
+ rect.origin.x = x;
+ rect.origin.y = y;
+ rect.size.width = window->pending.w;
+ rect.size.height = window->pending.h;
+ ConvertNSRect(&rect);
- [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
- ScheduleContextUpdates(windata);
- } else {
- // Can't set the window size.
- window->last_size_pending = false;
- }
- } else {
+ [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
+ ScheduleContextUpdates(windata);
+ } else {
// Can't set the window size.
window->last_size_pending = false;
}
@@ -2741,7 +2755,7 @@ void Cocoa_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
![data.listener isInFullscreenSpace]) {
if ([nswindow isMiniaturized]) {
[nswindow deminiaturize:nil];
- } else if ((window->flags & SDL_WINDOW_RESIZABLE) && [data.nswindow isZoomed]) {
+ } else if (Cocoa_IsWindowZoomed(window)) {
[nswindow zoom:nil];
}
} else if (data.was_zoomed) {