mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
fix: bind offscreen paint callback to child WebContents (#50152)
fix: bind offscreen paint callback to child WebContents Previously, MaybeOverrideCreateParamsForNewWindow bound the OffScreenWebContentsView's paint callback to the parent WebContents using base::Unretained(this). This was both unsafe (dangling pointer risk if the parent is destroyed before the child) and semantically incorrect — paint events belong to the child window, not the opener. Replace the callback in MaybeOverrideCreateParamsForNewWindow with base::DoNothing(), then rebind it to the child WebContents in AddNewContents via a new SetCallback method on OffScreenWebContentsView.
This commit is contained in:
@@ -1311,10 +1311,11 @@ void WebContents::MaybeOverrideCreateParamsForNewWindow(
|
||||
dict.Get(options::kOffscreen, &is_offscreen) && is_offscreen);
|
||||
|
||||
if (is_offscreen) {
|
||||
// Use a no-op callback here. The real OnPaint callback will be bound
|
||||
// to the child WebContents in AddNewContents via SetCallback().
|
||||
auto* view = new OffScreenWebContentsView(
|
||||
false, offscreen_use_shared_texture_,
|
||||
offscreen_shared_texture_pixel_format_,
|
||||
base::BindRepeating(&WebContents::OnPaint, base::Unretained(this)));
|
||||
offscreen_shared_texture_pixel_format_, base::DoNothing());
|
||||
create_params->view = view;
|
||||
create_params->delegate_view = view;
|
||||
}
|
||||
@@ -1342,6 +1343,15 @@ content::WebContents* WebContents::AddNewContents(
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
auto api_web_contents = CreateAndTake(isolate, std::move(new_contents), type);
|
||||
|
||||
// Rebind the paint callback to the child WebContents. The
|
||||
// OffScreenWebContentsView was initially created with the parent's OnPaint
|
||||
// in MaybeOverrideCreateParamsForNewWindow, but the paint data
|
||||
// belongs to the child.
|
||||
if (auto* osr_view = api_web_contents->GetOffScreenWebContentsView()) {
|
||||
osr_view->SetCallback(base::BindRepeating(&WebContents::OnPaint,
|
||||
api_web_contents->GetWeakPtr()));
|
||||
}
|
||||
|
||||
// We call RenderFrameCreated here as at this point the empty "about:blank"
|
||||
// render frame has already been created. If the window never navigates again
|
||||
// RenderFrameCreated won't be called and certain prefs like
|
||||
|
||||
@@ -45,6 +45,10 @@ void OffScreenWebContentsView::SetWebContents(
|
||||
view->InstallTransparency();
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetCallback(const OnPaintCallback& callback) {
|
||||
callback_ = callback;
|
||||
}
|
||||
|
||||
void OffScreenWebContentsView::SetNativeWindow(NativeWindow* window) {
|
||||
if (native_window_)
|
||||
native_window_->RemoveObserver(this);
|
||||
|
||||
@@ -43,6 +43,7 @@ class OffScreenWebContentsView : public content::WebContentsView,
|
||||
|
||||
void SetWebContents(content::WebContents*);
|
||||
void SetNativeWindow(NativeWindow* window);
|
||||
void SetCallback(const OnPaintCallback& callback);
|
||||
|
||||
// NativeWindowObserver:
|
||||
void OnWindowResize() override;
|
||||
|
||||
Reference in New Issue
Block a user