fix: menu bar hiding on two setFullscreen(false) (#49995)

* test: add failing test for `setFullscreen(false)`

`setFullscreen(false)` should do nothing
when not already in fullscreen, but it hides the menu bar
on Linux.

Co-authored-by: WofWca <wofwca@protonmail.com>

* fix: menu bar hiding on two setFullScreen(false)

This fixes the following bug on Linux (and maybe macOS):
1. Create a window with a menu bar.
2. Call `win.setFullScreen(false)`.

The menu bar will hide.

See the original bug in our project:
https://github.com/deltachat/deltachat-desktop/issues/4752.

Co-authored-by: WofWca <wofwca@protonmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: WofWca <wofwca@protonmail.com>
This commit is contained in:
trop[bot]
2026-03-04 14:06:35 -05:00
committed by GitHub
parent 7549704f1a
commit 3e6086d930
2 changed files with 22 additions and 20 deletions

View File

@@ -774,10 +774,9 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
if (!IsFullScreenable())
return;
bool leaving_fullscreen = IsFullscreen() && !fullscreen;
#if BUILDFLAG(IS_WIN)
// There is no native fullscreen state on Windows.
bool leaving_fullscreen = IsFullscreen() && !fullscreen;
if (fullscreen) {
last_window_state_ = ui::mojom::WindowShowState::kFullscreen;
NotifyWindowEnterFullScreen();
@@ -816,7 +815,13 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
// Note: the following must be after "widget()->SetFullscreen(fullscreen);"
if (leaving_fullscreen && !IsVisible())
FlipWindowStyle(GetAcceleratedWidget(), true, WS_VISIBLE);
#else
if (IsVisible())
widget()->SetFullscreen(fullscreen);
else if (fullscreen)
widget()->native_widget_private()->Show(
ui::mojom::WindowShowState::kFullscreen, gfx::Rect());
#endif
// Auto-hide menubar when in fullscreen.
if (fullscreen) {
menu_bar_visible_before_fullscreen_ = IsMenuBarVisible();
@@ -827,6 +832,9 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
// `menu_bar_visible_before_fullscreen_` is always false on the
// second call which results in `SetMenuBarVisibility(false)` no
// matter what. We check `leaving_fullscreen` to avoid this.
//
// Additionally, simply calling `win.setFullscreen(false)`
// when not in fullscreen should do nothing.
if (!leaving_fullscreen)
return;
@@ -834,23 +842,6 @@ void NativeWindowViews::SetFullScreen(bool fullscreen) {
menu_bar_visible_before_fullscreen_);
menu_bar_visible_before_fullscreen_ = false;
}
#else
if (IsVisible())
widget()->SetFullscreen(fullscreen);
else if (fullscreen)
widget()->native_widget_private()->Show(
ui::mojom::WindowShowState::kFullscreen, gfx::Rect());
// Auto-hide menubar when in fullscreen.
if (fullscreen) {
menu_bar_visible_before_fullscreen_ = IsMenuBarVisible();
SetMenuBarVisibility(false);
} else {
SetMenuBarVisibility(!IsMenuBarAutoHide() &&
menu_bar_visible_before_fullscreen_);
menu_bar_visible_before_fullscreen_ = false;
}
#endif
}
bool NativeWindowViews::IsFullscreen() const {

View File

@@ -5930,17 +5930,23 @@ describe('BrowserWindow module', () => {
ifdescribe(process.platform !== 'darwin')('when fullscreen state is changed', () => {
it('correctly remembers state prior to fullscreen change', async () => {
const w = new BrowserWindow({ show: false });
// This should do nothing.
w.setFullScreen(false);
expect(w.isMenuBarVisible()).to.be.true('isMenuBarVisible');
w.setMenuBarVisibility(false);
expect(w.isMenuBarVisible()).to.be.false('isMenuBarVisible');
const enterFS = once(w, 'enter-full-screen');
w.setFullScreen(true);
w.setFullScreen(true); // This should do nothing.
await enterFS;
expect(w.fullScreen).to.be.true('not fullscreen');
const exitFS = once(w, 'leave-full-screen');
w.setFullScreen(false);
w.setFullScreen(false); // This should do nothing.
await exitFS;
expect(w.fullScreen).to.be.false('not fullscreen');
@@ -5957,11 +5963,13 @@ describe('BrowserWindow module', () => {
const enterFS = once(w, 'enter-full-screen');
w.setFullScreen(true);
w.setFullScreen(true); // This should do nothing.
await enterFS;
expect(w.fullScreen).to.be.true('not fullscreen');
const exitFS = once(w, 'leave-full-screen');
w.setFullScreen(false);
w.setFullScreen(false); // This should do nothing.
await exitFS;
expect(w.fullScreen).to.be.false('not fullscreen');
@@ -5974,6 +5982,9 @@ describe('BrowserWindow module', () => {
const w = new BrowserWindow();
await w.loadFile(path.join(fixtures, 'pages', 'a.html'));
// This should do nothing.
w.setFullScreen(false);
expect(w.isMenuBarVisible()).to.be.true('isMenuBarVisible');
expect(w.isFullScreen()).to.be.false('is fullscreen');