From 32c60b29bbd9abcaedbe9d65b2a4eae78e1c2fca Mon Sep 17 00:00:00 2001 From: Shelley Vohr Date: Tue, 21 Feb 2023 12:11:34 +0100 Subject: [PATCH] fix: html fullscreen when window not fullscreenable (#37348) --- .../browser/api/electron_api_web_contents.cc | 15 ++++---- shell/browser/native_window_mac.mm | 2 +- spec/api-browser-window-spec.ts | 36 +++++++++++++++++++ 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index c30fa2e8d294..1f9c48a6424f 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -1307,7 +1307,10 @@ Profile* WebContents::GetProfile() { } bool WebContents::IsFullscreen() const { - return owner_window_ && owner_window_->IsFullscreen(); + if (!owner_window()) + return false; + + return owner_window()->IsFullscreen() || is_html_fullscreen(); } void WebContents::EnterFullscreen(const GURL& url, @@ -1353,7 +1356,7 @@ void WebContents::OnEnterFullscreenModeForTab( content::RenderFrameHost* requesting_frame, const blink::mojom::FullscreenOptions& options, bool allowed) { - if (!allowed || !owner_window_) + if (!allowed || !owner_window()) return; auto* source = content::WebContents::FromRenderFrameHost(requesting_frame); @@ -1377,7 +1380,7 @@ void WebContents::OnEnterFullscreenModeForTab( } void WebContents::ExitFullscreenModeForTab(content::WebContents* source) { - if (!owner_window_) + if (!owner_window()) return; // This needs to be called before we exit fullscreen on the native window, @@ -3657,14 +3660,14 @@ void WebContents::EnumerateDirectory( bool WebContents::IsFullscreenForTabOrPending( const content::WebContents* source) { if (!owner_window()) - return html_fullscreen_; + return is_html_fullscreen(); bool in_transition = owner_window()->fullscreen_transition_state() != NativeWindow::FullScreenTransitionState::NONE; bool is_html_transition = owner_window()->fullscreen_transition_type() == NativeWindow::FullScreenTransitionType::HTML; - return html_fullscreen_ || (in_transition && is_html_transition); + return is_html_fullscreen() || (in_transition && is_html_transition); } bool WebContents::TakeFocus(content::WebContents* source, bool reverse) { @@ -3954,7 +3957,7 @@ void WebContents::OnDevToolsSearchCompleted( void WebContents::SetHtmlApiFullscreen(bool enter_fullscreen) { // Window is already in fullscreen mode, save the state. - if (enter_fullscreen && owner_window_->IsFullscreen()) { + if (enter_fullscreen && owner_window()->IsFullscreen()) { native_fullscreen_ = true; UpdateHtmlApiFullscreen(true); return; diff --git a/shell/browser/native_window_mac.mm b/shell/browser/native_window_mac.mm index 3a2bb15b5814..f9b313be8240 100644 --- a/shell/browser/native_window_mac.mm +++ b/shell/browser/native_window_mac.mm @@ -619,7 +619,7 @@ void NativeWindowMac::SetFullScreen(bool fullscreen) { return; } - if (fullscreen == IsFullscreen()) + if (fullscreen == IsFullscreen() || !IsFullScreenable()) return; // Take note of the current window size diff --git a/spec/api-browser-window-spec.ts b/spec/api-browser-window-spec.ts index 72a0124a1cc8..3252bc0eff84 100644 --- a/spec/api-browser-window-spec.ts +++ b/spec/api-browser-window-spec.ts @@ -5077,6 +5077,42 @@ describe('BrowserWindow module', () => { await done; }); + it('handles HTML fullscreen transitions when fullscreenable is false', async () => { + const w = new BrowserWindow({ fullscreenable: false }); + await w.loadFile(path.join(fixtures, 'pages', 'a.html')); + + expect(w.isFullScreen()).to.be.false('is fullscreen'); + + let enterCount = 0; + let exitCount = 0; + + const done = new Promise((resolve, reject) => { + const checkDone = () => { + if (enterCount === 2 && exitCount === 2) resolve(); + }; + + w.webContents.on('enter-html-full-screen', async () => { + enterCount++; + if (w.isFullScreen()) reject(new Error('w.isFullScreen should be false')); + const isFS = await w.webContents.executeJavaScript('!!document.fullscreenElement'); + if (!isFS) reject(new Error('Document should have fullscreen element')); + checkDone(); + }); + + w.webContents.on('leave-html-full-screen', () => { + exitCount++; + if (w.isFullScreen()) reject(new Error('w.isFullScreen should be false')); + checkDone(); + }); + }); + + await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true); + await w.webContents.executeJavaScript('document.exitFullscreen()'); + await w.webContents.executeJavaScript('document.getElementById("div").requestFullscreen()', true); + await w.webContents.executeJavaScript('document.exitFullscreen()'); + await expect(done).to.eventually.be.fulfilled(); + }); + it('does not crash when exiting simpleFullScreen (properties)', async () => { const w = new BrowserWindow(); w.setSimpleFullScreen(true);