Browse Source

fix: ensure ready-to-show event is fired (#25448) (#26140)

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Milan Burda 4 years ago
parent
commit
c865244bb8

+ 21 - 1
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<BrowserWindow> 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.

+ 4 - 0
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<mojom::DraggableRegionPtr> draggable_regions_;
 #endif

+ 1 - 1
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()