From 19954719278c612aa41055483a090ece37ad7e79 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 15 Jan 2025 09:36:55 -0800 Subject: [PATCH] cocoa: fixed resizing windows with fixed aspect ratio The existing algorithm works well for min-max ratios, but didn't allow edge expansion of fixed aspect ratio windows. Use NSWindow setContentAspectRatio instead. --- src/video/cocoa/SDL_cocoavideo.m | 1 + src/video/cocoa/SDL_cocoawindow.h | 1 + src/video/cocoa/SDL_cocoawindow.m | 21 ++++++++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index b9977c441b..aae54ebad8 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -103,6 +103,7 @@ static SDL_VideoDevice *Cocoa_CreateDevice(void) device->SetWindowSize = Cocoa_SetWindowSize; device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize; device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize; + device->SetWindowAspectRatio = Cocoa_SetWindowAspectRatio; device->SetWindowOpacity = Cocoa_SetWindowOpacity; device->GetWindowSizeInPixels = Cocoa_GetWindowSizeInPixels; device->ShowWindow = Cocoa_ShowWindow; diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index af567b8af2..6df69f442a 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -168,6 +168,7 @@ extern bool Cocoa_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window); extern void Cocoa_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window); extern void Cocoa_SetWindowMinimumSize(SDL_VideoDevice *_this, SDL_Window *window); extern void Cocoa_SetWindowMaximumSize(SDL_VideoDevice *_this, SDL_Window *window); +extern void Cocoa_SetWindowAspectRatio(SDL_VideoDevice *_this, SDL_Window *window); extern void Cocoa_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h); extern bool Cocoa_SetWindowOpacity(SDL_VideoDevice *_this, SDL_Window *window, float opacity); extern void Cocoa_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window); diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 947db1e976..daa544f7a4 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1109,7 +1109,7 @@ static NSCursor *Cocoa_GetDesiredCursor(void) { SDL_Window *window = _data.window; - if (window->min_aspect > 0.0f || window->max_aspect > 0.0f) { + if (window->min_aspect != window->max_aspect) { NSWindow *nswindow = _data.nswindow; NSRect newContentRect = [nswindow contentRectForFrameRect:NSMakeRect(0, 0, frameSize.width, frameSize.height)]; NSSize newSize = newContentRect.size; @@ -1121,9 +1121,9 @@ static NSCursor *Cocoa_GetDesiredCursor(void) aspectRatio = newSize.width / newSize.height; if (maxAspectRatio > 0.0f && aspectRatio > maxAspectRatio) { - newSize.width = (int)SDL_roundf(newSize.height * maxAspectRatio); + newSize.width = SDL_roundf(newSize.height * maxAspectRatio); } else if (minAspectRatio > 0.0f && aspectRatio < minAspectRatio) { - newSize.height = (int)SDL_roundf(newSize.width / minAspectRatio); + newSize.height = SDL_roundf(newSize.width / minAspectRatio); } NSRect newFrameRect = [nswindow frameRectForContentRect:NSMakeRect(0, 0, newSize.width, newSize.height)]; @@ -2515,6 +2515,21 @@ void Cocoa_SetWindowMaximumSize(SDL_VideoDevice *_this, SDL_Window *window) } } +void Cocoa_SetWindowAspectRatio(SDL_VideoDevice *_this, SDL_Window *window) +{ + @autoreleasepool { + SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)window->internal; + + if (window->min_aspect > 0.0f && window->min_aspect == window->max_aspect) { + int numerator = 0, denominator = 1; + SDL_CalculateFraction(window->max_aspect, &numerator, &denominator); + [windata.nswindow setContentAspectRatio:NSMakeSize(numerator, denominator)]; + } else { + [windata.nswindow setContentAspectRatio:NSMakeSize(0, 0)]; + } + } +} + void Cocoa_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h) { @autoreleasepool {