Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fullscreen windows aren't resizable on macOS #34906

Merged
merged 1 commit into from Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions shell/browser/native_window_mac.h
Expand Up @@ -169,6 +169,7 @@ class NativeWindowMac : public NativeWindow,
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);
void SetCollectionBehavior(bool on, NSUInteger flag);
void SetWindowLevel(int level);
Expand Down
20 changes: 13 additions & 7 deletions shell/browser/native_window_mac.mm
Expand Up @@ -646,7 +646,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

bool NativeWindowMac::IsMaximized() {
if (([window_ styleMask] & NSWindowStyleMaskResizable) != 0)
if (HasStyleMask(NSWindowStyleMaskResizable) != 0)
return [window_ isZoomed];

NSRect rectScreen = GetAspectRatio() > 0.0
Expand Down Expand Up @@ -729,7 +729,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

bool NativeWindowMac::IsFullscreen() const {
return [window_ styleMask] & NSWindowStyleMaskFullScreen;
return HasStyleMask(NSWindowStyleMaskFullScreen);
}

void NativeWindowMac::SetBounds(const gfx::Rect& bounds, bool animate) {
Expand Down Expand Up @@ -830,7 +830,10 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

bool NativeWindowMac::IsResizable() {
return [window_ styleMask] & NSWindowStyleMaskResizable;
bool in_fs_transition =
fullscreen_transition_state() != FullScreenTransitionState::NONE;
bool has_rs_mask = HasStyleMask(NSWindowStyleMaskResizable);
return has_rs_mask && !IsFullscreen() && !in_fs_transition;
}

void NativeWindowMac::SetMovable(bool movable) {
Expand All @@ -846,7 +849,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

bool NativeWindowMac::IsMinimizable() {
return [window_ styleMask] & NSMiniaturizableWindowMask;
return HasStyleMask(NSWindowStyleMaskMiniaturizable);
}

void NativeWindowMac::SetMaximizable(bool maximizable) {
Expand Down Expand Up @@ -876,7 +879,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
}

bool NativeWindowMac::IsClosable() {
return [window_ styleMask] & NSWindowStyleMaskClosable;
return HasStyleMask(NSWindowStyleMaskClosable);
}

void NativeWindowMac::SetAlwaysOnTop(ui::ZOrderLevel z_order,
Expand Down Expand Up @@ -1391,8 +1394,7 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
NSVisualEffectView* vibrantView = [window_ vibrantView];

if (vibrantView != nil && !vibrancy_type_.empty()) {
const bool no_rounded_corner =
!([window_ styleMask] & NSWindowStyleMaskTitled);
const bool no_rounded_corner = !HasStyleMask(NSWindowStyleMaskTitled);
if (!has_frame() && !is_modal() && !no_rounded_corner) {
CGFloat radius;
if (fullscreen) {
Expand Down Expand Up @@ -1767,6 +1769,10 @@ void ViewDidMoveToSuperview(NSView* self, SEL _cmd) {
AddContentViewLayers();
}

bool NativeWindowMac::HasStyleMask(NSUInteger flag) const {
return [window_ styleMask] & flag;
}

void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) {
// Changing the styleMask of a frameless windows causes it to change size so
// we explicitly disable resizing while setting it.
Expand Down
6 changes: 4 additions & 2 deletions shell/browser/ui/cocoa/electron_ns_window_delegate.mm
Expand Up @@ -235,12 +235,14 @@ - (void)windowDidEndLiveResize:(NSNotification*)notification {
}

- (void)windowWillEnterFullScreen:(NSNotification*)notification {
// Store resizable mask so it can be restored after exiting fullscreen.
is_resizable_ = shell_->HasStyleMask(NSWindowStyleMaskResizable);

shell_->SetFullScreenTransitionState(FullScreenTransitionState::ENTERING);

shell_->NotifyWindowWillEnterFullScreen();

// Setting resizable to true before entering fullscreen.
is_resizable_ = shell_->IsResizable();
// Set resizable to true before entering fullscreen.
shell_->SetResizable(true);
}

Expand Down
20 changes: 18 additions & 2 deletions spec-main/api-browser-window-spec.ts
Expand Up @@ -4892,19 +4892,35 @@ describe('BrowserWindow module', () => {
});

ifdescribe(process.platform === 'darwin')('fullscreen state with resizable set', () => {
it('resizable flag should be set to true and restored', async () => {
it('resizable flag should be set to false and restored', async () => {
const w = new BrowserWindow({ resizable: false });

const enterFullScreen = emittedOnce(w, 'enter-full-screen');
w.setFullScreen(true);
await enterFullScreen;
expect(w.resizable).to.be.true('resizable');
expect(w.resizable).to.be.false('resizable');

await delay();
const leaveFullScreen = emittedOnce(w, 'leave-full-screen');
w.setFullScreen(false);
await leaveFullScreen;
expect(w.resizable).to.be.false('resizable');
});

it('default resizable flag should be restored after entering/exiting fullscreen', async () => {
const w = new BrowserWindow();

const enterFullScreen = emittedOnce(w, 'enter-full-screen');
w.setFullScreen(true);
await enterFullScreen;
expect(w.resizable).to.be.false('resizable');

await delay();
const leaveFullScreen = emittedOnce(w, 'leave-full-screen');
w.setFullScreen(false);
await leaveFullScreen;
expect(w.resizable).to.be.true('resizable');
});
});

ifdescribe(process.platform === 'darwin')('fullscreen state', () => {
Expand Down