diff --git content/browser/web_contents/web_contents_impl.cc content/browser/web_contents/web_contents_impl.cc index fe352434dd26e..72b68afb94d80 100644 --- content/browser/web_contents/web_contents_impl.cc +++ content/browser/web_contents/web_contents_impl.cc @@ -3947,6 +3947,12 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params, params.main_frame_name, GetOpener(), primary_main_frame_policy, base::UnguessableToken::Create()); + if (params.view && params.delegate_view) { + view_.reset(params.view); + render_view_host_delegate_view_ = params.delegate_view; + } + + if (!view_) { std::unique_ptr delegate = GetContentClient()->browser()->GetWebContentsViewDelegate(this); @@ -3957,6 +3963,7 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params, view_ = CreateWebContentsView(this, std::move(delegate), &render_view_host_delegate_view_); } + } CHECK(render_view_host_delegate_view_); CHECK(view_.get()); @@ -4167,6 +4174,9 @@ void WebContentsImpl::RenderWidgetCreated( "render_widget_host", render_widget_host); CHECK(!created_widgets_.contains(render_widget_host->GetFrameSinkId())); created_widgets_[render_widget_host->GetFrameSinkId()] = render_widget_host; + + observers_.NotifyObservers( + &WebContentsObserver::RenderWidgetCreated, render_widget_host); } void WebContentsImpl::RenderWidgetDeleted( @@ -5086,6 +5096,15 @@ FrameTree* WebContentsImpl::CreateNewWindow( create_params.picture_in_picture_options = *(params.pip_options); } + if (delegate_) { + delegate_->GetCustomWebContentsView(this, + params.target_url, + render_process_id, + opener->GetRoutingID(), + &create_params.view, + &create_params.delegate_view); + } + // Check whether there is an available prerendered page for this navigation if // this is not for guest. If it exists, take WebContents pre-created for // hosting the prerendered page instead of creating new WebContents. @@ -9913,6 +9932,9 @@ void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, } CloseListenerManager::DidChangeFocusedFrame(this); + + observers_.NotifyObservers(&WebContentsObserver::OnFrameFocused, + node->current_frame_host()); } FrameTree* WebContentsImpl::GetOwnedPictureInPictureFrameTree() { @@ -10561,6 +10583,11 @@ void WebContentsImpl::Resize(const gfx::Rect& new_bounds) { OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Resize"); #if defined(USE_AURA) aura::Window* window = GetNativeView(); + if (!window) { + // Will be nullptr with CEF OSR. + NOTIMPLEMENTED(); + return; + } window->SetBounds(gfx::Rect(window->bounds().origin(), new_bounds.size())); #elif BUILDFLAG(IS_ANDROID) content::RenderWidgetHostView* view = GetRenderWidgetHostView(); @@ -10573,6 +10600,11 @@ void WebContentsImpl::Resize(const gfx::Rect& new_bounds) { gfx::Size WebContentsImpl::GetSize() { #if defined(USE_AURA) aura::Window* window = GetNativeView(); + if (!window) { + // Will be nullptr with CEF OSR. + NOTIMPLEMENTED(); + return gfx::Size(); + } return window->bounds().size(); #elif BUILDFLAG(IS_ANDROID) ui::ViewAndroid* view_android = GetNativeView(); diff --git content/browser/web_contents/web_contents_impl_mac.mm content/browser/web_contents/web_contents_impl_mac.mm index f1105a13aa0eb..d1dba26bbac1f 100644 --- content/browser/web_contents/web_contents_impl_mac.mm +++ content/browser/web_contents/web_contents_impl_mac.mm @@ -6,6 +6,7 @@ #import +#include "base/notimplemented.h" #include "content/public/browser/web_contents.h" #include "ui/gfx/geometry/size.h" @@ -13,6 +14,11 @@ namespace content { void WebContentsImpl::Resize(const gfx::Rect& new_bounds) { NSView* view = GetNativeView().GetNativeNSView(); + if (!view) { + // Will be nullptr with CEF OSR. + NOTIMPLEMENTED(); + return; + } NSRect old_wcv_frame = view.frame; CGFloat new_x = old_wcv_frame.origin.x; CGFloat new_y = old_wcv_frame.origin.y + @@ -24,6 +30,11 @@ void WebContentsImpl::Resize(const gfx::Rect& new_bounds) { gfx::Size WebContentsImpl::GetSize() { NSView* view = GetNativeView().GetNativeNSView(); + if (!view) { + // Will be nullptr with CEF OSR. + NOTIMPLEMENTED(); + return gfx::Size(); + } NSRect frame = view.frame; return gfx::Size(NSWidth(frame), NSHeight(frame)); } diff --git content/public/browser/web_contents.h content/public/browser/web_contents.h index 437060750090e..337acf70169b1 100644 --- content/public/browser/web_contents.h +++ content/public/browser/web_contents.h @@ -121,10 +121,12 @@ class BrowserPluginGuestDelegate; class GuestPageHolder; class RenderFrameHost; class RenderViewHost; +class RenderViewHostDelegateView; class RenderWidgetHostView; class ScreenOrientationDelegate; class SiteInstance; class WebContentsDelegate; +class WebContentsView; class WebUI; struct DropData; struct MHTMLGenerationParams; @@ -270,6 +272,10 @@ class WebContents : public PageNavigator, public base::SupportsUserData { network::mojom::WebSandboxFlags starting_sandbox_flags = network::mojom::WebSandboxFlags::kNone; + // Optionally specify the view and delegate view. + raw_ptr view = nullptr; + raw_ptr delegate_view = nullptr; + // Value used to set the last time the WebContents was made active, this is // the value that'll be returned by GetLastActiveTimeTicks(). If this is // left default initialized then the value is not passed on to the diff --git content/public/browser/web_contents_delegate.h content/public/browser/web_contents_delegate.h index da319cb207331..bcd4de085fa6b 100644 --- content/public/browser/web_contents_delegate.h +++ content/public/browser/web_contents_delegate.h @@ -101,9 +101,11 @@ class EyeDropperListener; class FileSelectListener; class JavaScriptDialogManager; class RenderFrameHost; +class RenderViewHostDelegateView; class RenderWidgetHost; class SessionStorageNamespace; class SiteInstance; +class WebContentsView; struct ContextMenuParams; struct DropData; struct MediaPlayerWatchTime; @@ -376,6 +378,14 @@ class CONTENT_EXPORT WebContentsDelegate { const StoragePartitionConfig& partition_config, SessionStorageNamespace* session_storage_namespace); + virtual void GetCustomWebContentsView( + WebContents* web_contents, + const GURL& target_url, + int opener_render_process_id, + int opener_render_frame_id, + raw_ptr* view, + raw_ptr* delegate_view) {} + // Notifies the delegate about the creation of a new WebContents. This // typically happens when popups are created. virtual void WebContentsCreated(WebContents* source_contents, diff --git content/public/browser/web_contents_observer.h content/public/browser/web_contents_observer.h index 4f97e13f9125e..1946f9909803b 100644 --- content/public/browser/web_contents_observer.h +++ content/public/browser/web_contents_observer.h @@ -255,6 +255,9 @@ class CONTENT_EXPORT WebContentsObserver : public base::CheckedObserver { // controlled by the capturing tab. virtual void OnCapturedSurfaceControl() {} + // This method is invoked when a RenderWidget is created. + virtual void RenderWidgetCreated(RenderWidgetHost* render_widget_host) {} + // This method is invoked when the `blink::WebView` of the current // RenderViewHost is ready, e.g. because we recreated it after a crash. virtual void RenderViewReady() {} @@ -952,6 +955,10 @@ class CONTENT_EXPORT WebContentsObserver : public base::CheckedObserver { // WebContents has gained/lost focus. virtual void OnFocusChangedInPage(FocusedNodeDetails* details) {} + // Notification that |render_frame_host| for this WebContents has gained + // focus. + virtual void OnFrameFocused(RenderFrameHost* render_frame_host) {} + // Notifies that the manifest URL for the main frame changed to // |manifest_url|. This will be invoked when a document with a manifest loads // or when the manifest URL changes (possibly to nothing). It is not invoked