Browse Source

cocoa: Fix the window position when resizing

Cocoa will resize the window from the bottom-left instead of the top-left, so the position must be preserved when setting the new size.
Frank Praznik 1 year ago
parent
commit
87374af0a5
1 changed files with 23 additions and 21 deletions
  1. 23 21
      src/video/cocoa/SDL_cocoawindow.m

+ 23 - 21
src/video/cocoa/SDL_cocoawindow.m

@@ -332,7 +332,7 @@ static NSScreen *ScreenForRect(const NSRect *rect)
     return ScreenForPoint(&center);
     return ScreenForPoint(&center);
 }
 }
 
 
-static void ConvertNSRect(BOOL fullscreen, NSRect *r)
+static void ConvertNSRect(NSRect *r)
 {
 {
     r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
     r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
 }
 }
@@ -943,9 +943,8 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
     int x, y;
     int x, y;
     SDL_Window *window = _data.window;
     SDL_Window *window = _data.window;
     NSWindow *nswindow = _data.nswindow;
     NSWindow *nswindow = _data.nswindow;
-    BOOL fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN) ? YES : NO;
     NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
     NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
-    ConvertNSRect(fullscreen, &rect);
+    ConvertNSRect(&rect);
 
 
     if (inFullscreenTransition || b_inModeTransition) {
     if (inFullscreenTransition || b_inModeTransition) {
         /* We'll take care of this at the end of the transition */
         /* We'll take care of this at the end of the transition */
@@ -980,7 +979,7 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
             rect.origin.y = window->floating.y;
             rect.origin.y = window->floating.y;
             rect.size.width = window->floating.w;
             rect.size.width = window->floating.w;
             rect.size.height = window->floating.h;
             rect.size.height = window->floating.h;
-            ConvertNSRect(SDL_FALSE, &rect);
+            ConvertNSRect(&rect);
 
 
             frameSize = rect.size;
             frameSize = rect.size;
         }
         }
@@ -997,7 +996,6 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
     NSRect rect;
     NSRect rect;
     int x, y, w, h;
     int x, y, w, h;
     BOOL zoomed;
     BOOL zoomed;
-    BOOL fullscreen;
 
 
     if (inFullscreenTransition || b_inModeTransition) {
     if (inFullscreenTransition || b_inModeTransition) {
         /* We'll take care of this at the end of the transition */
         /* We'll take care of this at the end of the transition */
@@ -1011,8 +1009,7 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
     window = _data.window;
     window = _data.window;
     nswindow = _data.nswindow;
     nswindow = _data.nswindow;
     rect = [nswindow contentRectForFrameRect:[nswindow frame]];
     rect = [nswindow contentRectForFrameRect:[nswindow frame]];
-    fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN) ? YES : NO;
-    ConvertNSRect(fullscreen, &rect);
+    ConvertNSRect(&rect);
     x = (int)rect.origin.x;
     x = (int)rect.origin.x;
     y = (int)rect.origin.y;
     y = (int)rect.origin.y;
     w = (int)rect.size.width;
     w = (int)rect.size.width;
@@ -1337,7 +1334,7 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
         rect.origin.y = _data.was_zoomed ? window->windowed.y : window->floating.y;
         rect.origin.y = _data.was_zoomed ? window->windowed.y : window->floating.y;
         rect.size.width = _data.was_zoomed ? window->windowed.w : window->floating.w;
         rect.size.width = _data.was_zoomed ? window->windowed.w : window->floating.w;
         rect.size.height = _data.was_zoomed ? window->windowed.h : window->floating.h;
         rect.size.height = _data.was_zoomed ? window->windowed.h : window->floating.h;
-        ConvertNSRect(NO, &rect);
+        ConvertNSRect(&rect);
 
 
         _data.send_floating_position = NO;
         _data.send_floating_position = NO;
         _data.send_floating_size = NO;
         _data.send_floating_size = NO;
@@ -1934,8 +1931,7 @@ static int SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, NSWindow
         {
         {
             int x, y;
             int x, y;
             NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
             NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
-            BOOL fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN) ? YES : NO;
-            ConvertNSRect(fullscreen, &rect);
+            ConvertNSRect(&rect);
             SDL_GlobalToRelativeForWindow(window, (int)rect.origin.x, (int)rect.origin.y, &x, &y);
             SDL_GlobalToRelativeForWindow(window, (int)rect.origin.x, (int)rect.origin.y, &x, &y);
             window->x = x;
             window->x = x;
             window->y = y;
             window->y = y;
@@ -2078,7 +2074,6 @@ int Cocoa_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Propertie
             int x, y;
             int x, y;
             NSScreen *screen;
             NSScreen *screen;
             NSRect rect, screenRect;
             NSRect rect, screenRect;
-            BOOL fullscreen;
             NSUInteger style;
             NSUInteger style;
             SDLView *contentView;
             SDLView *contentView;
 
 
@@ -2087,8 +2082,7 @@ int Cocoa_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_Propertie
             rect.origin.y = y;
             rect.origin.y = y;
             rect.size.width = window->w;
             rect.size.width = window->w;
             rect.size.height = window->h;
             rect.size.height = window->h;
-            fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN) ? YES : NO;
-            ConvertNSRect(fullscreen, &rect);
+            ConvertNSRect(&rect);
 
 
             style = GetWindowStyle(window);
             style = GetWindowStyle(window);
 
 
@@ -2258,7 +2252,7 @@ int Cocoa_SetWindowPosition(SDL_VideoDevice *_this, SDL_Window *window)
                 rect.origin.x = x;
                 rect.origin.x = x;
                 rect.origin.y = y;
                 rect.origin.y = y;
             }
             }
