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

refactor: BrowserView is owned by a BaseWindow #35511

Merged
merged 3 commits into from Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from 2 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
89 changes: 39 additions & 50 deletions shell/browser/api/electron_api_base_window.cc
Expand Up @@ -753,61 +753,50 @@ void BaseWindow::SetParentWindow(v8::Local<v8::Value> value,
}
}

void BaseWindow::SetBrowserView(v8::Local<v8::Value> value) {
void BaseWindow::SetBrowserView(
absl::optional<gin::Handle<BrowserView>> browser_view) {
ResetBrowserViews();
AddBrowserView(value);
}

void BaseWindow::AddBrowserView(v8::Local<v8::Value> value) {
gin::Handle<BrowserView> browser_view;
if (value->IsObject() &&
gin::ConvertFromV8(isolate(), value, &browser_view)) {
auto get_that_view = browser_views_.find(browser_view->ID());
if (get_that_view == browser_views_.end()) {
// If we're reparenting a BrowserView, ensure that it's detached from
// its previous owner window.
auto* owner_window = browser_view->owner_window();
if (owner_window && owner_window != window_.get()) {
owner_window->RemoveBrowserView(browser_view->view());
browser_view->SetOwnerWindow(nullptr);
}

window_->AddBrowserView(browser_view->view());
browser_view->SetOwnerWindow(window_.get());
browser_views_[browser_view->ID()].Reset(isolate(), value);
if (browser_view)
AddBrowserView(*browser_view);
}

void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
auto iter = browser_views_.find(browser_view->ID());
if (iter == browser_views_.end()) {
// If we're reparenting a BrowserView, ensure that it's detached from
// its previous owner window.
BaseWindow* owner_window = browser_view->owner_window();
if (owner_window && owner_window != this) {
owner_window->RemoveBrowserView(browser_view);
browser_view->SetOwnerWindow(nullptr);
}

window_->AddBrowserView(browser_view->view());
nornagon marked this conversation as resolved.
Show resolved Hide resolved
browser_view->SetOwnerWindow(this);
browser_views_[browser_view->ID()].Reset(isolate(), browser_view.ToV8());
}
}

void BaseWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
gin::Handle<BrowserView> browser_view;
if (value->IsObject() &&
gin::ConvertFromV8(isolate(), value, &browser_view)) {
auto get_that_view = browser_views_.find(browser_view->ID());
if (get_that_view != browser_views_.end()) {
window_->RemoveBrowserView(browser_view->view());
browser_view->SetOwnerWindow(nullptr);
(*get_that_view).second.Reset(isolate(), value);
browser_views_.erase(get_that_view);
}
void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
auto iter = browser_views_.find(browser_view->ID());
if (iter != browser_views_.end()) {
window_->RemoveBrowserView(browser_view->view());
browser_view->SetOwnerWindow(nullptr);
iter->second.Reset();
browser_views_.erase(iter);
}
}

void BaseWindow::SetTopBrowserView(v8::Local<v8::Value> value,
void BaseWindow::SetTopBrowserView(gin::Handle<BrowserView> browser_view,
gin_helper::Arguments* args) {
gin::Handle<BrowserView> browser_view;
if (value->IsObject() &&
gin::ConvertFromV8(isolate(), value, &browser_view)) {
auto* owner_window = browser_view->owner_window();
auto get_that_view = browser_views_.find(browser_view->ID());
if (get_that_view == browser_views_.end() ||
(owner_window && owner_window != window_.get())) {
args->ThrowError("Given BrowserView is not attached to the window");
return;
}

window_->SetTopBrowserView(browser_view->view());
BaseWindow* owner_window = browser_view->owner_window();
auto iter = browser_views_.find(browser_view->ID());
if (iter == browser_views_.end() || (owner_window && owner_window != this)) {
args->ThrowError("Given BrowserView is not attached to the window");
return;
}

window_->SetTopBrowserView(browser_view->view());
}

std::string BaseWindow::GetMediaSourceId() const {
Expand Down Expand Up @@ -1127,11 +1116,11 @@ void BaseWindow::ResetBrowserViews() {
!browser_view.IsEmpty()) {
// There's a chance that the BrowserView may have been reparented - only
// reset if the owner window is *this* window.
auto* owner_window = browser_view->owner_window();
if (owner_window && owner_window == window_.get()) {
browser_view->SetOwnerWindow(nullptr);
owner_window->RemoveBrowserView(browser_view->view());
}
BaseWindow* owner_window = browser_view->owner_window();
DCHECK_EQ(owner_window, this);
nornagon marked this conversation as resolved.
Show resolved Hide resolved
browser_view->SetOwnerWindow(nullptr);
window_->RemoveBrowserView(browser_view->view());
browser_view->SetOwnerWindow(nullptr);
}

item.second.Reset();
Expand Down
10 changes: 6 additions & 4 deletions shell/browser/api/electron_api_base_window.h
Expand Up @@ -22,6 +22,7 @@
namespace electron::api {

class View;
class BrowserView;

class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
public NativeWindowObserver {
Expand Down Expand Up @@ -173,10 +174,11 @@ class BaseWindow : public gin_helper::TrackableObject<BaseWindow>,
void SetMenu(v8::Isolate* isolate, v8::Local<v8::Value> menu);
void RemoveMenu();
void SetParentWindow(v8::Local<v8::Value> value, gin_helper::Arguments* args);
virtual void SetBrowserView(v8::Local<v8::Value> value);
virtual void AddBrowserView(v8::Local<v8::Value> value);
virtual void RemoveBrowserView(v8::Local<v8::Value> value);
virtual void SetTopBrowserView(v8::Local<v8::Value> value,
virtual void SetBrowserView(
absl::optional<gin::Handle<BrowserView>> browser_view);
virtual void AddBrowserView(gin::Handle<BrowserView> browser_view);
virtual void RemoveBrowserView(gin::Handle<BrowserView> browser_view);
virtual void SetTopBrowserView(gin::Handle<BrowserView> browser_view,
gin_helper::Arguments* args);
virtual std::vector<v8::Local<v8::Value>> GetBrowserViews() const;
virtual void ResetBrowserViews();
Expand Down
5 changes: 3 additions & 2 deletions shell/browser/api/electron_api_browser_view.cc
Expand Up @@ -8,6 +8,7 @@

#include "content/browser/renderer_host/render_widget_host_view_base.h" // nogncheck
#include "content/public/browser/render_widget_host_view.h"
#include "shell/browser/api/electron_api_base_window.h"
#include "shell/browser/api/electron_api_web_contents.h"
#include "shell/browser/browser.h"
#include "shell/browser/native_browser_view.h"
Expand Down Expand Up @@ -99,10 +100,10 @@ BrowserView::BrowserView(gin::Arguments* args,
NativeBrowserView::Create(api_web_contents_->inspectable_web_contents()));
}

void BrowserView::SetOwnerWindow(NativeWindow* window) {
void BrowserView::SetOwnerWindow(BaseWindow* window) {
// Ensure WebContents and BrowserView owner windows are in sync.
if (web_contents())
web_contents()->SetOwnerWindow(window);
web_contents()->SetOwnerWindow(window ? window->window() : nullptr);

owner_window_ = window ? window->GetWeakPtr() : nullptr;
}
Expand Down
7 changes: 4 additions & 3 deletions shell/browser/api/electron_api_browser_view.h
Expand Up @@ -31,6 +31,7 @@ class Dictionary;
namespace electron::api {

class WebContents;
class BaseWindow;

class BrowserView : public gin::Wrappable<BrowserView>,
public gin_helper::Constructible<BrowserView>,
Expand All @@ -51,9 +52,9 @@ class BrowserView : public gin::Wrappable<BrowserView>,
WebContents* web_contents() const { return api_web_contents_; }
NativeBrowserView* view() const { return view_.get(); }

NativeWindow* owner_window() const { return owner_window_.get(); }
BaseWindow* owner_window() const { return owner_window_.get(); }

void SetOwnerWindow(NativeWindow* window);
void SetOwnerWindow(BaseWindow* window);

int32_t ID() const { return id_; }

Expand Down Expand Up @@ -83,7 +84,7 @@ class BrowserView : public gin::Wrappable<BrowserView>,
class WebContents* api_web_contents_ = nullptr;

std::unique_ptr<NativeBrowserView> view_;
base::WeakPtr<NativeWindow> owner_window_;
base::WeakPtr<BaseWindow> owner_window_;

int32_t id_;
};
Expand Down
18 changes: 10 additions & 8 deletions shell/browser/api/electron_api_browser_window.cc
Expand Up @@ -395,31 +395,33 @@ void BrowserWindow::SetBackgroundColor(const std::string& color_name) {
}
}

void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
void BrowserWindow::SetBrowserView(
absl::optional<gin::Handle<BrowserView>> browser_view) {
BaseWindow::ResetBrowserViews();
BaseWindow::AddBrowserView(value);
if (browser_view)
BaseWindow::AddBrowserView(*browser_view);
#if BUILDFLAG(IS_MAC)
UpdateDraggableRegions(draggable_regions_);
#endif
}

void BrowserWindow::AddBrowserView(v8::Local<v8::Value> value) {
BaseWindow::AddBrowserView(value);
void BrowserWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
BaseWindow::AddBrowserView(browser_view);
#if BUILDFLAG(IS_MAC)
UpdateDraggableRegions(draggable_regions_);
#endif
}

void BrowserWindow::RemoveBrowserView(v8::Local<v8::Value> value) {
BaseWindow::RemoveBrowserView(value);
void BrowserWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
BaseWindow::RemoveBrowserView(browser_view);
#if BUILDFLAG(IS_MAC)
UpdateDraggableRegions(draggable_regions_);
#endif
}

void BrowserWindow::SetTopBrowserView(v8::Local<v8::Value> value,
void BrowserWindow::SetTopBrowserView(gin::Handle<BrowserView> browser_view,
gin_helper::Arguments* args) {
BaseWindow::SetTopBrowserView(value, args);
BaseWindow::SetTopBrowserView(browser_view, args);
#if BUILDFLAG(IS_MAC)
UpdateDraggableRegions(draggable_regions_);
#endif
Expand Down
9 changes: 5 additions & 4 deletions shell/browser/api/electron_api_browser_window.h
Expand Up @@ -82,10 +82,11 @@ class BrowserWindow : public BaseWindow,
void Focus() override;
void Blur() override;
void SetBackgroundColor(const std::string& color_name) override;
void SetBrowserView(v8::Local<v8::Value> value) override;
void AddBrowserView(v8::Local<v8::Value> value) override;
void RemoveBrowserView(v8::Local<v8::Value> value) override;
void SetTopBrowserView(v8::Local<v8::Value> value,
void SetBrowserView(
absl::optional<gin::Handle<BrowserView>> browser_view) override;
void AddBrowserView(gin::Handle<BrowserView> browser_view) override;
void RemoveBrowserView(gin::Handle<BrowserView> browser_view) override;
void SetTopBrowserView(gin::Handle<BrowserView> browser_view,
gin_helper::Arguments* args) override;
void ResetBrowserViews() override;
void SetVibrancy(v8::Isolate* isolate, v8::Local<v8::Value> value) override;
Expand Down
2 changes: 1 addition & 1 deletion spec/api-browser-view-spec.ts
Expand Up @@ -30,7 +30,7 @@ describe('BrowserView module', () => {
w = null as any;
await p;

if (view) {
if (view && view.webContents) {
ckerr marked this conversation as resolved.
Show resolved Hide resolved
const p = emittedOnce(view.webContents, 'destroyed');
(view.webContents as any).destroy();
view = null as any;
Expand Down