diff --git a/shell/browser/api/electron_api_browser_window.cc b/shell/browser/api/electron_api_browser_window.cc index c926fd44ea279..f7cb0d625f73b 100644 --- a/shell/browser/api/electron_api_browser_window.cc +++ b/shell/browser/api/electron_api_browser_window.cc @@ -158,12 +158,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 7d3cab81b2804..d5c8dad159fea 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; @@ -114,6 +116,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 c448380655152..48505a541a080 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -1200,7 +1200,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()