-            ConvertNSRect(fullscreen, &rect);
+            ConvertNSRect(&rect);
 
 
             /* Position and constrain the popup */
             /* Position and constrain the popup */
             if (SDL_WINDOW_IS_POPUP(window)) {
             if (SDL_WINDOW_IS_POPUP(window)) {
@@ -2289,10 +2283,6 @@ void Cocoa_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
     @autoreleasepool {
     @autoreleasepool {
         SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)window->driverdata;
         SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)window->driverdata;
         NSWindow *nswindow = windata.nswindow;
         NSWindow *nswindow = windata.nswindow;
-        NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]];
-
-        rect.size.width = window->floating.w;
-        rect.size.height = window->floating.h;
 
 
         if ([windata.listener windowOperationIsPending:(PENDING_OPERATION_ENTER_FULLSCREEN | PENDING_OPERATION_LEAVE_FULLSCREEN)] ||
         if ([windata.listener windowOperationIsPending:(PENDING_OPERATION_ENTER_FULLSCREEN | PENDING_OPERATION_LEAVE_FULLSCREEN)] ||
             [windata.listener isInFullscreenSpaceTransition]) {
             [windata.listener isInFullscreenSpaceTransition]) {
@@ -2302,6 +2292,18 @@ void Cocoa_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window)
         /* isZoomed always returns true if the window is not resizable */
         /* isZoomed always returns true if the window is not resizable */
         if (!(window->flags & SDL_WINDOW_RESIZABLE) || !Cocoa_IsZoomed(window)) {
         if (!(window->flags & SDL_WINDOW_RESIZABLE) || !Cocoa_IsZoomed(window)) {
             if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
             if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
+                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.
+                 */
+                rect.origin.x = window->floating.x;
+                rect.origin.y = window->floating.y;
+                rect.size.width = window->floating.w;
+                rect.size.height = window->floating.h;
+                ConvertNSRect(&rect);
+
                 [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
                 [nswindow setFrame:[nswindow frameRectForContentRect:rect] display:YES];
                 ScheduleContextUpdates(windata);
                 ScheduleContextUpdates(windata);
             } else if (windata.was_zoomed) {
             } else if (windata.was_zoomed) {
@@ -2527,7 +2529,7 @@ void Cocoa_RestoreWindow(SDL_VideoDevice *_this, SDL_Window *window)
                 rect.size.width = window->floating.w;
                 rect.size.width = window->floating.w;
                 rect.size.height = window->floating.h;
                 rect.size.height = window->floating.h;
 
 
-                ConvertNSRect(SDL_FALSE, &rect);
+                ConvertNSRect(&rect);
 
 
                 if (data.send_floating_position) {
                 if (data.send_floating_position) {
                     data.send_floating_position = SDL_FALSE;
                     data.send_floating_position = SDL_FALSE;
@@ -2624,7 +2626,7 @@ int Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vi
             rect.origin.y = bounds.y;
             rect.origin.y = bounds.y;
             rect.size.width = bounds.w;
             rect.size.width = bounds.w;
             rect.size.height = bounds.h;
             rect.size.height = bounds.h;
-            ConvertNSRect(fullscreen, &rect);
+            ConvertNSRect(&rect);
 
 
             /* Hack to fix origin on macOS 10.4
             /* Hack to fix origin on macOS 10.4
                This is no longer needed as of macOS 10.15, according to bug 4822.
                This is no longer needed as of macOS 10.15, according to bug 4822.
@@ -2647,7 +2649,7 @@ int Cocoa_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_Vi
             rect.size.width = data.was_zoomed ? window->windowed.w : window->floating.w;
             rect.size.width = data.was_zoomed ? window->windowed.w : window->floating.w;
             rect.size.height = data.was_zoomed ? window->windowed.h : window->floating.h;
             rect.size.height = data.was_zoomed ? window->windowed.h : window->floating.h;
 
 
-            ConvertNSRect(fullscreen, &rect);
+            ConvertNSRect(&rect);
 
 
             /* The window is not meant to be fullscreen, but its flags might have a
             /* The window is not meant to be fullscreen, but its flags might have a
              * fullscreen bit set if it's scheduled to go fullscreen immediately
              * fullscreen bit set if it's scheduled to go fullscreen immediately