feat: replace BrowserView with WebContentsView (#35658)

This commit is contained in:
Jeremy Rose 2023-12-13 13:01:03 -08:00 committed by GitHub
parent a94fb2cb5d
commit 15c6014324
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
76 changed files with 2987 additions and 1531 deletions

View file

@ -13,7 +13,6 @@
#include "base/task/single_thread_task_runner.h"
#include "electron/buildflags/buildflags.h"
#include "gin/dictionary.h"
#include "shell/browser/api/electron_api_browser_view.h"
#include "shell/browser/api/electron_api_menu.h"
#include "shell/browser/api/electron_api_view.h"
#include "shell/browser/api/electron_api_web_contents.h"
@ -97,6 +96,8 @@ BaseWindow::BaseWindow(v8::Isolate* isolate,
options, parent.IsEmpty() ? nullptr : parent->window_.get()));
window_->AddObserver(this);
SetContentView(View::Create(isolate));
#if defined(TOOLKIT_VIEWS)
v8::Local<v8::Value> icon;
if (options.Get(options::kIcon, &icon)) {
@ -164,7 +165,6 @@ void BaseWindow::OnWindowClosed() {
Emit("closed");
RemoveFromParentChildWindows();
BaseWindow::ResetBrowserViews();
// Destroy the native class when window is closed.
base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
@ -311,8 +311,7 @@ void BaseWindow::OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {
#endif
void BaseWindow::SetContentView(gin::Handle<View> view) {
ResetBrowserViews();
content_view_.Reset(isolate(), view.ToV8());
content_view_.Reset(JavascriptEnvironment::GetIsolate(), view.ToV8());
window_->SetContentView(view->view());
}
@ -749,70 +748,6 @@ void BaseWindow::SetParentWindow(v8::Local<v8::Value> value,
}
}
void BaseWindow::SetBrowserView(
absl::optional<gin::Handle<BrowserView>> browser_view) {
ResetBrowserViews();
if (browser_view)
AddBrowserView(*browser_view);
}
void BaseWindow::AddBrowserView(gin::Handle<BrowserView> browser_view) {
if (!base::Contains(browser_views_, browser_view.ToV8())) {
// 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) {
// iter == browser_views_.end() should imply owner_window != this.
DCHECK_NE(owner_window, this);
owner_window->RemoveBrowserView(browser_view);
browser_view->SetOwnerWindow(nullptr);
}
// If the user set the BrowserView's bounds before adding it to the window,
// we need to get those initial bounds *before* adding it to the window
// so bounds isn't returned relative despite not being correctly positioned
// relative to the window.
auto bounds = browser_view->GetBounds();
window_->AddBrowserView(browser_view->view());
window_->AddDraggableRegionProvider(browser_view.get());
browser_view->SetOwnerWindow(this);
browser_views_.emplace_back().Reset(isolate(), browser_view.ToV8());
// Recalibrate bounds relative to the containing window.
if (!bounds.IsEmpty())
browser_view->SetBounds(bounds);
}
}
void BaseWindow::RemoveBrowserView(gin::Handle<BrowserView> browser_view) {
auto iter = std::find(browser_views_.begin(), browser_views_.end(),
browser_view.ToV8());
if (iter != browser_views_.end()) {
window_->RemoveDraggableRegionProvider(browser_view.get());
window_->RemoveBrowserView(browser_view->view());
browser_view->SetOwnerWindow(nullptr);
iter->Reset();
browser_views_.erase(iter);
}
}
void BaseWindow::SetTopBrowserView(gin::Handle<BrowserView> browser_view,
gin_helper::Arguments* args) {
BaseWindow* owner_window = browser_view->owner_window();
auto iter = std::find(browser_views_.begin(), browser_views_.end(),
browser_view.ToV8());
if (iter == browser_views_.end() || (owner_window && owner_window != this)) {
args->ThrowError("Given BrowserView is not attached to the window");
return;
}
browser_views_.erase(iter);
browser_views_.emplace_back().Reset(isolate(), browser_view.ToV8());
window_->SetTopBrowserView(browser_view->view());
}
std::string BaseWindow::GetMediaSourceId() const {
return window_->GetDesktopMediaID().ToString();
}
@ -1018,31 +953,6 @@ std::vector<v8::Local<v8::Object>> BaseWindow::GetChildWindows() const {
return child_windows_.Values(isolate());
}
v8::Local<v8::Value> BaseWindow::GetBrowserView(
gin_helper::Arguments* args) const {
if (browser_views_.empty()) {
return v8::Null(isolate());
} else if (browser_views_.size() == 1) {
auto first_view = browser_views_.begin();
return v8::Local<v8::Value>::New(isolate(), *first_view);
} else {
args->ThrowError(
"BrowserWindow have multiple BrowserViews, "
"Use getBrowserViews() instead");
return v8::Null(isolate());
}
}
std::vector<v8::Local<v8::Value>> BaseWindow::GetBrowserViews() const {
std::vector<v8::Local<v8::Value>> ret;
for (auto const& browser_view : browser_views_) {
ret.push_back(v8::Local<v8::Value>::New(isolate(), browser_view));
}
return ret;
}
bool BaseWindow::IsModal() const {
return window_->is_modal();
}
@ -1140,31 +1050,6 @@ int32_t BaseWindow::GetID() const {
return weak_map_id();
}
void BaseWindow::ResetBrowserViews() {
v8::HandleScope scope(isolate());
for (auto& item : browser_views_) {
gin::Handle<BrowserView> browser_view;
if (gin::ConvertFromV8(isolate(),
v8::Local<v8::Value>::New(isolate(), item),
&browser_view) &&
!browser_view.IsEmpty()) {
// There's a chance that the BrowserView may have been reparented - only
// reset if the owner window is *this* window.
BaseWindow* owner_window = browser_view->owner_window();
DCHECK_EQ(owner_window, this);
browser_view->SetOwnerWindow(nullptr);
window_->RemoveBrowserView(browser_view->view());
window_->RemoveDraggableRegionProvider(browser_view.get());
browser_view->SetOwnerWindow(nullptr);
}
item.Reset();
}
browser_views_.clear();
}
void BaseWindow::RemoveFromParentChildWindows() {
if (parent_window_.IsEmpty())
return;
@ -1274,10 +1159,6 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("setMenu", &BaseWindow::SetMenu)
.SetMethod("removeMenu", &BaseWindow::RemoveMenu)
.SetMethod("setParentWindow", &BaseWindow::SetParentWindow)
.SetMethod("setBrowserView", &BaseWindow::SetBrowserView)
.SetMethod("addBrowserView", &BaseWindow::AddBrowserView)
.SetMethod("removeBrowserView", &BaseWindow::RemoveBrowserView)
.SetMethod("setTopBrowserView", &BaseWindow::SetTopBrowserView)
.SetMethod("getMediaSourceId", &BaseWindow::GetMediaSourceId)
.SetMethod("getNativeWindowHandle", &BaseWindow::GetNativeWindowHandle)
.SetMethod("setProgressBar", &BaseWindow::SetProgressBar)
@ -1333,10 +1214,10 @@ void BaseWindow::BuildPrototype(v8::Isolate* isolate,
.SetMethod("previewFile", &BaseWindow::PreviewFile)
.SetMethod("closeFilePreview", &BaseWindow::CloseFilePreview)
.SetMethod("getContentView", &BaseWindow::GetContentView)
.SetProperty("contentView", &BaseWindow::GetContentView,
&BaseWindow::SetContentView)
.SetMethod("getParentWindow", &BaseWindow::GetParentWindow)
.SetMethod("getChildWindows", &BaseWindow::GetChildWindows)
.SetMethod("getBrowserView", &BaseWindow::GetBrowserView)
.SetMethod("getBrowserViews", &BaseWindow::GetBrowserViews)
.SetMethod("isModal", &BaseWindow::IsModal)
.SetMethod("setThumbarButtons", &BaseWindow::SetThumbarButtons)
#if defined(TOOLKIT_VIEWS)