fix: handle BrowserView reparenting (#27000)
This commit is contained in:
parent
6307b52dc5
commit
3286b5fa46
2 changed files with 36 additions and 2 deletions
|
@ -755,6 +755,14 @@ void BaseWindow::AddBrowserView(v8::Local<v8::Value> value) {
|
||||||
auto get_that_view = browser_views_.find(browser_view->ID());
|
auto get_that_view = browser_views_.find(browser_view->ID());
|
||||||
if (get_that_view == browser_views_.end()) {
|
if (get_that_view == browser_views_.end()) {
|
||||||
if (browser_view->web_contents()) {
|
if (browser_view->web_contents()) {
|
||||||
|
// If we're reparenting a BrowserView, ensure that it's detached from
|
||||||
|
// its previous owner window.
|
||||||
|
auto* owner_window = browser_view->web_contents()->owner_window();
|
||||||
|
if (owner_window && owner_window != window_.get()) {
|
||||||
|
owner_window->RemoveBrowserView(browser_view->view());
|
||||||
|
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
window_->AddBrowserView(browser_view->view());
|
window_->AddBrowserView(browser_view->view());
|
||||||
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
browser_view->web_contents()->SetOwnerWindow(window_.get());
|
||||||
}
|
}
|
||||||
|
@ -1076,9 +1084,14 @@ void BaseWindow::ResetBrowserViews() {
|
||||||
v8::Local<v8::Value>::New(isolate(), item.second),
|
v8::Local<v8::Value>::New(isolate(), item.second),
|
||||||
&browser_view) &&
|
&browser_view) &&
|
||||||
!browser_view.IsEmpty()) {
|
!browser_view.IsEmpty()) {
|
||||||
|
// There's a chance that the BrowserView may have been reparented - only
|
||||||
|
// reset if the owner window is *this* window.
|
||||||
if (browser_view->web_contents()) {
|
if (browser_view->web_contents()) {
|
||||||
window_->RemoveBrowserView(browser_view->view());
|
auto* owner_window = browser_view->web_contents()->owner_window();
|
||||||
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
if (owner_window == window_.get()) {
|
||||||
|
browser_view->web_contents()->SetOwnerWindow(nullptr);
|
||||||
|
owner_window->RemoveBrowserView(browser_view->view());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,27 @@ describe('BrowserView module', () => {
|
||||||
w.addBrowserView(view1);
|
w.addBrowserView(view1);
|
||||||
}).to.not.throw();
|
}).to.not.throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can handle BrowserView reparenting', async () => {
|
||||||
|
view = new BrowserView();
|
||||||
|
|
||||||
|
w.addBrowserView(view);
|
||||||
|
view.webContents.loadURL('about:blank');
|
||||||
|
await emittedOnce(view.webContents, 'did-finish-load');
|
||||||
|
|
||||||
|
const w2 = new BrowserWindow({ show: false });
|
||||||
|
w2.addBrowserView(view);
|
||||||
|
|
||||||
|
w.close();
|
||||||
|
|
||||||
|
view.webContents.loadURL(`file://${fixtures}/pages/blank.html`);
|
||||||
|
await emittedOnce(view.webContents, 'did-finish-load');
|
||||||
|
|
||||||
|
// Clean up - the afterEach hook assumes the webContents on w is still alive.
|
||||||
|
w = new BrowserWindow({ show: false });
|
||||||
|
w2.close();
|
||||||
|
w2.destroy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('BrowserWindow.removeBrowserView()', () => {
|
describe('BrowserWindow.removeBrowserView()', () => {
|
||||||
|
|
Loading…
Reference in a new issue