Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure ready-to-show event is fired #25672

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions lib/browser/api/web-contents.ts
Expand Up @@ -615,6 +615,15 @@ WebContents.prototype._init = function () {
app.emit('login', event, this, ...args);
});

this.on('ready-to-show' as any, () => {
const owner = this.getOwnerBrowserWindow();
if (owner && !owner.isDestroyed()) {
process.nextTick(() => {
owner.emit('ready-to-show');
});
}
});

const event = process._linkedBinding('electron_browser_event').createEmpty();
app.emit('web-contents-created', event, this);

Expand Down
29 changes: 0 additions & 29 deletions shell/browser/api/electron_api_browser_window.cc
Expand Up @@ -152,35 +152,6 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() {
auto* const view = web_contents()->GetRenderWidgetHostView();
view->Show();
view->SetSize(window()->GetContentSize());

// Emit the ReadyToShow event in next tick in case of pending drawing work.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(
[](base::WeakPtr<BrowserWindow> 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() {
Expand Down
4 changes: 0 additions & 4 deletions shell/browser/api/electron_api_browser_window.h
Expand Up @@ -49,8 +49,6 @@ class BrowserWindow : public BaseWindow,
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(
Expand Down Expand Up @@ -121,8 +119,6 @@ class BrowserWindow : public BaseWindow,
// 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_MAC)
std::vector<mojom::DraggableRegionPtr> draggable_regions_;
#endif
Expand Down
6 changes: 6 additions & 0 deletions shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -1240,6 +1240,12 @@ void WebContents::Invoke(bool internal,
std::move(callback), internal, channel, std::move(arguments));
}

void WebContents::OnFirstNonEmptyLayout() {
if (receivers_.current_context() == web_contents()->GetMainFrame()) {
Emit("ready-to-show");
}
}

void WebContents::ReceivePostMessage(const std::string& channel,
blink::TransferableMessage message) {
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_web_contents.h
Expand Up @@ -631,6 +631,7 @@ class WebContents : public gin::Wrappable<WebContents>,
const std::string& channel,
blink::CloneableMessage arguments,
InvokeCallback callback) override;
void OnFirstNonEmptyLayout() override;
void ReceivePostMessage(const std::string& channel,
blink::TransferableMessage message) override;
void MessageSync(bool internal,
Expand Down
4 changes: 4 additions & 0 deletions shell/common/api/api.mojom
Expand Up @@ -49,6 +49,10 @@ interface ElectronBrowser {
string channel,
blink.mojom.CloneableMessage arguments) => (blink.mojom.CloneableMessage result);

// Informs underlying WebContents that first non-empty layout was performed
// by compositor.
OnFirstNonEmptyLayout();

ReceivePostMessage(string channel, blink.mojom.TransferableMessage message);

// Emits an event on |channel| from the ipcMain JavaScript object in the main
Expand Down
10 changes: 10 additions & 0 deletions shell/renderer/electron_render_frame_observer.cc
Expand Up @@ -128,6 +128,16 @@ void ElectronRenderFrameObserver::OnDestruct() {
delete this;
}

void ElectronRenderFrameObserver::DidMeaningfulLayout(
blink::WebMeaningfulLayout layout_type) {
if (layout_type == blink::WebMeaningfulLayout::kVisuallyNonEmpty) {
mojo::Remote<mojom::ElectronBrowser> browser_remote;
render_frame_->GetRemoteInterfaces()->GetInterface(
browser_remote.BindNewPipeAndPassReceiver());
browser_remote->OnFirstNonEmptyLayout();
}
}

void ElectronRenderFrameObserver::CreateIsolatedWorldContext() {
auto* frame = render_frame_->GetWebFrame();
blink::WebIsolatedWorldInfo info;
Expand Down
1 change: 1 addition & 0 deletions shell/renderer/electron_render_frame_observer.h
Expand Up @@ -33,6 +33,7 @@ class ElectronRenderFrameObserver : public content::RenderFrameObserver {
void WillReleaseScriptContext(v8::Local<v8::Context> context,
int world_id) override;
void OnDestruct() override;
void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override;

private:
bool ShouldNotifyClient(int world_id);
Expand Down