From f6dced63b5699ac9ab56750813bfe546627d92c7 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2020 09:42:24 +0900 Subject: [PATCH] fix: ensure ready-to-show event is fired (#25490) Co-authored-by: Cheng Zhao --- .../api/electron_api_browser_window.cc | 22 ++++++++++++++++++- .../browser/api/electron_api_browser_window.h | 4 ++++ spec-main/api-browser-window-spec.ts | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/shell/browser/api/electron_api_browser_window.cc b/shell/browser/api/electron_api_browser_window.cc index 07fc7e8ab1df4..42ffd9b0695ee 100644 --- a/shell/browser/api/electron_api_browser_window.cc +++ b/shell/browser/api/electron_api_browser_window.cc @@ -159,12 +159,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 c7f1a99f30175..56770e6b2fd27 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 0e0dae20b1ecf..782afa1999357 100644 --- a/spec-main/api-browser-window-spec.ts +++ b/spec-main/api-browser-window-spec.ts @@ -1275,7 +1275,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();