cef/patch/patches/chrome_browser_browser.patch
Marshall Greenblatt dd81904a2f Add initial support for API versioning (see #3836)
- Generated files are now created when running cef_create_projects or
  the new version_manager.py tool. These files are still created in the
  cef/ source tree (same location as before) but Git ignores them due to
  the generated .gitignore file.
- API hashes are committed to Git as a new cef_api_versions.json file.
  This file is used for both code generation and CEF version calculation
  (replacing the previous usage of cef_api_hash.h for this purpose).
  It will be updated by the CEF admin before merging breaking API
  changes upstream.
- As an added benefit to the above, contributor PRs will no longer
  contain generated code that is susceptible to frequent merge conflicts.
- From a code generation perspective, the main difference is that we now
  use versioned structs (e.g. cef_browser_0_t instead of cef_browser_t)
  on the libcef (dll/framework) side. Most of the make_*.py tool changes
  are related to supporting this.
- From the client perspective, you can now define CEF_API_VERSION in the
  project configuration (or get CEF_EXPERIMENTAL by default). This
  define will change the API exposed in CEF’s include/ and include/capi
  header files. All client-side targets including libcef_dll_wrapper
  will need be recompiled when changing this define.
- Examples of the new API-related define usage are provided in
  cef_api_version_test.h, api_version_test_impl.cc and
  api_version_unittest.cc.

To test:
- Run `ceftests --gtest_filter=ApiVersionTest.*`
- Add `cef_api_version=13300` to GN_DEFINES. Re-run configure, build and
  ceftests steps.
- Repeat with 13301, 13302, 13303 (all supported test versions).
2025-01-08 17:19:43 -05:00

651 lines
24 KiB
Diff

diff --git chrome/browser/browser_about_handler.cc chrome/browser/browser_about_handler.cc
index 2480282a19d12..dbd1fbf8a15b5 100644
--- chrome/browser/browser_about_handler.cc
+++ chrome/browser/browser_about_handler.cc
@@ -72,6 +72,9 @@ bool HandleNonNavigationAboutURL(const GURL& url) {
FROM_HERE, base::BindOnce(&chrome::AttemptExit));
return true;
}
+ if (base::EqualsCaseInsensitiveASCII(spec, "chrome://ignore/")) {
+ return true;
+ }
return false;
}
diff --git chrome/browser/devtools/devtools_window.cc chrome/browser/devtools/devtools_window.cc
index 4aaba212926f4..e8aadb2c97fe9 100644
--- chrome/browser/devtools/devtools_window.cc
+++ chrome/browser/devtools/devtools_window.cc
@@ -38,6 +38,7 @@
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/task_manager/web_contents_tags.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
@@ -1221,6 +1222,13 @@ DevToolsWindow* DevToolsWindow::Create(
!browser->is_type_normal()) {
can_dock = false;
}
+
+#if BUILDFLAG(ENABLE_CEF)
+ if (can_dock && browser && browser->cef_delegate()) {
+ // Don't dock DevTools for CEF-managed browsers.
+ can_dock = false;
+ }
+#endif
}
// Create WebContents with devtools.
@@ -1680,9 +1688,13 @@ void DevToolsWindow::OpenInNewTab(const GURL& url) {
if (!inspected_web_contents ||
!inspected_web_contents->OpenURL(params,
/*navigation_handle_callback=*/{})) {
+#if !BUILDFLAG(ENABLE_CEF)
+ // Remove default behavior when CEF handles the open via OnOpenURLFromTab.
+ // See CEF issue #3735.
chrome::ScopedTabbedBrowserDisplayer displayer(profile_);
chrome::AddSelectedTabWithURL(displayer.browser(), fixed_url,
ui::PAGE_TRANSITION_LINK);
+#endif
}
}
@@ -1845,12 +1857,28 @@ void DevToolsWindow::CreateDevToolsBrowser() {
Browser::CreationStatus::kOk) {
return;
}
- browser_ =
- Browser::Create(Browser::CreateParams::CreateForDevTools(profile_));
- browser_->tab_strip_model()->AddWebContents(
- OwnedMainWebContents::TakeWebContents(
- std::move(owned_main_web_contents_)),
- -1, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, AddTabTypes::ADD_ACTIVE);
+
+ auto* inspected_web_contents = GetInspectedWebContents();
+ auto* opener = chrome::FindBrowserWithTab(inspected_web_contents);
+ auto devtools_contents = OwnedMainWebContents::TakeWebContents(
+ std::move(owned_main_web_contents_));
+
+#if BUILDFLAG(ENABLE_CEF)
+ // If a Browser is created, it will take ownership of |devtools_contents|.
+ browser_ = cef::BrowserDelegate::CreateDevToolsBrowser(
+ profile_, opener, inspected_web_contents, devtools_contents);
+#endif
+
+ if (!browser_) {
+ auto create_params = Browser::CreateParams::CreateForDevTools(profile_);
+ create_params.opener = opener;
+
+ browser_ = Browser::Create(std::move(create_params));
+ browser_->tab_strip_model()->AddWebContents(
+ std::move(devtools_contents),
+ -1, ui::PAGE_TRANSITION_AUTO_TOPLEVEL, AddTabTypes::ADD_ACTIVE);
+ }
+
OverrideAndSyncDevToolsRendererPrefs();
}
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
index 977b3222c8f7c..e5d36a4e5921e 100644
--- chrome/browser/ui/BUILD.gn
+++ chrome/browser/ui/BUILD.gn
@@ -8,6 +8,7 @@ import("//build/config/compiler/compiler.gni")
import("//build/config/features.gni")
import("//build/config/ozone.gni")
import("//build/config/ui.gni")
+import("//cef/libcef/features/features.gni")
import("//chrome/browser/buildflags.gni")
import("//chrome/common/features.gni")
import("//chromeos/ash/components/assistant/assistant.gni")
@@ -303,6 +304,10 @@ static_library("ui") {
"//build/config/compiler:wexit_time_destructors",
]
+ if (enable_cef) {
+ configs += [ "//cef/libcef/features:config" ]
+ }
+
public_deps = [
# WARNING WARNING WARNING
# New dependencies outside of //chrome/browser should be added to
@@ -331,6 +336,7 @@ static_library("ui") {
"//build/config/chromebox_for_meetings:buildflags",
"//build/config/linux/dbus:buildflags",
"//cc/paint",
+ "//cef/libcef/features",
"//chrome:resources",
"//chrome:strings",
"//chrome/app:chrome_dll_resources",
@@ -699,6 +705,13 @@ static_library("ui") {
deps += [ "//components/plus_addresses/resources:vector_icons" ]
}
+ if (enable_cef) {
+ deps += [
+ "//cef:cef_resources",
+ "//cef:make_version_header",
+ ]
+ }
+
# TODO(crbug.com/41437292): Remove this circular dependency.
# Any circular includes must depend on the target "//chrome/browser:browser_public_dependencies".
# These are all-platform circular includes.
@@ -5487,6 +5500,7 @@ static_library("ui") {
if (enable_printing) {
deps += [
"//components/printing/browser",
+ "//components/printing/common:mojo_interfaces",
"//printing",
]
}
diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc
index a62c82aab7a35..cbd8c87aba959 100644
--- chrome/browser/ui/browser.cc
+++ chrome/browser/ui/browser.cc
@@ -269,6 +269,25 @@
#include "components/captive_portal/content/captive_portal_tab_helper.h"
#endif
+#if BUILDFLAG(ENABLE_CEF)
+#define CALL_CEF_DELEGATE(name, ...) \
+ if (cef_browser_delegate_) { \
+ cef_browser_delegate_->name(__VA_ARGS__); \
+ }
+#define CALL_CEF_DELEGATE_RETURN(name, ...) \
+ if (cef_browser_delegate_) { \
+ return cef_browser_delegate_->name(__VA_ARGS__); \
+ }
+#define CALL_CEF_DELEGATE_RESULT(name, result, ...) \
+ if (cef_browser_delegate_) { \
+ result = cef_browser_delegate_->name(__VA_ARGS__); \
+ }
+#else // !BUILDFLAG(ENABLE_CEF)
+#define CALL_CEF_DELEGATE(name, ...)
+#define CALL_CEF_DELEGATE_RETURN(name, ...)
+#define CALL_CEF_DELEGATE_RESULT(name, result, ...)
+#endif
+
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/extension_browser_window_helper.h"
#endif
@@ -558,6 +577,10 @@ Browser::Browser(const CreateParams& params)
type_(params.type),
profile_(params.profile),
window_(nullptr),
+#if BUILDFLAG(ENABLE_CEF)
+ cef_browser_delegate_(
+ cef::BrowserDelegate::Create(this, params.cef_params, params.opener)),
+#endif
tab_strip_model_delegate_(
std::make_unique<chrome::BrowserTabStripModelDelegate>(this)),
tab_strip_model_(std::make_unique<TabStripModel>(
@@ -788,6 +811,12 @@ Browser::~Browser() {
// away so they don't try and call back to us.
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
+
+ // Clean up any objects attached via UserData before implicit destruction
+ // of CreateParams. Destruction of those objects may call into something
+ // (ProfileImpl, PrefService, etc) that will be destroyed when the last
+ // CefRequestContextImpl reference (held by CreateParams) is released.
+ ClearAllUserData();
}
///////////////////////////////////////////////////////////////////////////////
@@ -1407,6 +1436,8 @@ void Browser::WindowFullscreenStateChanged() {
->WindowFullscreenStateChanged();
command_controller_->FullscreenStateChanged();
UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
+
+ CALL_CEF_DELEGATE(WindowFullscreenStateChanged);
}
void Browser::FullscreenTopUIStateChanged() {
@@ -1726,6 +1757,14 @@ content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
if (exclusive_access_manager_->HandleUserKeyEvent(event))
return content::KeyboardEventProcessingResult::HANDLED;
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_) {
+ auto result = cef_browser_delegate_->PreHandleKeyboardEvent(source, event);
+ if (result != content::KeyboardEventProcessingResult::NOT_HANDLED)
+ return result;
+ }
+#endif
+
return window()->PreHandleKeyboardEvent(event);
}
@@ -1733,8 +1772,18 @@ bool Browser::HandleKeyboardEvent(content::WebContents* source,
const NativeWebKeyboardEvent& event) {
DevToolsWindow* devtools_window =
DevToolsWindow::GetInstanceForInspectedWebContents(source);
- return (devtools_window && devtools_window->ForwardKeyboardEvent(event)) ||
- window()->HandleKeyboardEvent(event);
+ if (devtools_window && devtools_window->ForwardKeyboardEvent(event)) {
+ return true;
+ }
+
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_ &&
+ cef_browser_delegate_->HandleKeyboardEvent(source, event)) {
+ return true;
+ }
+#endif
+
+ return window()->HandleKeyboardEvent(event);
}
bool Browser::TabsNeedBeforeUnloadFired() const {
@@ -1826,9 +1875,14 @@ bool Browser::IsBackForwardCacheSupported(content::WebContents& web_contents) {
content::PreloadingEligibility Browser::IsPrerender2Supported(
content::WebContents& web_contents) {
+#if BUILDFLAG(ENABLE_CEF)
+ // Prerender is not supported in CEF. See issue #3664.
+ return content::PreloadingEligibility::kPreloadingDisabled;
+#else
Profile* profile =
Profile::FromBrowserContext(web_contents.GetBrowserContext());
return prefetch::IsSomePreloadingEnabled(*profile->GetPrefs());
+#endif
}
bool Browser::ShouldShowStaleContentOnEviction(content::WebContents* source) {
@@ -1888,6 +1942,14 @@ WebContents* Browser::OpenURLFromTab(
std::move(navigation_handle_callback));
}
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_ &&
+ !cef_browser_delegate_->OpenURLFromTabEx(source, params,
+ navigation_handle_callback)) {
+ return nullptr;
+ }
+#endif
+
NavigateParams nav_params(this, params.url, params.transition);
nav_params.FillNavigateParamsFromOpenURLParams(params);
nav_params.source_contents = source;
@@ -2054,6 +2116,8 @@ void Browser::LoadingStateChanged(WebContents* source,
bool should_show_loading_ui) {
ScheduleUIUpdate(source, content::INVALIDATE_TYPE_LOAD);
UpdateWindowForLoadingStateChanged(source, should_show_loading_ui);
+
+ CALL_CEF_DELEGATE(LoadingStateChanged, source, should_show_loading_ui);
}
void Browser::CloseContents(WebContents* source) {
@@ -2082,6 +2146,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
}
void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
+ CALL_CEF_DELEGATE(UpdateTargetURL, source, url);
+
if (!GetStatusBubble())
return;
@@ -2089,6 +2155,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
GetStatusBubble()->SetURL(url);
}
+bool Browser::DidAddMessageToConsole(
+ content::WebContents* source,
+ blink::mojom::ConsoleMessageLevel log_level,
+ const std::u16string& message,
+ int32_t line_no,
+ const std::u16string& source_id) {
+ CALL_CEF_DELEGATE_RETURN(DidAddMessageToConsole, source, log_level, message,
+ line_no, source_id);
+ return false;
+}
+
void Browser::ContentsMouseEvent(WebContents* source, const ui::Event& event) {
const ui::EventType type = event.type();
const bool exited = type == ui::EventType::kMouseExited;
@@ -2117,6 +2194,19 @@ bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
return false;
}
+void Browser::CanDownload(const GURL& url,
+ const std::string& request_method,
+ base::OnceCallback<void(bool)> callback) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_) {
+ cef_browser_delegate_->CanDownload(url, request_method,
+ std::move(callback));
+ return;
+ }
+#endif
+ std::move(callback).Run(true);
+}
+
void Browser::BeforeUnloadFired(WebContents* web_contents,
bool proceed,
bool* proceed_to_fire_unload) {
@@ -2213,12 +2303,24 @@ void Browser::WebContentsCreated(WebContents* source_contents,
// will later be inserted into this browser using Browser::Navigate via
// AddNewContents.
TabHelpers::AttachTabHelpers(new_contents);
+
+ CALL_CEF_DELEGATE(WebContentsCreated, source_contents,
+ opener_render_process_id, opener_render_frame_id,
+ frame_name, target_url, new_contents);
}
void Browser::RendererUnresponsive(
WebContents* source,
content::RenderWidgetHost* render_widget_host,
base::RepeatingClosure hang_monitor_restarter) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_ &&
+ cef_browser_delegate_->RendererUnresponsiveEx(source, render_widget_host,
+ hang_monitor_restarter)) {
+ return;
+ }
+#endif
+
// Don't show the page hung dialog when a HTML popup hangs because
// the dialog will take the focus and immediately close the popup.
RenderWidgetHostView* view = render_widget_host->GetView();
@@ -2231,6 +2333,13 @@ void Browser::RendererUnresponsive(
void Browser::RendererResponsive(
WebContents* source,
content::RenderWidgetHost* render_widget_host) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_ &&
+ cef_browser_delegate_->RendererResponsiveEx(source, render_widget_host)) {
+ return;
+ }
+#endif
+
RenderWidgetHostView* view = render_widget_host->GetView();
if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) {
TabDialogs::FromWebContents(source)->HideHungRendererDialog(
@@ -2240,6 +2349,15 @@ void Browser::RendererResponsive(
content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager(
WebContents* source) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_) {
+ auto* cef_js_dialog_manager =
+ cef_browser_delegate_->GetJavaScriptDialogManager(source);
+ if (cef_js_dialog_manager) {
+ return cef_js_dialog_manager;
+ }
+ }
+#endif
return javascript_dialogs::TabModalDialogManager::FromWebContents(source);
}
@@ -2275,6 +2393,11 @@ void Browser::DraggableRegionsChanged(
if (app_controller_) {
app_controller_->DraggableRegionsChanged(regions, contents);
}
+#if BUILDFLAG(ENABLE_CEF)
+ else if (cef_delegate()) {
+ cef_delegate()->DraggableRegionsChanged(regions, contents);
+ }
+#endif
}
void Browser::DidFinishNavigation(
@@ -2355,11 +2478,15 @@ void Browser::EnterFullscreenModeForTab(
const blink::mojom::FullscreenOptions& options) {
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
requesting_frame, options.display_id);
+
+ CALL_CEF_DELEGATE(EnterFullscreenModeForTab, requesting_frame, options);
}
void Browser::ExitFullscreenModeForTab(WebContents* web_contents) {
exclusive_access_manager_->fullscreen_controller()->ExitFullscreenModeForTab(
web_contents);
+
+ CALL_CEF_DELEGATE(ExitFullscreenModeForTab, web_contents);
}
bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
@@ -2562,6 +2689,15 @@ void Browser::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
content::MediaResponseCallback callback) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_) {
+ callback = cef_browser_delegate_->RequestMediaAccessPermissionEx(
+ web_contents, request, std::move(callback));
+ if (callback.is_null())
+ return;
+ }
+#endif
+
const extensions::Extension* extension =
GetExtensionForOrigin(profile_, request.security_origin);
MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
@@ -3114,9 +3250,10 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
// Browser, Getters for UI (private):
StatusBubble* Browser::GetStatusBubble() {
+ bool show_by_default = true;
// For kiosk and exclusive app mode we want to always hide the status bubble.
if (IsRunningInAppMode()) {
- return nullptr;
+ show_by_default = false;
}
// We hide the status bar for web apps windows as this matches native
@@ -3124,6 +3261,12 @@ StatusBubble* Browser::GetStatusBubble() {
// mode, as the minimal browser UI includes the status bar.
if (web_app::AppBrowserController::IsWebApp(this) &&
!app_controller()->HasMinimalUiButtons()) {
+ show_by_default = false;
+ }
+
+ bool show = show_by_default;
+ CALL_CEF_DELEGATE_RESULT(ShowStatusBubble, show, show_by_default);
+ if (!show) {
return nullptr;
}
@@ -3269,6 +3412,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
web_contents_collection_.StopObserving(web_contents);
}
+
+ CALL_CEF_DELEGATE(SetAsDelegate, web_contents, set_delegate);
}
void Browser::TabDetachedAtImpl(content::WebContents* contents,
@@ -3426,6 +3571,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
bool check_can_support) const {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_delegate()) {
+ if (auto value = cef_delegate()->SupportsWindowFeature(feature)) {
+ return *value;
+ }
+ }
+#endif
+
switch (type_) {
case TYPE_NORMAL:
return NormalBrowserSupportsWindowFeature(feature, check_can_support);
diff --git chrome/browser/ui/browser.h chrome/browser/ui/browser.h
index 1455dcab97edb..eb86532470a75 100644
--- chrome/browser/ui/browser.h
+++ chrome/browser/ui/browser.h
@@ -25,6 +25,7 @@
#include "base/types/expected.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
+#include "cef/libcef/features/features.h"
#include "chrome/browser/tab_contents/web_contents_collection.h"
#include "chrome/browser/themes/theme_service_observer.h"
#include "chrome/browser/ui/bookmarks/bookmark_bar.h"
@@ -55,6 +56,10 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/shell_dialogs/select_file_dialog.h"
+#if BUILDFLAG(ENABLE_CEF)
+#include "cef/libcef/browser/chrome/browser_delegate.h"
+#endif
+
#if BUILDFLAG(IS_ANDROID)
#error This file should only be included on desktop.
#endif
@@ -339,6 +344,15 @@ class Browser : public TabStripModelObserver,
// Document Picture in Picture options, specific to TYPE_PICTURE_IN_PICTURE.
std::optional<blink::mojom::PictureInPictureWindowOptions> pip_options;
+#if BUILDFLAG(ENABLE_CEF)
+ // Opaque CEF-specific configuration. Will be propagated to new Browsers.
+ scoped_refptr<cef::BrowserDelegate::CreateParams> cef_params;
+
+ // Specify the Browser that is opening this popup.
+ // Currently only used with TYPE_PICTURE_IN_PICTURE and TYPE_DEVTOOLS.
+ raw_ptr<Browser, DanglingUntriaged> opener = nullptr;
+#endif
+
private:
friend class Browser;
friend class WindowSizerChromeOSTest;
@@ -422,6 +436,13 @@ class Browser : public TabStripModelObserver,
update_ui_immediately_for_testing_ = true;
}
+ // Return true if CEF will expose the toolbar to the client. This value is
+ // used to selectively enable toolbar behaviors such as command processing
+ // and omnibox focus without also including the toolbar in BrowserView layout
+ // calculations.
+ void set_toolbar_overridden(bool val) { toolbar_overridden_ = val; }
+ bool toolbar_overridden() const { return toolbar_overridden_; }
+
// Accessors ////////////////////////////////////////////////////////////////
const CreateParams& create_params() const { return create_params_; }
@@ -523,6 +544,12 @@ class Browser : public TabStripModelObserver,
base::WeakPtr<Browser> AsWeakPtr();
base::WeakPtr<const Browser> AsWeakPtr() const;
+#if BUILDFLAG(ENABLE_CEF)
+ cef::BrowserDelegate* cef_delegate() const {
+ return cef_browser_delegate_.get();
+ }
+#endif
+
// Get the FindBarController for this browser, creating it if it does not
// yet exist.
FindBarController* GetFindBarController();
@@ -964,10 +991,18 @@ class Browser : public TabStripModelObserver,
void SetContentsBounds(content::WebContents* source,
const gfx::Rect& bounds) override;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
+ bool DidAddMessageToConsole(content::WebContents* source,
+ blink::mojom::ConsoleMessageLevel log_level,
+ const std::u16string& message,
+ int32_t line_no,
+ const std::u16string& source_id) override;
void ContentsMouseEvent(content::WebContents* source,
const ui::Event& event) override;
void ContentsZoomChange(bool zoom_in) override;
bool TakeFocus(content::WebContents* source, bool reverse) override;
+ void CanDownload(const GURL& url,
+ const std::string& request_method,
+ base::OnceCallback<void(bool)> callback) override;
void BeforeUnloadFired(content::WebContents* source,
bool proceed,
bool* proceed_to_fire_unload) override;
@@ -1306,6 +1341,10 @@ class Browser : public TabStripModelObserver,
// This Browser's window.
raw_ptr<BrowserWindow, DanglingUntriaged> window_;
+#if BUILDFLAG(ENABLE_CEF)
+ std::unique_ptr<cef::BrowserDelegate> cef_browser_delegate_;
+#endif
+
std::unique_ptr<TabStripModelDelegate> const tab_strip_model_delegate_;
std::unique_ptr<TabStripModel> const tab_strip_model_;
@@ -1372,6 +1411,8 @@ class Browser : public TabStripModelObserver,
const std::string initial_workspace_;
bool initial_visible_on_all_workspaces_state_;
+ bool toolbar_overridden_ = false;
+
CreationSource creation_source_ = CreationSource::kUnknown;
UnloadController unload_controller_;
diff --git chrome/browser/ui/browser_navigator.cc chrome/browser/ui/browser_navigator.cc
index d26f6e2bdefd8..6c37714cc328f 100644
--- chrome/browser/ui/browser_navigator.cc
+++ chrome/browser/ui/browser_navigator.cc
@@ -260,6 +260,10 @@ std::tuple<Browser*, int> GetBrowserAndTabForDisposition(
browser_params.pip_options = pip_options;
+#if BUILDFLAG(ENABLE_CEF)
+ browser_params.opener = params.browser;
+#endif
+
const BrowserWindow* const browser_window = params.browser->window();
const gfx::NativeWindow native_window =
browser_window ? browser_window->GetNativeWindow()
@@ -547,7 +551,17 @@ std::unique_ptr<content::WebContents> CreateTargetContents(
}
#endif
- return WebContents::Create(create_params);
+ std::unique_ptr<WebContents> target_contents =
+ WebContents::Create(create_params);
+
+#if BUILDFLAG(ENABLE_CEF)
+ auto cef_delegate = params.browser->cef_delegate();
+ if (cef_delegate) {
+ cef_delegate->OnWebContentsCreated(target_contents.get());
+ }
+#endif
+
+ return target_contents;
}
bool IsHostAllowedInIncognito(const GURL& url) {
diff --git chrome/browser/ui/browser_tabstrip.cc chrome/browser/ui/browser_tabstrip.cc
index 1f84235515463..82942fb06b5f3 100644
--- chrome/browser/ui/browser_tabstrip.cc
+++ chrome/browser/ui/browser_tabstrip.cc
@@ -33,9 +33,13 @@ content::WebContents* AddAndReturnTabAt(
// Time new tab page creation time. We keep track of the timing data in
// WebContents, but we want to include the time it takes to create the
// WebContents object too.
+ // For CEF use a PageTransition that matches
+ // CefFrameHostImpl::kPageTransitionExplicit.
base::TimeTicks new_tab_start_time = base::TimeTicks::Now();
NavigateParams params(browser, url.is_empty() ? browser->GetNewTabURL() : url,
- ui::PAGE_TRANSITION_TYPED);
+ static_cast<ui::PageTransition>(
+ ui::PAGE_TRANSITION_TYPED |
+ ui::PAGE_TRANSITION_FROM_ADDRESS_BAR));
params.disposition = foreground ? WindowOpenDisposition::NEW_FOREGROUND_TAB
: WindowOpenDisposition::NEW_BACKGROUND_TAB;
params.tabstrip_index = idx;
@@ -84,6 +88,16 @@ content::WebContents* AddWebContents(
// 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 nullptr;
+ }
+ }
+#endif
+
NavigateParams params(browser, std::move(new_contents));
params.source_contents = source_contents;
params.url = target_url;