From 19954719278c612aa41055483a090ece37ad7e79 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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 b9977c441bc91..aae54ebad8d96 100644
--- a/src/video/cocoa/SDL_cocoavideo.m
+++ b/src/video/cocoa/SDL_cocoavideo.m
@@ -103,6 +103,7 @@ static void Cocoa_DeleteDevice(SDL_VideoDevice *device)
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 af567b8af2899..6df69f442a080 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 947db1e976c42..daa544f7a43c0 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -1109,7 +1109,7 @@ - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
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 @@ - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
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 {