diff --git a/shell/browser/api/electron_api_browser_window.cc b/shell/browser/api/electron_api_browser_window.cc index 38474e0115a18..6821931900fae 100644 --- a/shell/browser/api/electron_api_browser_window.cc +++ b/shell/browser/api/electron_api_browser_window.cc @@ -157,12 +157,32 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce( [](base::WeakPtr self) { - if (self) + if (self && !self->did_ready_to_show_fired_) { + self->did_ready_to_show_fired_ = true; self->Emit("ready-to-show"); + } }, GetWeakPtr())); } +void BrowserWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) { + // The DidFirstVisuallyNonEmptyPaint event is not very stable that, sometimes + // on some machines it might not be fired, and the actual behavior depends on + // the version of Chromium. + // To work around this bug, we ensure the ready-to-show event is emitted if it + // has not been emitted in did-finish-load event. + // Note that we use did-finish-load event instead of dom-ready event because + // the latter may actually be emitted before the ready-to-show event. + // See also https://github.com/electron/electron/issues/7779. + if (window()->IsVisible() || did_ready_to_show_fired_) + return; + if (render_frame_host->GetParent()) // child frame + return; + did_ready_to_show_fired_ = true; + Emit("ready-to-show"); +} + void BrowserWindow::BeforeUnloadDialogCancelled() { WindowList::WindowCloseCancelled(window()); // Cancel unresponsive event when window close is cancelled. diff --git a/shell/browser/api/electron_api_browser_window.h b/shell/browser/api/electron_api_browser_window.h index b24c99a3b6043..2d3a37c823b35 100644 --- a/shell/browser/api/electron_api_browser_window.h +++ b/shell/browser/api/electron_api_browser_window.h @@ -49,6 +49,8 @@ class BrowserWindow : public TopLevelWindow, content::RenderViewHost* new_host) override; void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidFirstVisuallyNonEmptyPaint() override; + void DidFinishLoad(content::RenderFrameHost* render_frame_host, + const GURL& validated_url) override; void BeforeUnloadDialogCancelled() override; void OnRendererUnresponsive(content::RenderProcessHost*) override; void OnRendererResponsive( @@ -119,6 +121,8 @@ class BrowserWindow : public TopLevelWindow, // it should be cancelled when we can prove that the window is responsive. base::CancelableClosure window_unresponsive_closure_; + bool did_ready_to_show_fired_ = false; + #if defined(OS_MACOSX) std::vector draggable_regions_; #endif diff --git a/spec-main/api-browser-window-spec.ts b/spec-main/api-browser-window-spec.ts index 3c145bb974215..68eed522a6893 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -1280,7 +1280,7 @@ describe('BrowserWindow module', () => { it('preserves transparency', async () => { const w = new BrowserWindow({ show: false, transparent: true }); - w.loadURL('about:blank'); + w.loadFile(path.join(fixtures, 'pages', 'theme-color.html')); await emittedOnce(w, 'ready-to-show'); w.show();