Skip to content

Commit b85195e

Browse files
fix: ensure ready-to-show event is fired (electron#25632)
1 parent ac25f4d commit b85195e

8 files changed

Lines changed: 31 additions & 33 deletions

lib/browser/api/web-contents.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,15 @@ WebContents.prototype._init = function () {
615615
app.emit('login', event, this, ...args);
616616
});
617617

618+
this.on('ready-to-show' as any, () => {
619+
const owner = this.getOwnerBrowserWindow();
620+
if (owner && !owner.isDestroyed()) {
621+
process.nextTick(() => {
622+
owner.emit('ready-to-show');
623+
});
624+
}
625+
});
626+
618627
const event = process._linkedBinding('electron_browser_event').createEmpty();
619628
app.emit('web-contents-created', event, this);
620629

shell/browser/api/electron_api_browser_window.cc

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -152,35 +152,6 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
152152
auto* const view = web_contents()->GetRenderWidgetHostView();
153153
view->Show();
154154
view->SetSize(window()->GetContentSize());
155-
156-
// Emit the ReadyToShow event in next tick in case of pending drawing work.
157-
base::ThreadTaskRunnerHandle::Get()->PostTask(
158-
FROM_HERE, base::BindOnce(
159-
[](base::WeakPtr<BrowserWindow> self) {
160-
if (self && !self->did_ready_to_show_fired_) {
161-
self->did_ready_to_show_fired_ = true;
162-
self->Emit("ready-to-show");
163-
}
164-
},
165-
GetWeakPtr()));
166-
}
167-
168-
void BrowserWindow::DidFinishLoad(content::RenderFrameHost* render_frame_host,
169-
const GURL& validated_url) {
170-
// The DidFirstVisuallyNonEmptyPaint event is not very stable that, sometimes
171-
// on some machines it might not be fired, and the actual behavior depends on
172-
// the version of Chromium.
173-
// To work around this bug, we ensure the ready-to-show event is emitted if it
174-
// has not been emitted in did-finish-load event.
175-
// Note that we use did-finish-load event instead of dom-ready event because
176-
// the latter may actually be emitted before the ready-to-show event.
177-
// See also https://github.com/electron/electron/issues/7779.
178-
if (window()->IsVisible() || did_ready_to_show_fired_)
179-
return;
180-
if (render_frame_host->GetParent()) // child frame
181-
return;
182-
did_ready_to_show_fired_ = true;
183-
Emit("ready-to-show");
184155
}
185156

186157
void BrowserWindow::BeforeUnloadDialogCancelled() {

shell/browser/api/electron_api_browser_window.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@ class BrowserWindow : public BaseWindow,
4949
content::RenderViewHost* new_host) override;
5050
void RenderViewCreated(content::RenderViewHost* render_view_host) override;
5151
void DidFirstVisuallyNonEmptyPaint() override;
52-
void DidFinishLoad(content::RenderFrameHost* render_frame_host,
53-
const GURL& validated_url) override;
5452
void BeforeUnloadDialogCancelled() override;
5553
void OnRendererUnresponsive(content::RenderProcessHost*) override;
5654
void OnRendererResponsive(
@@ -121,8 +119,6 @@ class BrowserWindow : public BaseWindow,
121119
// it should be cancelled when we can prove that the window is responsive.
122120
base::CancelableClosure window_unresponsive_closure_;
123121

124-
bool did_ready_to_show_fired_ = false;
125-
126122
#if defined(OS_MAC)
127123
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
128124
#endif

shell/browser/api/electron_api_web_contents.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,6 +1240,12 @@ void WebContents::Invoke(bool internal,
12401240
std::move(callback), internal, channel, std::move(arguments));
12411241
}
12421242

1243+
void WebContents::OnFirstNonEmptyLayout() {
1244+
if (receivers_.current_context() == web_contents()->GetMainFrame()) {
1245+
Emit("ready-to-show");
1246+
}
1247+
}
1248+
12431249
void WebContents::ReceivePostMessage(const std::string& channel,
12441250
blink::TransferableMessage message) {
12451251
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();

shell/browser/api/electron_api_web_contents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ class WebContents : public gin::Wrappable<WebContents>,
631631
const std::string& channel,
632632
blink::CloneableMessage arguments,
633633
InvokeCallback callback) override;
634+
void OnFirstNonEmptyLayout() override;
634635
void ReceivePostMessage(const std::string& channel,
635636
blink::TransferableMessage message) override;
636637
void MessageSync(bool internal,

shell/common/api/api.mojom

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ interface ElectronBrowser {
4949
string channel,
5050
blink.mojom.CloneableMessage arguments) => (blink.mojom.CloneableMessage result);
5151

52+
// Informs underlying WebContents that first non-empty layout was performed
53+
// by compositor.
54+
OnFirstNonEmptyLayout();
55+
5256
ReceivePostMessage(string channel, blink.mojom.TransferableMessage message);
5357

5458
// Emits an event on |channel| from the ipcMain JavaScript object in the main

shell/renderer/electron_render_frame_observer.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ void ElectronRenderFrameObserver::OnDestruct() {
128128
delete this;
129129
}
130130

131+
void ElectronRenderFrameObserver::DidMeaningfulLayout(
132+
blink::WebMeaningfulLayout layout_type) {
133+
if (layout_type == blink::WebMeaningfulLayout::kVisuallyNonEmpty) {
134+
mojo::Remote<mojom::ElectronBrowser> browser_remote;
135+
render_frame_->GetRemoteInterfaces()->GetInterface(
136+
browser_remote.BindNewPipeAndPassReceiver());
137+
browser_remote->OnFirstNonEmptyLayout();
138+
}
139+
}
140+
131141
void ElectronRenderFrameObserver::CreateIsolatedWorldContext() {
132142
auto* frame = render_frame_->GetWebFrame();
133143
blink::WebIsolatedWorldInfo info;

shell/renderer/electron_render_frame_observer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ElectronRenderFrameObserver : public content::RenderFrameObserver {
3333
void WillReleaseScriptContext(v8::Local<v8::Context> context,
3434
int world_id) override;
3535
void OnDestruct() override;
36+
void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override;
3637

3738
private:
3839
bool ShouldNotifyClient(int world_id);

0 commit comments

Comments
 (0)