diff --git a/atom/browser/api/atom_api_web_view_manager.cc b/atom/browser/api/atom_api_web_view_manager.cc index f06c1105526e..1586c3a10dde 100644 --- a/atom/browser/api/atom_api_web_view_manager.cc +++ b/atom/browser/api/atom_api_web_view_manager.cc @@ -14,22 +14,12 @@ using atom::WebContentsPreferences; namespace { -atom::WebViewManager* GetWebViewManager(content::WebContents* web_contents) { - auto context = web_contents->GetBrowserContext(); - if (context) { - auto manager = context->GetGuestManager(); - return static_cast(manager); - } else { - return nullptr; - } -} - void AddGuest(int guest_instance_id, int element_instance_id, content::WebContents* embedder, content::WebContents* guest_web_contents, const base::DictionaryValue& options) { - auto manager = GetWebViewManager(embedder); + auto manager = atom::WebViewManager::GetWebViewManager(embedder); if (manager) manager->AddGuest(guest_instance_id, element_instance_id, embedder, guest_web_contents); @@ -38,7 +28,7 @@ void AddGuest(int guest_instance_id, } void RemoveGuest(content::WebContents* embedder, int guest_instance_id) { - auto manager = GetWebViewManager(embedder); + auto manager = atom::WebViewManager::GetWebViewManager(embedder); if (manager) manager->RemoveGuest(guest_instance_id); } diff --git a/atom/browser/web_contents_preferences.cc b/atom/browser/web_contents_preferences.cc index bfaca8d7ca77..ef9fc4df0b8c 100644 --- a/atom/browser/web_contents_preferences.cc +++ b/atom/browser/web_contents_preferences.cc @@ -9,6 +9,7 @@ #include #include "atom/browser/native_window.h" +#include "atom/browser/web_view_manager.h" #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "base/command_line.h" @@ -130,7 +131,7 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( base::DoubleToString(zoom_factor)); // --guest-instance-id, which is used to identify guest WebContents. - int guest_instance_id; + int guest_instance_id = 0; if (web_preferences.GetInteger(options::kGuestInstanceID, &guest_instance_id)) command_line->AppendSwitchASCII(switches::kGuestInstanceID, base::IntToString(guest_instance_id)); @@ -157,6 +158,17 @@ void WebContentsPreferences::AppendExtraCommandLineSwitches( // The initial visibility state. NativeWindow* window = NativeWindow::FromWebContents(web_contents); + + // Use embedder window for webviews + if (guest_instance_id && !window) { + auto manager = WebViewManager::GetWebViewManager(web_contents); + if (manager) { + auto embedder = manager->GetEmbedder(guest_instance_id); + if (embedder) + window = NativeWindow::FromWebContents(embedder); + } + } + if (window) { bool visible = window->IsVisible() && !window->IsMinimized(); if (!visible) // Default state is visible. diff --git a/atom/browser/web_view_manager.cc b/atom/browser/web_view_manager.cc index d404c1a43680..815e60a166ca 100644 --- a/atom/browser/web_view_manager.cc +++ b/atom/browser/web_view_manager.cc @@ -42,6 +42,13 @@ void WebViewManager::RemoveGuest(int guest_instance_id) { } } +content::WebContents* WebViewManager::GetEmbedder(int guest_instance_id) { + if (ContainsKey(web_contents_embedder_map_, guest_instance_id)) + return web_contents_embedder_map_[guest_instance_id].embedder; + else + return nullptr; +} + content::WebContents* WebViewManager::GetGuestByInstanceID( int owner_process_id, int element_instance_id) { @@ -65,4 +72,16 @@ bool WebViewManager::ForEachGuest(content::WebContents* embedder_web_contents, return false; } +// static +WebViewManager* WebViewManager::GetWebViewManager( + content::WebContents* web_contents) { + auto context = web_contents->GetBrowserContext(); + if (context) { + auto manager = context->GetGuestManager(); + return static_cast(manager); + } else { + return nullptr; + } +} + } // namespace atom diff --git a/atom/browser/web_view_manager.h b/atom/browser/web_view_manager.h index ff9a8ecba2ab..eb2ba8ad42c8 100644 --- a/atom/browser/web_view_manager.h +++ b/atom/browser/web_view_manager.h @@ -21,6 +21,9 @@ class WebViewManager : public content::BrowserPluginGuestManager { content::WebContents* embedder, content::WebContents* web_contents); void RemoveGuest(int guest_instance_id); + content::WebContents* GetEmbedder(int guest_instance_id); + + static WebViewManager* GetWebViewManager(content::WebContents* web_contents); protected: // content::BrowserPluginGuestManager: diff --git a/lib/renderer/web-view/web-view.js b/lib/renderer/web-view/web-view.js index 1636d560ee53..e9d300aabbcb 100644 --- a/lib/renderer/web-view/web-view.js +++ b/lib/renderer/web-view/web-view.js @@ -42,6 +42,11 @@ var WebViewImpl = (function () { this.webviewNode.setZoomLevel(zoomLevel) } webFrame.on('zoom-level-changed', this.onZoomLevelChanged) + + this.onVisibilityChanged = (event, visibilityState) => { + this.webviewNode.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', visibilityState) + } + ipcRenderer.on('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', this.onVisibilityChanged) } WebViewImpl.prototype.createBrowserPluginNode = function () { @@ -56,6 +61,7 @@ var WebViewImpl = (function () { WebViewImpl.prototype.reset = function () { // Unlisten the zoom-level-changed event. webFrame.removeListener('zoom-level-changed', this.onZoomLevelChanged) + ipcRenderer.removeListener('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', this.onVisibilityChanged) // If guestInstanceId is defined then the has navigated and has // already picked up a partition ID. Thus, we need to reset the initialization diff --git a/spec/fixtures/pages/visibilitychange.html b/spec/fixtures/pages/visibilitychange.html new file mode 100644 index 000000000000..9f49f520de1f --- /dev/null +++ b/spec/fixtures/pages/visibilitychange.html @@ -0,0 +1,11 @@ + + + + + diff --git a/spec/fixtures/pages/webview-visibilitychange.html b/spec/fixtures/pages/webview-visibilitychange.html new file mode 100644 index 000000000000..7c8b7cef9df5 --- /dev/null +++ b/spec/fixtures/pages/webview-visibilitychange.html @@ -0,0 +1,5 @@ + + + + + diff --git a/spec/webview-spec.js b/spec/webview-spec.js index 8a109b6d7bfd..7bdb3a632e0c 100644 --- a/spec/webview-spec.js +++ b/spec/webview-spec.js @@ -867,4 +867,25 @@ describe(' tag', function () { }) w.loadURL('file://' + fixtures + '/pages/webview-zoom-factor.html') }) + + it('inherits the parent window visibility state and receives visibilitychange events', function (done) { + w = new BrowserWindow({ + show: false + }) + + ipcMain.once('pong', function (event, visibilityState, hidden) { + assert.equal(visibilityState, 'hidden') + assert.equal(hidden, true) + + w.webContents.send('ELECTRON_RENDERER_WINDOW_VISIBILITY_CHANGE', 'visible') + + ipcMain.once('pong', function (event, visibilityState, hidden) { + assert.equal(visibilityState, 'visible') + assert.equal(hidden, false) + done() + }) + }) + + w.loadURL('file://' + fixtures + '/pages/webview-visibilitychange.html') + }) })