refactor: JSify BrowserWindow unresponsive handling (#37902)
This commit is contained in:
parent
b683754c16
commit
67ba30402b
3 changed files with 23 additions and 59 deletions
|
@ -36,6 +36,29 @@ BrowserWindow.prototype._init = function (this: BWT) {
|
|||
app.emit('browser-window-focus', event, this);
|
||||
});
|
||||
|
||||
let unresponsiveEvent: NodeJS.Timeout | null = null;
|
||||
const emitUnresponsiveEvent = () => {
|
||||
unresponsiveEvent = null;
|
||||
if (!this.isDestroyed() && this.isEnabled()) { this.emit('unresponsive'); }
|
||||
};
|
||||
this.webContents.on('unresponsive', () => {
|
||||
if (!unresponsiveEvent) { unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 50); }
|
||||
});
|
||||
this.webContents.on('responsive', () => {
|
||||
if (unresponsiveEvent) {
|
||||
clearTimeout(unresponsiveEvent);
|
||||
unresponsiveEvent = null;
|
||||
}
|
||||
this.emit('responsive');
|
||||
});
|
||||
this.on('close', () => {
|
||||
if (!unresponsiveEvent) { unresponsiveEvent = setTimeout(emitUnresponsiveEvent, 5000); }
|
||||
});
|
||||
this.webContents.on('destroyed', () => {
|
||||
if (unresponsiveEvent) clearTimeout(unresponsiveEvent);
|
||||
unresponsiveEvent = null;
|
||||
});
|
||||
|
||||
// Subscribe to visibilityState changes and pass to renderer process.
|
||||
let isVisible = this.isVisible() && !this.isMinimized();
|
||||
const visibilityChanged = () => {
|
||||
|
|
|
@ -117,19 +117,6 @@ BrowserWindow::~BrowserWindow() {
|
|||
|
||||
void BrowserWindow::BeforeUnloadDialogCancelled() {
|
||||
WindowList::WindowCloseCancelled(window());
|
||||
// Cancel unresponsive event when window close is cancelled.
|
||||
window_unresponsive_closure_.Cancel();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnRendererUnresponsive(content::RenderProcessHost*) {
|
||||
// Schedule the unresponsive shortly later, since we may receive the
|
||||
// responsive event soon. This could happen after the whole application had
|
||||
// blocked for a while.
|
||||
// Also notice that when closing this event would be ignored because we have
|
||||
// explicitly started a close timeout counter. This is on purpose because we
|
||||
// don't want the unresponsive event to be sent too early when user is closing
|
||||
// the window.
|
||||
ScheduleUnresponsiveEvent(50);
|
||||
}
|
||||
|
||||
void BrowserWindow::WebContentsDestroyed() {
|
||||
|
@ -137,11 +124,6 @@ void BrowserWindow::WebContentsDestroyed() {
|
|||
CloseImmediately();
|
||||
}
|
||||
|
||||
void BrowserWindow::OnRendererResponsive(content::RenderProcessHost*) {
|
||||
window_unresponsive_closure_.Cancel();
|
||||
Emit("responsive");
|
||||
}
|
||||
|
||||
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
|
||||
// window.resizeTo(...)
|
||||
// window.moveTo(...)
|
||||
|
@ -177,13 +159,6 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
|
|||
// first, and when the web page is closed the window will also be closed.
|
||||
*prevent_default = true;
|
||||
|
||||
// Assume the window is not responding if it doesn't cancel the close and is
|
||||
// not closed in 5s, in this way we can quickly show the unresponsive
|
||||
// dialog when the window is busy executing some script without waiting for
|
||||
// the unresponsive timeout.
|
||||
if (window_unresponsive_closure_.IsCancelled())
|
||||
ScheduleUnresponsiveEvent(5000);
|
||||
|
||||
// Already closed by renderer.
|
||||
if (!web_contents() || !api_web_contents_)
|
||||
return;
|
||||
|
@ -250,9 +225,6 @@ void BrowserWindow::CloseImmediately() {
|
|||
}
|
||||
|
||||
BaseWindow::CloseImmediately();
|
||||
|
||||
// Do not sent "unresponsive" event after window is closed.
|
||||
window_unresponsive_closure_.Cancel();
|
||||
}
|
||||
|
||||
void BrowserWindow::Focus() {
|
||||
|
@ -362,24 +334,6 @@ void BrowserWindow::SetTitleBarOverlay(const gin_helper::Dictionary& options,
|
|||
}
|
||||
#endif
|
||||
|
||||
void BrowserWindow::ScheduleUnresponsiveEvent(int ms) {
|
||||
if (!window_unresponsive_closure_.IsCancelled())
|
||||
return;
|
||||
|
||||
window_unresponsive_closure_.Reset(base::BindRepeating(
|
||||
&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr()));
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
|
||||
FROM_HERE, window_unresponsive_closure_.callback(),
|
||||
base::Milliseconds(ms));
|
||||
}
|
||||
|
||||
void BrowserWindow::NotifyWindowUnresponsive() {
|
||||
window_unresponsive_closure_.Cancel();
|
||||
if (!window_->IsClosed() && window_->IsEnabled()) {
|
||||
Emit("unresponsive");
|
||||
}
|
||||
}
|
||||
|
||||
void BrowserWindow::OnWindowShow() {
|
||||
web_contents()->WasShown();
|
||||
BaseWindow::OnWindowShow();
|
||||
|
|
|
@ -43,9 +43,6 @@ class BrowserWindow : public BaseWindow,
|
|||
|
||||
// content::WebContentsObserver:
|
||||
void BeforeUnloadDialogCancelled() override;
|
||||
void OnRendererUnresponsive(content::RenderProcessHost*) override;
|
||||
void OnRendererResponsive(
|
||||
content::RenderProcessHost* render_process_host) override;
|
||||
void WebContentsDestroyed() override;
|
||||
|
||||
// ExtendedWebContentsObserver:
|
||||
|
@ -84,16 +81,6 @@ class BrowserWindow : public BaseWindow,
|
|||
private:
|
||||
// Helpers.
|
||||
|
||||
// Schedule a notification unresponsive event.
|
||||
void ScheduleUnresponsiveEvent(int ms);
|
||||
|
||||
// Dispatch unresponsive event to observers.
|
||||
void NotifyWindowUnresponsive();
|
||||
|
||||
// Closure that would be called when window is unresponsive when closing,
|
||||
// it should be cancelled when we can prove that the window is responsive.
|
||||
base::CancelableRepeatingClosure window_unresponsive_closure_;
|
||||
|
||||
v8::Global<v8::Value> web_contents_;
|
||||
v8::Global<v8::Value> web_contents_view_;
|
||||
base::WeakPtr<api::WebContents> api_web_contents_;
|
||||
|
|
Loading…
Reference in a new issue