diff --git a/shell/browser/native_window_mac.h b/shell/browser/native_window_mac.h index 2ed12d23d903f..ef5ab1b10e12b 100644 --- a/shell/browser/native_window_mac.h +++ b/shell/browser/native_window_mac.h @@ -165,6 +165,8 @@ class NativeWindowMac : public NativeWindow, void UpdateVibrancyRadii(bool fullscreen); + void UpdateWindowOriginalFrame(); + // Set the attribute of NSWindow while work around a bug of zoom button. bool HasStyleMask(NSUInteger flag) const; void SetStyleMask(bool on, NSUInteger flag); diff --git a/shell/browser/native_window_mac.mm b/shell/browser/native_window_mac.mm index dcf5a1a8b6b61..243f89a4547fb 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]; } @@ -613,7 +613,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) { @@ -657,7 +657,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) { // Take note of the current window size if (IsNormal()) - original_frame_ = [window_ frame]; + UpdateWindowOriginalFrame(); [window_ miniaturize:nil]; } @@ -701,7 +701,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 @@ -737,6 +737,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() { @@ -1009,7 +1010,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]; } @@ -1406,6 +1407,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 affd748964f6e..5b331b4571616 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 f35cdbec8339f..e6cd0971be06e 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -1228,6 +1228,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'); @@ -1246,6 +1247,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', () => { @@ -1257,6 +1303,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({ @@ -1277,6 +1324,7 @@ describe('BrowserWindow module', () => { await unmaximize; expectBoundsEqual(w.getNormalBounds(), bounds); }); + it('correctly checks transparent window maximization state', async () => { w.destroy(); w = new BrowserWindow({ @@ -1296,6 +1344,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({ @@ -1325,6 +1374,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', () => { @@ -1336,6 +1420,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({ @@ -1381,6 +1466,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', () => { @@ -1418,6 +1547,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();