diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 4bbf6f579feb8..b441f25b78545 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -1104,6 +1104,37 @@ void WebContents::NavigationEntryCommitted( details.is_same_document, details.did_replace_entry); } +void WebContents::SetBackgroundThrottling(bool allowed) { + background_throttling_ = allowed; + + const auto* contents = web_contents(); + if (!contents) { + return; + } + + const auto* render_view_host = contents->GetRenderViewHost(); + if (!render_view_host) { + return; + } + + const auto* render_process_host = render_view_host->GetProcess(); + if (!render_process_host) { + return; + } + + auto* render_widget_host_impl = content::RenderWidgetHostImpl::FromID( + render_process_host->GetID(), render_view_host->GetRoutingID()); + if (!render_widget_host_impl) { + return; + } + + render_widget_host_impl->disable_hidden_ = !background_throttling_; + + if (render_widget_host_impl->is_hidden()) { + render_widget_host_impl->WasShown(false); + } +} + int WebContents::GetProcessID() const { return web_contents()->GetMainFrame()->GetProcess()->GetID(); } @@ -2011,6 +2042,8 @@ void WebContents::BuildPrototype(v8::Isolate* isolate, prototype->SetClassName(mate::StringToV8(isolate, "WebContents")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) .MakeDestroyable() + .SetMethod("setBackgroundThrottling", + &WebContents::SetBackgroundThrottling) .SetMethod("getProcessId", &WebContents::GetProcessID) .SetMethod("getOSProcessId", &WebContents::GetOSProcessID) .SetMethod("equal", &WebContents::Equal) diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 0dc47ab26a9d1..dfe4e4c678ee2 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -101,6 +101,7 @@ class WebContents : public mate::TrackableObject, // Notifies to destroy any guest web contents before destroying self. void DestroyWebContents(bool async); + void SetBackgroundThrottling(bool allowed); int GetProcessID() const; base::ProcessId GetOSProcessID() const; Type GetType() const; diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index eb7d2b03c3392..29aef125ba903 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -1527,6 +1527,13 @@ Returns `Promise` - Indicates whether the snapshot has been created succes Takes a V8 heap snapshot and saves it to `filePath`. +#### `contents.setBackgroundThrottling(allowed)` + +* `allowed` Boolean + +Controls whether or not this WebContents will throttle animations and timers +when the page becomes backgrounded. This also affects the Page Visibility API. + ### Instance Properties #### `contents.id` diff --git a/lib/browser/api/browser-window.js b/lib/browser/api/browser-window.js index d0e6d38c2f5cb..a563700a3792d 100644 --- a/lib/browser/api/browser-window.js +++ b/lib/browser/api/browser-window.js @@ -221,6 +221,9 @@ Object.assign(BrowserWindow.prototype, { }, setTouchBar (touchBar) { electron.TouchBar._setOnWindow(touchBar, this) + }, + setBackgroundThrottling (allowed) { + this.webContents.setBackgroundThrottling(allowed) } }) diff --git a/spec/api-web-contents-spec.js b/spec/api-web-contents-spec.js index f990d891609da..05f4fa6a366f7 100644 --- a/spec/api-web-contents-spec.js +++ b/spec/api-web-contents-spec.js @@ -905,4 +905,31 @@ describe('webContents module', () => { return expect(promise).to.be.eventually.rejectedWith(Error, 'takeHeapSnapshot failed') }) }) + + describe('setBackgroundThrottling()', () => { + it('does not crash when allowing', (done) => { + w.webContents.setBackgroundThrottling(true) + done() + }) + + it('does not crash when disallowing', (done) => { + w.destroy() + w = new BrowserWindow({ + show: false, + width: 400, + height: 400, + webPreferences: { + backgroundThrottling: true + } + }) + + w.webContents.setBackgroundThrottling(false) + done() + }) + + it('does not crash when called via BrowserWindow', (done) => { + w.setBackgroundThrottling(true) + done() + }) + }) })