From 3819a78a97149cf30d14fc724d626c01a255e72d Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Wed, 22 Sep 2021 09:29:03 +0900 Subject: [PATCH] fix: maximized state calculation for non-resizable windows (#31040) * fix: maximized state calculation for non-resizable windows * refactor: clean up NSRect comparison Co-authored-by: Shelley Vohr --- docs/api/browser-window.md | 2 +- shell/browser/native_window_mac.h | 14 ++++++++++++++ shell/browser/native_window_mac.mm | 16 +++++++--------- .../ui/cocoa/electron_ns_window_delegate.mm | 8 +++++++- spec-main/api-browser-window-spec.ts | 18 ++++++++++++++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index 3591b683607d1..226dd38207e22 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -977,7 +977,7 @@ the player itself we would call this function with arguments of 16/9 and are within the content view--only that they exist. Sum any extra width and height areas you have within the overall content view. -The aspect ratio is not respected when window is resized programmingly with +The aspect ratio is not respected when window is resized programmatically with APIs like `win.setSize`. #### `win.setBackgroundColor(backgroundColor)` diff --git a/shell/browser/native_window_mac.h b/shell/browser/native_window_mac.h index d1eced30dae81..3913722d18b95 100644 --- a/shell/browser/native_window_mac.h +++ b/shell/browser/native_window_mac.h @@ -189,6 +189,19 @@ class NativeWindowMac : public NativeWindow, bool zoom_to_page_width() const { return zoom_to_page_width_; } bool always_simple_fullscreen() const { return always_simple_fullscreen_; } + // We need to save the result of windowWillUseStandardFrame:defaultFrame + // because macOS calls it with what it refers to as the "best fit" frame for a + // zoom. This means that even if an aspect ratio is set, macOS might adjust it + // to better fit the screen. + // + // Thus, we can't just calculate the maximized aspect ratio'd sizing from + // the current visible screen and compare that to the current window's frame + // to determine whether a window is maximized. + NSRect default_frame_for_zoom() const { return default_frame_for_zoom_; } + void set_default_frame_for_zoom(NSRect frame) { + default_frame_for_zoom_ = frame; + } + protected: // views::WidgetDelegate: views::View* GetContentsView() override; @@ -264,6 +277,7 @@ class NativeWindowMac : public NativeWindow, NSRect original_frame_; NSInteger original_level_; NSUInteger simple_fullscreen_mask_; + NSRect default_frame_for_zoom_; std::string vibrancy_type_; diff --git a/shell/browser/native_window_mac.mm b/shell/browser/native_window_mac.mm index 139d7a15849bd..870b6a5112ca0 100644 --- a/shell/browser/native_window_mac.mm +++ b/shell/browser/native_window_mac.mm @@ -608,16 +608,14 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { } bool NativeWindowMac::IsMaximized() { - if (([window_ styleMask] & NSWindowStyleMaskResizable) != 0) { + if (([window_ styleMask] & NSWindowStyleMaskResizable) != 0) return [window_ isZoomed]; - } else { - NSRect rectScreen = [[NSScreen mainScreen] visibleFrame]; - NSRect rectWindow = [window_ frame]; - return (rectScreen.origin.x == rectWindow.origin.x && - rectScreen.origin.y == rectWindow.origin.y && - rectScreen.size.width == rectWindow.size.width && - rectScreen.size.height == rectWindow.size.height); - } + + NSRect rectScreen = GetAspectRatio() > 0.0 + ? default_frame_for_zoom() + : [[NSScreen mainScreen] visibleFrame]; + + return NSEqualRects([window_ frame], rectScreen); } void NativeWindowMac::Minimize() { diff --git a/shell/browser/ui/cocoa/electron_ns_window_delegate.mm b/shell/browser/ui/cocoa/electron_ns_window_delegate.mm index b2d3cf9e6acfb..f9422ce92d1dd 100644 --- a/shell/browser/ui/cocoa/electron_ns_window_delegate.mm +++ b/shell/browser/ui/cocoa/electron_ns_window_delegate.mm @@ -62,8 +62,11 @@ - (void)windowDidChangeOcclusionState:(NSNotification*)notification { // menu to determine the "standard size" of the window. - (NSRect)windowWillUseStandardFrame:(NSWindow*)window defaultFrame:(NSRect)frame { - if (!shell_->zoom_to_page_width()) + if (!shell_->zoom_to_page_width()) { + if (shell_->GetAspectRatio() > 0.0) + shell_->set_default_frame_for_zoom(frame); return frame; + } // If the shift key is down, maximize. if ([[NSApp currentEvent] modifierFlags] & NSShiftKeyMask) @@ -88,6 +91,9 @@ - (NSRect)windowWillUseStandardFrame:(NSWindow*)window // Set the width. Don't touch y or height. frame.size.width = zoomed_width; + if (shell_->GetAspectRatio() > 0.0) + shell_->set_default_frame_for_zoom(frame); + return frame; } diff --git a/spec-main/api-browser-window-spec.ts b/spec-main/api-browser-window-spec.ts index ade443512d4bd..ed6c9c151a6c9 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -1114,6 +1114,24 @@ describe('BrowserWindow module', () => { await unmaximize; expect(w.isMaximized()).to.equal(false); }); + it('returns the correct value for windows with an aspect ratio', async () => { + w.destroy(); + w = new BrowserWindow({ + show: false, + fullscreenable: false + }); + + w.setAspectRatio(16 / 11); + + const maximize = emittedOnce(w, 'resize'); + w.show(); + w.maximize(); + await maximize; + + expect(w.isMaximized()).to.equal(true); + w.resizable = false; + expect(w.isMaximized()).to.equal(true); + }); }); ifdescribe(process.platform !== 'linux')('Minimized state', () => {