From edbb0cd99f82ea6121879f089a1c4c51baf0c2b0 Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Wed, 8 Jun 2022 00:13:55 +0200 Subject: [PATCH] fix: update normal bounds prior to minimizing --- shell/browser/native_window_mac.h | 2 + shell/browser/native_window_mac.mm | 15 +- .../ui/cocoa/electron_ns_window_delegate.mm | 1 + spec-main/api-browser-window-spec.ts | 173 ++++++++++++++++++ 4 files changed, 186 insertions(+), 5 deletions(-) diff --git a/shell/browser/native_window_mac.h b/shell/browser/native_window_mac.h index 9b6fcb14dda59..e9c6245085caa 100644 --- a/shell/browser/native_window_mac.h +++ b/shell/browser/native_window_mac.h @@ -166,6 +166,8 @@ class NativeWindowMac : public NativeWindow, void UpdateVibrancyRadii(bool fullscreen); + void UpdateWindowOriginalFrame(); + // Set the attribute of NSWindow while work around a bug of zoom button. void SetStyleMask(bool on, NSUInteger flag); void SetCollectionBehavior(bool on, NSUInteger flag); diff --git a/shell/browser/native_window_mac.mm b/shell/browser/native_window_mac.mm index ea30b66444c3e..9ee9cbbb2e591 100644 --- a/shell/browser/native_window_mac.mm +++ b/shell/browser/native_window_mac.mm @@ -451,7 +451,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { SetContentView(new views::View()); AddContentViewLayers(); - original_frame_ = [window_ frame]; + UpdateWindowOriginalFrame(); original_level_ = [window_ level]; } @@ -618,7 +618,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { // Take note of the current window size if (IsNormal()) - original_frame_ = [window_ frame]; + UpdateWindowOriginalFrame(); [window_ zoom:nil]; if (!is_visible) { @@ -662,7 +662,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { // Take note of the current window size if (IsNormal()) - original_frame_ = [window_ frame]; + UpdateWindowOriginalFrame(); [window_ miniaturize:nil]; } @@ -715,7 +715,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { // Take note of the current window size if (IsNormal()) - original_frame_ = [window_ frame]; + UpdateWindowOriginalFrame(); // This needs to be set here because it can be the case that // SetFullScreen is called by a user before windowWillEnterFullScreen @@ -751,6 +751,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { [window_ setFrame:cocoa_bounds display:YES animate:animate]; user_set_bounds_maximized_ = IsMaximized() ? true : false; + UpdateWindowOriginalFrame(); } gfx::Rect NativeWindowMac::GetBounds() { @@ -1025,7 +1026,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { // Take note of the current window size and level if (IsNormal()) { - original_frame_ = [window_ frame]; + UpdateWindowOriginalFrame(); original_level_ = [window_ level]; } @@ -1423,6 +1424,10 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { } } +void NativeWindowMac::UpdateWindowOriginalFrame() { + original_frame_ = [window_ frame]; +} + void NativeWindowMac::SetVibrancy(const std::string& type) { NSVisualEffectView* vibrantView = [window_ vibrantView]; diff --git a/shell/browser/ui/cocoa/electron_ns_window_delegate.mm b/shell/browser/ui/cocoa/electron_ns_window_delegate.mm index fc471ea827fb9..79b2bc8faecc1 100644 --- a/shell/browser/ui/cocoa/electron_ns_window_delegate.mm +++ b/shell/browser/ui/cocoa/electron_ns_window_delegate.mm @@ -203,6 +203,7 @@ - (void)windowWillMiniaturize:(NSNotification*)notification { // windowDidDeminiaturize level_ = [window level]; shell_->SetWindowLevel(NSNormalWindowLevel); + shell_->UpdateWindowOriginalFrame(); } - (void)windowDidMiniaturize:(NSNotification*)notification { diff --git a/spec-main/api-browser-window-spec.ts b/spec-main/api-browser-window-spec.ts index 969578ec87fba..5f854b927a95b 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -1230,6 +1230,7 @@ describe('BrowserWindow module', () => { await resize; expectBoundsEqual(w.getNormalBounds(), w.getBounds()); }); + it('checks normal bounds after move', async () => { const pos = [10, 10]; const move = emittedOnce(w, 'move'); @@ -1248,6 +1249,51 @@ describe('BrowserWindow module', () => { await maximize; expectBoundsEqual(w.getNormalBounds(), bounds); }); + + it('updates normal bounds after resize and maximize', async () => { + const size = [300, 400]; + const resize = emittedOnce(w, 'resize'); + w.setSize(size[0], size[1]); + await resize; + const original = w.getBounds(); + + const maximize = emittedOnce(w, 'maximize'); + w.maximize(); + await maximize; + + const normal = w.getNormalBounds(); + const bounds = w.getBounds(); + + expect(normal).to.deep.equal(original); + expect(normal).to.not.deep.equal(bounds); + + const close = emittedOnce(w, 'close'); + w.close(); + await close; + }); + + it('updates normal bounds after move and maximize', async () => { + const pos = [10, 10]; + const move = emittedOnce(w, 'move'); + w.setPosition(pos[0], pos[1]); + await move; + const original = w.getBounds(); + + const maximize = emittedOnce(w, 'maximize'); + w.maximize(); + await maximize; + + const normal = w.getNormalBounds(); + const bounds = w.getBounds(); + + expect(normal).to.deep.equal(original); + expect(normal).to.not.deep.equal(bounds); + + const close = emittedOnce(w, 'close'); + w.close(); + await close; + }); + it('checks normal bounds when unmaximized', async () => { const bounds = w.getBounds(); w.once('maximize', () => { @@ -1259,6 +1305,7 @@ describe('BrowserWindow module', () => { await unmaximize; expectBoundsEqual(w.getNormalBounds(), bounds); }); + it('does not change size for a frameless window with min size', async () => { w.destroy(); w = new BrowserWindow({ @@ -1279,6 +1326,7 @@ describe('BrowserWindow module', () => { await unmaximize; expectBoundsEqual(w.getNormalBounds(), bounds); }); + it('correctly checks transparent window maximization state', async () => { w.destroy(); w = new BrowserWindow({ @@ -1298,6 +1346,7 @@ 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({ @@ -1327,6 +1376,41 @@ describe('BrowserWindow module', () => { await minimize; expectBoundsEqual(w.getNormalBounds(), bounds); }); + + it('updates normal bounds after move and minimize', async () => { + const pos = [10, 10]; + const move = emittedOnce(w, 'move'); + w.setPosition(pos[0], pos[1]); + await move; + const original = w.getBounds(); + + const minimize = emittedOnce(w, 'minimize'); + w.minimize(); + await minimize; + + const normal = w.getNormalBounds(); + + expect(original).to.deep.equal(normal); + expectBoundsEqual(normal, w.getBounds()); + }); + + it('updates normal bounds after resize and minimize', async () => { + const size = [300, 400]; + const resize = emittedOnce(w, 'resize'); + w.setSize(size[0], size[1]); + await resize; + const original = w.getBounds(); + + const minimize = emittedOnce(w, 'minimize'); + w.minimize(); + await minimize; + + const normal = w.getNormalBounds(); + + expect(original).to.deep.equal(normal); + expectBoundsEqual(normal, w.getBounds()); + }); + it('checks normal bounds when restored', async () => { const bounds = w.getBounds(); w.once('minimize', () => { @@ -1338,6 +1422,7 @@ describe('BrowserWindow module', () => { await restore; expectBoundsEqual(w.getNormalBounds(), bounds); }); + it('does not change size for a frameless window with min size', async () => { w.destroy(); w = new BrowserWindow({ @@ -1383,6 +1468,50 @@ describe('BrowserWindow module', () => { expectBoundsEqual(w.getNormalBounds(), bounds); }); + it('updates normal bounds after resize and fullscreen', async () => { + const size = [300, 400]; + const resize = emittedOnce(w, 'resize'); + w.setSize(size[0], size[1]); + await resize; + const original = w.getBounds(); + + const fsc = emittedOnce(w, 'enter-full-screen'); + w.fullScreen = true; + await fsc; + + const normal = w.getNormalBounds(); + const bounds = w.getBounds(); + + expect(normal).to.deep.equal(original); + expect(normal).to.not.deep.equal(bounds); + + const close = emittedOnce(w, 'close'); + w.close(); + await close; + }); + + it('updates normal bounds after move and fullscreen', async () => { + const pos = [10, 10]; + const move = emittedOnce(w, 'move'); + w.setPosition(pos[0], pos[1]); + await move; + const original = w.getBounds(); + + const fsc = emittedOnce(w, 'enter-full-screen'); + w.fullScreen = true; + await fsc; + + const normal = w.getNormalBounds(); + const bounds = w.getBounds(); + + expect(normal).to.deep.equal(original); + expect(normal).to.not.deep.equal(bounds); + + const close = emittedOnce(w, 'close'); + w.close(); + await close; + }); + it('checks normal bounds when unfullscreen\'ed', async () => { const bounds = w.getBounds(); w.once('enter-full-screen', () => { @@ -1420,6 +1549,50 @@ describe('BrowserWindow module', () => { expectBoundsEqual(w.getNormalBounds(), bounds); }); + it('updates normal bounds after resize and fullscreen', async () => { + const size = [300, 400]; + const resize = emittedOnce(w, 'resize'); + w.setSize(size[0], size[1]); + await resize; + const original = w.getBounds(); + + const fsc = emittedOnce(w, 'enter-full-screen'); + w.setFullScreen(true); + await fsc; + + const normal = w.getNormalBounds(); + const bounds = w.getBounds(); + + expect(normal).to.deep.equal(original); + expect(normal).to.not.deep.equal(bounds); + + const close = emittedOnce(w, 'close'); + w.close(); + await close; + }); + + it('updates normal bounds after move and fullscreen', async () => { + const pos = [10, 10]; + const move = emittedOnce(w, 'move'); + w.setPosition(pos[0], pos[1]); + await move; + const original = w.getBounds(); + + const fsc = emittedOnce(w, 'enter-full-screen'); + w.setFullScreen(true); + await fsc; + + const normal = w.getNormalBounds(); + const bounds = w.getBounds(); + + expect(normal).to.deep.equal(original); + expect(normal).to.not.deep.equal(bounds); + + const close = emittedOnce(w, 'close'); + w.close(); + await close; + }); + it('checks normal bounds when unfullscreen\'ed', async () => { const bounds = w.getBounds(); w.show();