fix: remove cyclic references of BrowserWindow (#22006)

* fix: remove cyclic references in BrowserWindow

* fix: prevent TopLevelWindow from garbage collection

* test: garbage collection of BrowserWindow

* chore: createIDWeakMap is used in tests
This commit is contained in:
Cheng Zhao 2020-02-11 09:37:46 +09:00 committed by GitHub
parent 9942149f3c
commit 9ad6f06831
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 76 additions and 32 deletions

View file

@ -222,6 +222,31 @@ void BrowserWindow::OnDraggableRegionsUpdated(
UpdateDraggableRegions(regions);
}
void BrowserWindow::OnSetContentBounds(const gfx::Rect& rect) {
// window.resizeTo(...)
// window.moveTo(...)
window()->SetBounds(rect, false);
}
void BrowserWindow::OnActivateContents() {
// Hide the auto-hide menu when webContents is focused.
#if !defined(OS_MACOSX)
if (IsMenuBarAutoHide() && IsMenuBarVisible())
window()->SetMenuBarVisibility(false);
#endif
}
void BrowserWindow::OnPageTitleUpdated(const base::string16& title,
bool explicit_set) {
// Change window title to page title.
auto self = GetWeakPtr();
if (!Emit("page-title-updated", title, explicit_set)) {
// |this| might be deleted, or marked as destroyed by close().
if (self && !IsDestroyed())
SetTitle(base::UTF16ToUTF8(title));
}
}
void BrowserWindow::RequestPreferredWidth(int* width) {
*width = web_contents()->GetPreferredSize().width();
}
@ -251,6 +276,8 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) {
void BrowserWindow::OnWindowClosed() {
Cleanup();
// See TopLevelWindow::OnWindowClosed on why calling InvalidateWeakPtrs.
weak_factory_.InvalidateWeakPtrs();
TopLevelWindow::OnWindowClosed();
}

View file

@ -57,6 +57,10 @@ class BrowserWindow : public TopLevelWindow,
void OnRendererResponsive() override;
void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) override;
void OnSetContentBounds(const gfx::Rect& rect) override;
void OnActivateContents() override;
void OnPageTitleUpdated(const base::string16& title,
bool explicit_set) override;
// NativeWindowObserver:
void RequestPreferredWidth(int* width) override;

View file

@ -120,6 +120,9 @@ TopLevelWindow::~TopLevelWindow() {
// Destroy the native window in next tick because the native code might be
// iterating all windows.
base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release());
// Remove global reference so the JS object can be garbage collected.
self_ref_.Reset();
}
void TopLevelWindow::InitWith(v8::Isolate* isolate,
@ -135,6 +138,9 @@ void TopLevelWindow::InitWith(v8::Isolate* isolate,
DCHECK(!parent.IsEmpty());
parent->child_windows_.Set(isolate, weak_map_id(), wrapper);
}
// Reference this object in case it got garbage collected.
self_ref_.Reset(isolate, wrapper);
}
void TopLevelWindow::WillCloseWindow(bool* prevent_default) {

View file

@ -259,6 +259,9 @@ class TopLevelWindow : public gin_helper::TrackableObject<TopLevelWindow>,
std::unique_ptr<NativeWindow> window_;
// Reference to JS wrapper to prevent garbage collection.
v8::Global<v8::Value> self_ref_;
base::WeakPtrFactory<TopLevelWindow> weak_factory_;
};

View file

@ -705,8 +705,9 @@ void WebContents::BeforeUnloadFired(content::WebContents* tab,
}
void WebContents::SetContentsBounds(content::WebContents* source,
const gfx::Rect& pos) {
Emit("move", pos);
const gfx::Rect& rect) {
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnSetContentBounds(rect);
}
void WebContents::CloseContents(content::WebContents* source) {
@ -725,7 +726,8 @@ void WebContents::CloseContents(content::WebContents* source) {
}
void WebContents::ActivateContents(content::WebContents* source) {
Emit("activate");
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnActivateContents();
}
void WebContents::UpdateTargetURL(content::WebContents* source,
@ -1228,6 +1230,8 @@ void WebContents::TitleWasSet(content::NavigationEntry* entry) {
final_title = title;
}
}
for (ExtendedWebContentsObserver& observer : observers_)
observer.OnPageTitleUpdated(final_title, explicit_set);
Emit("page-title-updated", final_title, explicit_set);
}

View file

@ -81,6 +81,10 @@ class ExtendedWebContentsObserver : public base::CheckedObserver {
virtual void OnRendererResponsive() {}
virtual void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) {}
virtual void OnSetContentBounds(const gfx::Rect& rect) {}
virtual void OnActivateContents() {}
virtual void OnPageTitleUpdated(const base::string16& title,
bool explicit_set) {}
protected:
~ExtendedWebContentsObserver() override {}