chrome: Use default Browser creation for picture-in-picture popups (see issue #3448)

Note: In current master (based on M111), document PiP partially works when
run with the `--enable-features=DocumentPictureInPictureAPI` command-line
flag. However, the document PiP implementation at this Chromium version is
missing fixes that have already been cherry-picked to the 5563 release
branch. Those fixes will only be available in master after the next Chromium
update (to M112).
This commit is contained in:
Marshall Greenblatt 2023-02-09 13:15:15 -05:00
parent 400fbf7839
commit ff68c01543
11 changed files with 176 additions and 93 deletions

View File

@ -81,7 +81,7 @@ class CefBrowserViewDelegate : public CefViewDelegate {
/// popup will be a DevTools browser. Return the delegate that will be used
/// for the new popup BrowserView.
///
/*--cef()--*/
/*--cef(optional_param=client)--*/
virtual CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
CefRefPtr<CefBrowserView> browser_view,
const CefBrowserSettings& settings,

View File

@ -1227,7 +1227,7 @@ void AlloyBrowserHostImpl::WebContentsCreated(
target_url,
frame_util::MakeGlobalId(opener_render_process_id,
opener_render_frame_id),
settings, client, platform_delegate, extra_info);
settings, client, platform_delegate, extra_info, new_contents);
scoped_refptr<CefBrowserInfo> info =
CefBrowserInfoManager::GetInstance()->CreatePopupBrowserInfo(

View File

@ -125,6 +125,7 @@ bool CefBrowserInfoManager::CanCreateWindow(
CefRefPtr<CefClient> client = browser->GetClient();
bool allow = true;
bool handled = false;
CefWindowInfo window_info;
@ -133,7 +134,7 @@ bool CefBrowserInfoManager::CanCreateWindow(
#endif
auto pending_popup = std::make_unique<CefBrowserInfoManager::PendingPopup>();
pending_popup->step = CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW;
pending_popup->step = PendingPopup::CAN_CREATE_WINDOW;
pending_popup->opener_global_id = opener->GetGlobalId();
pending_popup->target_url = target_url;
pending_popup->target_frame_name = frame_name;
@ -142,6 +143,11 @@ bool CefBrowserInfoManager::CanCreateWindow(
pending_popup->client = client;
pending_popup->settings = browser->settings();
// With the Chrome runtime, we want to use default popup Browser creation
// for document picture-in-picture.
pending_popup->use_default_browser_creation =
disposition == WindowOpenDisposition::NEW_PICTURE_IN_PICTURE;
if (client.get()) {
CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
if (handler.get()) {
@ -172,6 +178,7 @@ bool CefBrowserInfoManager::CanCreateWindow(
cef_features, window_info, pending_popup->client,
pending_popup->settings, pending_popup->extra_info,
no_javascript_access);
handled = true;
}
}
@ -179,14 +186,21 @@ bool CefBrowserInfoManager::CanCreateWindow(
CefBrowserCreateParams create_params;
create_params.MaybeSetWindowInfo(window_info);
if (!handled) {
// Use default Browser creation if OnBeforePopup was unhandled.
// TODO(chrome): Expose a mechanism for the client to choose default
// creation.
pending_popup->use_default_browser_creation = true;
}
// In most cases, Views-hosted browsers should create Views-hosted popups
// and native browsers should use default popup handling. The one exception
// is with the Chrome runtime where a Views-hosted browser may have an
// external parent. In that case we want to use default popup handling even
// though the parent is (technically) Views-hosted.
// and native browsers should use default popup handling. With the Chrome
// runtime, we should additionally use default handling (a) when using an
// external parent and (b) when using default Browser creation.
create_params.popup_with_views_hosted_opener =
browser->HasView() &&
!browser->platform_delegate()->HasExternalParent();
!browser->platform_delegate()->HasExternalParent() &&
!pending_popup->use_default_browser_creation;
create_params.settings = pending_popup->settings;
create_params.client = pending_popup->client;
@ -217,8 +231,7 @@ void CefBrowserInfoManager::GetCustomWebContentsView(
CEF_REQUIRE_UIT();
REQUIRE_ALLOY_RUNTIME();
std::unique_ptr<CefBrowserInfoManager::PendingPopup> pending_popup =
PopPendingPopup(CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW,
auto pending_popup = PopPendingPopup(PendingPopup::CAN_CREATE_WINDOW,
opener_global_id, target_url);
DCHECK(pending_popup.get());
DCHECK(pending_popup->platform_delegate.get());
@ -228,8 +241,7 @@ void CefBrowserInfoManager::GetCustomWebContentsView(
delegate_view);
}
pending_popup->step =
CefBrowserInfoManager::PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW;
pending_popup->step = PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW;
PushPendingPopup(std::move(pending_popup));
}
@ -239,16 +251,16 @@ void CefBrowserInfoManager::WebContentsCreated(
CefBrowserSettings& settings,
CefRefPtr<CefClient>& client,
std::unique_ptr<CefBrowserPlatformDelegate>& platform_delegate,
CefRefPtr<CefDictionaryValue>& extra_info) {
CefRefPtr<CefDictionaryValue>& extra_info,
content::WebContents* new_contents) {
CEF_REQUIRE_UIT();
// GET_CUSTOM_WEB_CONTENTS_VIEW is only used with the alloy runtime.
const auto previous_step =
cef::IsAlloyRuntimeEnabled()
? CefBrowserInfoManager::PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW
: CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW;
const auto previous_step = cef::IsAlloyRuntimeEnabled()
? PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW
: PendingPopup::CAN_CREATE_WINDOW;
std::unique_ptr<CefBrowserInfoManager::PendingPopup> pending_popup =
auto pending_popup =
PopPendingPopup(previous_step, opener_global_id, target_url);
DCHECK(pending_popup.get());
DCHECK(pending_popup->platform_delegate.get());
@ -257,6 +269,30 @@ void CefBrowserInfoManager::WebContentsCreated(
client = pending_popup->client;
platform_delegate = std::move(pending_popup->platform_delegate);
extra_info = pending_popup->extra_info;
// AddWebContents (the next step) is only used with the Chrome runtime.
if (cef::IsChromeRuntimeEnabled()) {
pending_popup->step = PendingPopup::WEB_CONTENTS_CREATED;
pending_popup->new_contents = new_contents;
PushPendingPopup(std::move(pending_popup));
}
}
bool CefBrowserInfoManager::AddWebContents(content::WebContents* new_contents) {
CEF_REQUIRE_UIT();
DCHECK(cef::IsChromeRuntimeEnabled());
// Pending popup information may be missing in cases where
// chrome::AddWebContents is called directly from the Chrome UI (profile
// settings, etc).
auto pending_popup =
PopPendingPopup(PendingPopup::WEB_CONTENTS_CREATED, new_contents);
if (pending_popup) {
return !pending_popup->use_default_browser_creation;
}
// Proceed with default handling.
return false;
}
void CefBrowserInfoManager::OnGetNewBrowserInfo(
@ -297,7 +333,9 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(
std::make_pair(global_id, std::move(pending)));
// Register a timeout for the pending response so that the renderer process
// doesn't hang forever.
// doesn't hang forever. With the Chrome runtime, timeouts may occur in cases
// where chrome::AddWebContents or WebContents::Create are called directly
// from the Chrome UI (profile settings, etc).
if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableNewBrowserInfoTimeout)) {
CEF_POST_DELAYED_TASK(
@ -438,16 +476,18 @@ void CefBrowserInfoManager::PushPendingPopup(
std::unique_ptr<CefBrowserInfoManager::PendingPopup>
CefBrowserInfoManager::PopPendingPopup(
PendingPopup::Step step,
PendingPopup::Step previous_step,
const content::GlobalRenderFrameHostId& opener_global_id,
const GURL& target_url) {
CEF_REQUIRE_UIT();
DCHECK(frame_util::IsValidGlobalId(opener_global_id));
DCHECK_LE(previous_step, PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW);
PendingPopupList::iterator it = pending_popup_list_.begin();
for (; it != pending_popup_list_.end(); ++it) {
PendingPopup* popup = it->get();
if (popup->step == step && popup->opener_global_id == opener_global_id &&
if (popup->step == previous_step &&
popup->opener_global_id == opener_global_id &&
popup->target_url == target_url) {
// Transfer ownership of the pointer.
it->release();
@ -459,6 +499,26 @@ CefBrowserInfoManager::PopPendingPopup(
return nullptr;
}
std::unique_ptr<CefBrowserInfoManager::PendingPopup>
CefBrowserInfoManager::PopPendingPopup(PendingPopup::Step previous_step,
content::WebContents* new_contents) {
CEF_REQUIRE_UIT();
DCHECK_GE(previous_step, PendingPopup::WEB_CONTENTS_CREATED);
PendingPopupList::iterator it = pending_popup_list_.begin();
for (; it != pending_popup_list_.end(); ++it) {
PendingPopup* popup = it->get();
if (popup->step == previous_step && popup->new_contents == new_contents) {
// Transfer ownership of the pointer.
it->release();
pending_popup_list_.erase(it);
return base::WrapUnique(popup);
}
}
return nullptr;
}
scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfoInternal(
const content::GlobalRenderFrameHostId& global_id,
bool* is_guest_view) {

View File

@ -97,7 +97,12 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
CefBrowserSettings& settings,
CefRefPtr<CefClient>& client,
std::unique_ptr<CefBrowserPlatformDelegate>& platform_delegate,
CefRefPtr<CefDictionaryValue>& extra_info);
CefRefPtr<CefDictionaryValue>& extra_info,
content::WebContents* new_contents);
// Called from ChromeBrowserDelegate::AddWebContents. See comments on
// PendingPopup for more information. Returns true for custom handling.
bool AddWebContents(content::WebContents* source_contents);
// Called from CefBrowserManager::GetNewBrowserInfo for delivering
// browser info to the renderer process. If the browser info already exists
@ -154,6 +159,8 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Creates the OSR views for windowless popups.
// - WebContentsCreated (UIT):
// Creates the CefBrowserHost representation for the popup.
// - AddWebContents (UIT) (chrome runtime only):
// Creates the Browser or tab representation for the popup.
// - CefBrowserManager::GetNewBrowserInfo (IOT)
// Passes information about the popup to the renderer process.
struct PendingPopup {
@ -163,6 +170,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
enum Step {
CAN_CREATE_WINDOW,
GET_CUSTOM_WEB_CONTENTS_VIEW,
WEB_CONTENTS_CREATED,
} step;
// Initial state from ViewHostMsg_CreateWindow.
@ -179,15 +187,29 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Platform delegate specific to the new popup.
std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate;
// True if default Browser or tab creation should proceed from
// AddWebContents (chrome runtime only).
bool use_default_browser_creation = false;
// The newly created WebContents (set in WebContentsCreated).
content::WebContents* new_contents = nullptr;
};
// Manage pending popups. Only called on the UI thread.
void PushPendingPopup(std::unique_ptr<PendingPopup> popup);
// Used after CanCreateWindow is called.
std::unique_ptr<PendingPopup> PopPendingPopup(
PendingPopup::Step step,
PendingPopup::Step previous_step,
const content::GlobalRenderFrameHostId& opener_global_id,
const GURL& target_url);
// Used after WebContentsCreated is called.
std::unique_ptr<PendingPopup> PopPendingPopup(
PendingPopup::Step previous_step,
content::WebContents* new_contents);
// Retrieves the BrowserInfo matching the specified ID.
scoped_refptr<CefBrowserInfo> GetBrowserInfoInternal(
const content::GlobalRenderFrameHostId& global_id,

View File

@ -36,7 +36,16 @@ class BrowserDelegate : public content::WebContentsDelegate {
~BrowserDelegate() override {}
// Called immediately after |new_contents| is created.
// Optionally override chrome::AddWebContents behavior. This is most often
// called via Browser::AddNewContents for new popup browsers and provides an
// opportunity for CEF to create a new Browser instead of proceeding with
// default Browser or tab creation.
virtual std::unique_ptr<content::WebContents> AddWebContents(
std::unique_ptr<content::WebContents> new_contents) = 0;
// Called immediately after |new_contents| is created via chrome::Navigate.
// This is most often called for navigations targeting a new tab without a
// pre-existing WebContents.
virtual void OnWebContentsCreated(content::WebContents* new_contents) = 0;
// Add or remove ownership of the WebContents.

View File

@ -34,6 +34,25 @@ ChromeBrowserDelegate::ChromeBrowserDelegate(
ChromeBrowserDelegate::~ChromeBrowserDelegate() = default;
std::unique_ptr<content::WebContents> ChromeBrowserDelegate::AddWebContents(
std::unique_ptr<content::WebContents> new_contents) {
if (CefBrowserInfoManager::GetInstance()->AddWebContents(
new_contents.get())) {
// The browser host should have been created in WebContentsCreated().
auto new_browser =
ChromeBrowserHostImpl::GetBrowserForContents(new_contents.get());
if (new_browser) {
// Create a new Browser and give it ownership of the new WebContents.
new_browser->AddNewContents(std::move(new_contents));
} else {
LOG(ERROR) << "No host found for chrome popup browser";
}
}
// Proceed with default chrome::AddWebContents behavior.
return new_contents;
}
void ChromeBrowserDelegate::OnWebContentsCreated(
content::WebContents* new_contents) {
// Necessary to receive LoadingStateChanged calls during initial navigation.
@ -132,7 +151,7 @@ void ChromeBrowserDelegate::WebContentsCreated(
target_url,
frame_util::MakeGlobalId(opener_render_process_id,
opener_render_frame_id),
settings, client, platform_delegate, extra_info);
settings, client, platform_delegate, extra_info, new_contents);
auto opener = ChromeBrowserHostImpl::GetBrowserForContents(source_contents);
if (!opener) {
@ -155,27 +174,6 @@ void ChromeBrowserDelegate::WebContentsCreated(
browser_info, opener, request_context_impl);
}
void ChromeBrowserDelegate::AddNewContents(
content::WebContents* source_contents,
std::unique_ptr<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& window_features,
bool user_gesture,
bool* was_blocked) {
auto new_browser =
ChromeBrowserHostImpl::GetBrowserForContents(new_contents.get());
if (new_browser) {
// Create a new Browser and give it ownership of the WebContents.
new_browser->AddNewContents(std::move(new_contents));
return;
}
// Fall back to default behavior from Browser::AddNewContents.
chrome::AddWebContents(browser_, source_contents, std::move(new_contents),
target_url, disposition, window_features);
}
content::WebContents* ChromeBrowserDelegate::OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) {

View File

@ -48,6 +48,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
~ChromeBrowserDelegate() override;
// cef::BrowserDelegate methods:
std::unique_ptr<content::WebContents> AddWebContents(
std::unique_ptr<content::WebContents> new_contents) override;
void OnWebContentsCreated(content::WebContents* new_contents) override;
void SetAsDelegate(content::WebContents* web_contents,
bool set_delegate) override;
@ -66,13 +68,6 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
const std::string& frame_name,
const GURL& target_url,
content::WebContents* new_contents) override;
void AddNewContents(content::WebContents* source_contents,
std::unique_ptr<content::WebContents> new_contents,
const GURL& target_url,
WindowOpenDisposition disposition,
const blink::mojom::WindowFeatures& window_features,
bool user_gesture,
bool* was_blocked) override;
content::WebContents* OpenURLFromTab(
content::WebContents* source,
const content::OpenURLParams& params) override;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=499cb70269cbe05c9bba4b0672a26116f7436f76$
// $hash=8b92c198857b0ca5c3ddc9b2c8a82febe7ed8cde$
//
#include "libcef_dll/cpptoc/views/browser_view_delegate_cpptoc.h"
@ -111,11 +111,7 @@ browser_view_delegate_get_delegate_for_popup_browser_view(
NOTREACHED() << "invalid settings->[base.]size";
return NULL;
}
// Verify param: client; type: refptr_same
DCHECK(client);
if (!client) {
return NULL;
}
// Unverified params: client
// Translate param: settings; type: struct_byref_const
CefBrowserSettings settingsObj;

View File

@ -9,7 +9,7 @@
// implementations. See the translator.README.txt file in the tools directory
// for more information.
//
// $hash=4f26a1968e558512fa9894106f0bc9f6b9d8a10f$
// $hash=7301ce9c063a7ff4ab88b6382f6441ba314b20c0$
//
#include "libcef_dll/ctocpp/views/browser_view_delegate_ctocpp.h"
@ -101,11 +101,7 @@ CefBrowserViewDelegateCToCpp::GetDelegateForPopupBrowserView(
if (!browser_view.get()) {
return nullptr;
}
// Verify param: client; type: refptr_same
DCHECK(client.get());
if (!client.get()) {
return nullptr;
}
// Unverified params: client
// Execute
cef_browser_view_delegate_t* _retval =

View File

@ -70,7 +70,7 @@ index 03a6d3a2ee5e8..a19224279243c 100644
]
}
diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc
index 08ac5f0afd874..480986df48aa6 100644
index 08ac5f0afd874..9248d822a3745 100644
--- chrome/browser/ui/browser.cc
+++ chrome/browser/ui/browser.cc
@@ -264,6 +264,25 @@
@ -177,23 +177,7 @@ index 08ac5f0afd874..480986df48aa6 100644
NavigateParams nav_params(this, params.url, params.transition);
nav_params.FillNavigateParamsFromOpenURLParams(params);
nav_params.source_contents = source;
@@ -1712,6 +1770,15 @@ void Browser::AddNewContents(
return;
}
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_) {
+ cef_browser_delegate_->AddNewContents(
+ source, std::move(new_contents), target_url, disposition,
+ window_features, user_gesture, was_blocked);
+ return;
+ }
+#endif
+
chrome::AddWebContents(this, source, std::move(new_contents), target_url,
disposition, window_features, window_action);
}
@@ -1730,6 +1797,8 @@ void Browser::LoadingStateChanged(WebContents* source,
@@ -1730,6 +1788,8 @@ void Browser::LoadingStateChanged(WebContents* source,
bool should_show_loading_ui) {
ScheduleUIUpdate(source, content::INVALIDATE_TYPE_LOAD);
UpdateWindowForLoadingStateChanged(source, should_show_loading_ui);
@ -202,7 +186,7 @@ index 08ac5f0afd874..480986df48aa6 100644
}
void Browser::CloseContents(WebContents* source) {
@@ -1757,6 +1826,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
@@ -1757,6 +1817,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
}
void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
@ -211,7 +195,7 @@ index 08ac5f0afd874..480986df48aa6 100644
if (!GetStatusBubble())
return;
@@ -1764,6 +1835,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
@@ -1764,6 +1826,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
GetStatusBubble()->SetURL(url);
}
@ -229,7 +213,7 @@ index 08ac5f0afd874..480986df48aa6 100644
void Browser::ContentsMouseEvent(WebContents* source,
bool motion,
bool exited) {
@@ -1788,6 +1870,19 @@ bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
@@ -1788,6 +1861,19 @@ bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
return false;
}
@ -249,7 +233,7 @@ index 08ac5f0afd874..480986df48aa6 100644
void Browser::BeforeUnloadFired(WebContents* web_contents,
bool proceed,
bool* proceed_to_fire_unload) {
@@ -1880,6 +1975,10 @@ void Browser::WebContentsCreated(WebContents* source_contents,
@@ -1880,6 +1966,10 @@ void Browser::WebContentsCreated(WebContents* source_contents,
// Make the tab show up in the task manager.
task_manager::WebContentsTags::CreateForTabContents(new_contents);
@ -260,7 +244,7 @@ index 08ac5f0afd874..480986df48aa6 100644
}
void Browser::PortalWebContentsCreated(WebContents* portal_web_contents) {
@@ -1991,11 +2090,15 @@ void Browser::EnterFullscreenModeForTab(
@@ -1991,11 +2081,15 @@ void Browser::EnterFullscreenModeForTab(
const blink::mojom::FullscreenOptions& options) {
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
requesting_frame, options.display_id);
@ -276,7 +260,7 @@ index 08ac5f0afd874..480986df48aa6 100644
}
bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
@@ -2189,6 +2292,15 @@ void Browser::RequestMediaAccessPermission(
@@ -2189,6 +2283,15 @@ void Browser::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
content::MediaResponseCallback callback) {
@ -292,7 +276,7 @@ index 08ac5f0afd874..480986df48aa6 100644
const extensions::Extension* extension =
GetExtensionForOrigin(profile_, request.security_origin);
MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
@@ -2725,13 +2837,20 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
@@ -2725,13 +2828,20 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
// Browser, Getters for UI (private):
StatusBubble* Browser::GetStatusBubble() {
@ -314,7 +298,7 @@ index 08ac5f0afd874..480986df48aa6 100644
return window_ ? window_->GetStatusBubble() : nullptr;
}
@@ -2863,6 +2982,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
@@ -2863,6 +2973,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
web_contents_collection_.StopObserving(web_contents);
}
@ -444,7 +428,7 @@ index f6df2d49dc719..01e5e7a42fa96 100644
// tab helpers, so the entire set of tab helpers needs to be set up
// immediately.
diff --git chrome/browser/ui/browser_tabstrip.cc chrome/browser/ui/browser_tabstrip.cc
index a3dbf97b6f943..6d8e521e9f189 100644
index a3dbf97b6f943..799a64e17fca5 100644
--- chrome/browser/ui/browser_tabstrip.cc
+++ chrome/browser/ui/browser_tabstrip.cc
@@ -33,9 +33,13 @@ void AddTabAt(Browser* browser,
@ -462,3 +446,20 @@ index a3dbf97b6f943..6d8e521e9f189 100644
params.disposition = foreground ? WindowOpenDisposition::NEW_FOREGROUND_TAB
: WindowOpenDisposition::NEW_BACKGROUND_TAB;
params.tabstrip_index = idx;
@@ -71,6 +75,16 @@ void AddWebContents(Browser* browser,
// Can't create a new contents for the current tab - invalid case.
DCHECK(disposition != WindowOpenDisposition::CURRENT_TAB);
+#if BUILDFLAG(ENABLE_CEF)
+ if (browser && browser->cef_delegate() && new_contents) {
+ new_contents = browser->cef_delegate()->AddWebContents(
+ std::move(new_contents));
+ if (!new_contents) {
+ return;
+ }
+ }
+#endif
+
NavigateParams params(browser, std::move(new_contents));
params.source_contents = source_contents;
params.url = target_url;

View File

@ -767,6 +767,12 @@ bool ClientHandler::OnBeforePopup(
bool* no_javascript_access) {
CEF_REQUIRE_UI_THREAD();
if (target_disposition == WOD_NEW_PICTURE_IN_PICTURE) {
// Use default handling for document picture-in-picture popups.
client = nullptr;
return false;
}
// Return true to cancel the popup window.
return !CreatePopupWindow(browser, false, popupFeatures, windowInfo, client,
settings);