Browse Source

fix: don't unmaximize on macOS if user set max bounds (#33549)

Co-authored-by: Shelley Vohr <[email protected]>
trop[bot] 3 years ago
parent
commit
ae9be599e7

+ 2 - 0
shell/browser/native_window_mac.h

@@ -267,6 +267,8 @@ class NativeWindowMac : public NativeWindow,
   // Maximizable window state; necessary for persistence through redraws.
   bool maximizable_ = true;
 
+  bool user_set_bounds_maximized_ = false;
+
   // Simple (pre-Lion) Fullscreen Settings
   bool always_simple_fullscreen_ = false;
   bool is_simple_fullscreen_ = false;

+ 13 - 1
shell/browser/native_window_mac.mm

@@ -612,7 +612,18 @@ void NativeWindowMac::Maximize() {
 }
 
 void NativeWindowMac::Unmaximize() {
-  if (!IsMaximized())
+  // Bail if the last user set bounds were the same size as the window
+  // screen (e.g. the user set the window to maximized via setBounds)
+  //
+  // Per docs during zoom:
+  // > If there’s no saved user state because there has been no previous
+  // > zoom,the size and location of the window don’t change.
+  //
+  // However, in classic Apple fashion, this is not the case in practice,
+  // and the frame inexplicably becomes very tiny. We should prevent
+  // zoom from being called if the window is being unmaximized and its
+  // unmaximized window bounds are themselves functionally maximized.
+  if (!IsMaximized() || user_set_bounds_maximized_)
     return;
 
   [window_ zoom:nil];
@@ -714,6 +725,7 @@ void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) {
   cocoa_bounds.origin.y = NSHeight([screen frame]) - size.height() - bounds.y();
 
   [window_ setFrame:cocoa_bounds display:YES animate:animate];
+  user_set_bounds_maximized_ = IsMaximized() ? true : false;
 }
 
 gfx::Rect NativeWindowMac::GetBounds() {

+ 16 - 0
spec-main/api-browser-window-spec.ts

@@ -3632,6 +3632,22 @@ describe('BrowserWindow module', () => {
       expectBoundsEqual(w.getSize(), initialSize);
       expectBoundsEqual(w.getPosition(), initialPosition);
     });
+
+    ifit(process.platform === 'darwin')('should not change size or position of a window which is functionally maximized', async () => {
+      const { workArea } = screen.getPrimaryDisplay();
+
+      const bounds = {
+        x: workArea.x,
+        y: workArea.y,
+        width: workArea.width,
+        height: workArea.height
+      };
+
+      const w = new BrowserWindow(bounds);
+      w.unmaximize();
+      await delay(1000);
+      expectBoundsEqual(w.getBounds(), bounds);
+    });
   });
 
   describe('setFullScreen(false)', () => {