diff --git a/atom/browser/common_web_contents_delegate.cc b/atom/browser/common_web_contents_delegate.cc index dae1ec367d67..07b5a5b7e5ec 100644 --- a/atom/browser/common_web_contents_delegate.cc +++ b/atom/browser/common_web_contents_delegate.cc @@ -619,7 +619,17 @@ void CommonWebContentsDelegate::SetHtmlApiFullscreen(bool enter_fullscreen) { return; } - owner_window_->SetFullScreen(enter_fullscreen); + // Set fullscreen on window if allowed. + auto* web_preferences = WebContentsPreferences::From(GetWebContents()); + bool html_fullscreenable = + web_preferences ? !web_preferences->IsEnabled( + options::kDisableHtmlFullscreenWindowResize) + : true; + + if (html_fullscreenable) { + owner_window_->SetFullScreen(enter_fullscreen); + } + html_fullscreen_ = enter_fullscreen; native_fullscreen_ = false; } diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index c2713f9bb31b..260cad9a7949 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -122,6 +122,7 @@ WebContentsPreferences::WebContentsPreferences( SetDefaultBoolIfUndefined(options::kNodeIntegration, false); SetDefaultBoolIfUndefined(options::kNodeIntegrationInSubFrames, false); SetDefaultBoolIfUndefined(options::kNodeIntegrationInWorker, false); + SetDefaultBoolIfUndefined(options::kDisableHtmlFullscreenWindowResize, false); SetDefaultBoolIfUndefined(options::kWebviewTag, false); SetDefaultBoolIfUndefined(options::kSandbox, false); SetDefaultBoolIfUndefined(options::kNativeWindowOpen, false); @@ -371,6 +372,9 @@ void WebContentsPreferences::AppendCommandLineSwitches( if (IsEnabled(options::kNodeIntegrationInSubFrames)) command_line->AppendSwitch(switches::kNodeIntegrationInSubFrames); + if (IsEnabled(options::kDisableHtmlFullscreenWindowResize)) + command_line->AppendSwitch(switches::kDisableHtmlFullscreenWindowResize); + // We are appending args to a webContents so let's save the current state // of our preferences object so that during the lifetime of the WebContents // we can fetch the options used to initally configure the WebContents diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index a01681ca1b5c..b22631651d87 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -156,6 +156,10 @@ const char kOffscreen[] = "offscreen"; const char kNodeIntegrationInSubFrames[] = "nodeIntegrationInSubFrames"; +// Disable window resizing when HTML Fullscreen API is activated. +const char kDisableHtmlFullscreenWindowResize[] = + "disableHtmlFullscreenWindowResize"; + } // namespace options namespace switches { @@ -220,6 +224,10 @@ const char kNodeIntegrationInWorker[] = "node-integration-in-worker"; // environments will be created in sub-frames. const char kNodeIntegrationInSubFrames[] = "node-integration-in-subframes"; +// Disable window resizing when HTML Fullscreen API is activated. +const char kDisableHtmlFullscreenWindowResize[] = + "disable-html-fullscreen-window-resize"; + // Widevine options // Path to Widevine CDM binaries. const char kWidevineCdmPath[] = "widevine-cdm-path"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index 80aafa3db62b..3b999faa8e8b 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -76,6 +76,7 @@ extern const char kWebSecurity[]; extern const char kAllowRunningInsecureContent[]; extern const char kOffscreen[]; extern const char kNodeIntegrationInSubFrames[]; +extern const char kDisableHtmlFullscreenWindowResize[]; } // namespace options @@ -111,6 +112,7 @@ extern const char kNativeWindowOpen[]; extern const char kNodeIntegrationInWorker[]; extern const char kWebviewTag[]; extern const char kNodeIntegrationInSubFrames[]; +extern const char kDisableHtmlFullscreenWindowResize[]; extern const char kWidevineCdmPath[]; extern const char kWidevineCdmVersion[]; diff --git a/docs/api/browser-window.md b/docs/api/browser-window.md index b5dc64d81d26..7f31f397941e 100644 --- a/docs/api/browser-window.md +++ b/docs/api/browser-window.md @@ -379,6 +379,9 @@ It creates a new `BrowserWindow` with native properties as set by the `options`. content in the window, can be `no-user-gesture-required`, `user-gesture-required`, `document-user-activation-required`. Defaults to `no-user-gesture-required`. + * `disableHtmlFullscreenWindowResize` Boolean (optional) - Whether to + prevent the window from resizing when entering HTML Fullscreen. Default + is `false`. When setting minimum or maximum window size with `minWidth`/`maxWidth`/ `minHeight`/`maxHeight`, it only constrains the users. It won't prevent you from diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index e4972bfa5593..f457921090c2 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -361,6 +361,14 @@ win.webContents.on('before-input-event', (event, input) => { }) ``` +#### Event: 'enter-html-full-screen' + +Emitted when the window enters a full-screen state triggered by HTML API. + +#### Event: 'leave-html-full-screen' + +Emitted when the window leaves a full-screen state triggered by HTML API. + #### Event: 'devtools-opened' Emitted when DevTools is opened. diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 8b83847041d5..28748ed7e851 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -2097,6 +2097,28 @@ describe('BrowserWindow module', () => { expect(typeofProcess).to.eql('undefined') }) }) + + describe('"disableHtmlFullscreenWindowResize" option', () => { + it('prevents window from resizing when set', (done) => { + w.destroy() + w = new BrowserWindow({ + show: false, + webPreferences: { + disableHtmlFullscreenWindowResize: true + } + }) + w.webContents.once('did-finish-load', () => { + const size = w.getSize() + w.webContents.once('enter-html-full-screen', () => { + const newSize = w.getSize() + expect(newSize).to.deep.equal(size) + done() + }) + w.webContents.executeJavaScript('document.body.webkitRequestFullscreen()', true) + }) + w.loadURL('about:blank') + }) + }) }) describe('nativeWindowOpen + contextIsolation options', () => {