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
This commit is contained in:
Sam Lantinga 2025-02-21 17:59:48 -08:00
parent b5297de56f
commit fcd41c1d2c
1 changed files with 41 additions and 27 deletions

View File

@ -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 typedef enum CocoaMenuVisibility
{ {
COCOA_MENU_VISIBILITY_AUTO = 0, COCOA_MENU_VISIBILITY_AUTO = 0,
@ -1172,7 +1193,7 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
} }
if (!zoomed) { if (!zoomed) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0); SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
} else if (zoomed) { } else {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0); SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
if ([self windowOperationIsPending:PENDING_OPERATION_MINIMIZE]) { if ([self windowOperationIsPending:PENDING_OPERATION_MINIMIZE]) {
[nswindow miniaturize:nil]; [nswindow miniaturize:nil];
@ -1208,8 +1229,7 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
// Always send restored before maximized. // Always send restored before maximized.
SDL_SendWindowEvent(_data.window, SDL_EVENT_WINDOW_RESTORED, 0, 0); SDL_SendWindowEvent(_data.window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
// isZoomed always returns true if the window is not resizable. if (Cocoa_IsWindowZoomed(_data.window)) {
if ((_data.window->flags & SDL_WINDOW_RESIZABLE) && [_data.nswindow isZoomed]) {
SDL_SendWindowEvent(_data.window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0); SDL_SendWindowEvent(_data.window, SDL_EVENT_WINDOW_MAXIMIZED, 0, 0);
} }
@ -2469,9 +2489,7 @@ void Cocoa_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
return; return;
} }
// isZoomed always returns true if the window is not resizable if (!Cocoa_IsWindowZoomed(window)) {
if (!(window->flags & SDL_WINDOW_RESIZABLE) || ![nswindow isZoomed]) {
if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
int x, y; int x, y;
NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
@ -2492,10 +2510,6 @@ void Cocoa_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
// Can't set the window size. // Can't set the window size.
window->last_size_pending = false; window->last_size_pending = false;
} }
} 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]) { ![data.listener isInFullscreenSpace]) {
if ([nswindow isMiniaturized]) { if ([nswindow isMiniaturized]) {
[nswindow deminiaturize:nil]; [nswindow deminiaturize:nil];
} else if ((window->flags & SDL_WINDOW_RESIZABLE) && [data.nswindow isZoomed]) { } else if (Cocoa_IsWindowZoomed(window)) {
[nswindow zoom:nil]; [nswindow zoom:nil];
} }
} else if (data.was_zoomed) { } else if (data.was_zoomed) {