1121 lines
44 KiB
Diff
1121 lines
44 KiB
Diff
diff --git chrome/browser/ui/browser_command_controller.cc chrome/browser/ui/browser_command_controller.cc
|
|
index 14e7065d7dbd6..b01501b4253a3 100644
|
|
--- chrome/browser/ui/browser_command_controller.cc
|
|
+++ chrome/browser/ui/browser_command_controller.cc
|
|
@@ -414,6 +414,7 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
|
|
// choose to not implement CommandUpdaterDelegate inside this class and
|
|
// therefore command_updater_ doesn't have the delegate set).
|
|
if (!SupportsCommand(id) || !IsCommandEnabled(id)) {
|
|
+ LOG(WARNING) << "Invalid/disabled command " << id;
|
|
return false;
|
|
}
|
|
|
|
@@ -430,6 +431,13 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
|
|
DCHECK(command_updater_.IsCommandEnabled(id))
|
|
<< "Invalid/disabled command " << id;
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_->cef_delegate() &&
|
|
+ browser_->cef_delegate()->HandleCommand(id, disposition)) {
|
|
+ return true;
|
|
+ }
|
|
+#endif
|
|
+
|
|
// The order of commands in this switch statement must match the function
|
|
// declaration order in browser.h!
|
|
switch (id) {
|
|
@@ -1207,11 +1215,13 @@ void BrowserCommandController::TabRestoreServiceLoaded(
|
|
// BrowserCommandController, private:
|
|
|
|
bool BrowserCommandController::IsShowingMainUI() {
|
|
- return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
|
|
+ return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ||
|
|
+ browser_->toolbar_overridden();
|
|
}
|
|
|
|
bool BrowserCommandController::IsShowingLocationBar() {
|
|
- return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
|
|
+ return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR) ||
|
|
+ browser_->toolbar_overridden();
|
|
}
|
|
|
|
void BrowserCommandController::InitCommandState() {
|
|
diff --git chrome/browser/ui/toolbar/app_menu_model.cc chrome/browser/ui/toolbar/app_menu_model.cc
|
|
index 32f5ef6e5ac36..6b82915434afe 100644
|
|
--- chrome/browser/ui/toolbar/app_menu_model.cc
|
|
+++ chrome/browser/ui/toolbar/app_menu_model.cc
|
|
@@ -717,10 +717,12 @@ FindAndEditSubMenuModel::FindAndEditSubMenuModel(
|
|
ui::SimpleMenuModel::Delegate* delegate)
|
|
: SimpleMenuModel(delegate) {
|
|
AddItemWithStringIdAndVectorIcon(this, IDC_FIND, IDS_FIND, kSearchMenuIcon);
|
|
+ if (delegate->IsCommandIdVisible(IDC_EDIT_MENU)) {
|
|
AddSeparator(ui::NORMAL_SEPARATOR);
|
|
AddItemWithStringIdAndVectorIcon(this, IDC_CUT, IDS_CUT, kCutMenuIcon);
|
|
AddItemWithStringIdAndVectorIcon(this, IDC_COPY, IDS_COPY, kCopyMenuIcon);
|
|
AddItemWithStringIdAndVectorIcon(this, IDC_PASTE, IDS_PASTE, kPasteMenuIcon);
|
|
+ }
|
|
}
|
|
|
|
class SaveAndShareSubMenuModel : public ui::SimpleMenuModel {
|
|
@@ -785,6 +787,57 @@ SaveAndShareSubMenuModel::SaveAndShareSubMenuModel(
|
|
}
|
|
}
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+using IsVisibleCallback = base::RepeatingCallback<bool(int)>;
|
|
+
|
|
+void FilterMenuModel(ui::SimpleMenuModel* model,
|
|
+ const IsVisibleCallback& is_visible) {
|
|
+ std::optional<size_t> last_separator;
|
|
+ size_t visible_ct = 0;
|
|
+ for (size_t i = 0; i < model->GetItemCount(); ++i) {
|
|
+ const auto type = model->GetTypeAt(i);
|
|
+ if (type == ui::MenuModel::TYPE_SEPARATOR) {
|
|
+ if (last_separator) {
|
|
+ // Remove multiple separators in a row. Prefer to remove a NORMAL
|
|
+ // separator if possible (as compared to zoom/edit controls which use
|
|
+ // UPPER/LOWER separators).
|
|
+ if (model->GetSeparatorTypeAt(*last_separator) ==
|
|
+ ui::NORMAL_SEPARATOR) {
|
|
+ model->RemoveItemAt(*last_separator);
|
|
+ i--;
|
|
+ last_separator = i;
|
|
+ } else {
|
|
+ model->RemoveItemAt(i);
|
|
+ i--;
|
|
+ }
|
|
+ } else if (visible_ct == 0) {
|
|
+ // Remove leading separator.
|
|
+ model->RemoveItemAt(i);
|
|
+ i--;
|
|
+ } else {
|
|
+ last_separator = i;
|
|
+ }
|
|
+ visible_ct = 0;
|
|
+ } else if (is_visible.Run(model->GetCommandIdAt(i))) {
|
|
+ last_separator = absl::nullopt;
|
|
+ visible_ct++;
|
|
+
|
|
+ if (type == ui::MenuModel::TYPE_SUBMENU) {
|
|
+ // Filter sub-menu.
|
|
+ auto sub_model =
|
|
+ static_cast<ui::SimpleMenuModel*>(model->GetSubmenuModelAt(i));
|
|
+ FilterMenuModel(sub_model, is_visible);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (last_separator) {
|
|
+ // Remove trailing separator.
|
|
+ model->RemoveItemAt(*last_separator);
|
|
+ }
|
|
+}
|
|
+#endif // BUILDFLAG(ENABLE_CEF)
|
|
+
|
|
} // namespace
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1701,7 +1754,7 @@ bool AppMenuModel::IsCommandIdChecked(int command_id) const {
|
|
return false;
|
|
}
|
|
|
|
-bool AppMenuModel::IsCommandIdEnabled(int command_id) const {
|
|
+bool AppMenuModel::IsCommandIdEnabledInternal(int command_id) const {
|
|
GlobalError* error =
|
|
GlobalErrorServiceFactory::GetForProfile(browser_->profile())
|
|
->GetGlobalErrorByMenuItemCommandID(command_id);
|
|
@@ -1717,6 +1770,30 @@ bool AppMenuModel::IsCommandIdEnabled(int command_id) const {
|
|
}
|
|
}
|
|
|
|
+bool AppMenuModel::IsCommandIdEnabled(int command_id) const {
|
|
+ if (!IsCommandIdEnabledInternal(command_id)) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_->cef_delegate()) {
|
|
+ return browser_->cef_delegate()->IsAppMenuItemEnabled(command_id);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+bool AppMenuModel::IsCommandIdVisible(int command_id) const {
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_->cef_delegate()) {
|
|
+ return browser_->cef_delegate()->IsAppMenuItemVisible(command_id);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
bool AppMenuModel::IsCommandIdAlerted(int command_id) const {
|
|
if (command_id == IDC_VIEW_PASSWORDS ||
|
|
command_id == IDC_SHOW_PASSWORD_MANAGER) {
|
|
@@ -1873,8 +1950,10 @@ void AppMenuModel::Build() {
|
|
IDS_CLEAR_BROWSING_DATA,
|
|
kTrashCanRefreshIcon);
|
|
|
|
+ if (IsCommandIdVisible(IDC_ZOOM_MENU)) {
|
|
AddSeparator(ui::NORMAL_SEPARATOR);
|
|
CreateZoomMenu();
|
|
+ }
|
|
AddSeparator(ui::NORMAL_SEPARATOR);
|
|
|
|
AddItemWithStringIdAndVectorIcon(this, IDC_PRINT, IDS_PRINT, kPrintMenuIcon);
|
|
@@ -1977,6 +2056,11 @@ void AppMenuModel::Build() {
|
|
}
|
|
#endif // !BUILDFLAG(IS_CHROMEOS_ASH)
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ FilterMenuModel(this, base::BindRepeating(&AppMenuModel::IsCommandIdVisible,
|
|
+ base::Unretained(this)));
|
|
+#endif
|
|
+
|
|
uma_action_recorded_ = false;
|
|
}
|
|
|
|
diff --git chrome/browser/ui/toolbar/app_menu_model.h chrome/browser/ui/toolbar/app_menu_model.h
|
|
index 426ca35c4c814..247cfd2d99731 100644
|
|
--- chrome/browser/ui/toolbar/app_menu_model.h
|
|
+++ chrome/browser/ui/toolbar/app_menu_model.h
|
|
@@ -232,6 +232,7 @@ class AppMenuModel : public ui::SimpleMenuModel,
|
|
void ExecuteCommand(int command_id, int event_flags) override;
|
|
bool IsCommandIdChecked(int command_id) const override;
|
|
bool IsCommandIdEnabled(int command_id) const override;
|
|
+ bool IsCommandIdVisible(int command_id) const override;
|
|
bool IsCommandIdAlerted(int command_id) const override;
|
|
bool IsElementIdAlerted(ui::ElementIdentifier element_id) const override;
|
|
bool GetAcceleratorForCommandId(int command_id,
|
|
@@ -272,6 +273,8 @@ class AppMenuModel : public ui::SimpleMenuModel,
|
|
void LogSafetyHubInteractionMetrics(safety_hub::SafetyHubModuleType sh_module,
|
|
int event_flags);
|
|
|
|
+ bool IsCommandIdEnabledInternal(int command_id) const;
|
|
+
|
|
private:
|
|
// Adds actionable global error menu items to the menu.
|
|
// Examples: Extension permissions and sign in errors.
|
|
diff --git chrome/browser/ui/views/find_bar_host.cc chrome/browser/ui/views/find_bar_host.cc
|
|
index 81455e1765477..7357122b31b1d 100644
|
|
--- chrome/browser/ui/views/find_bar_host.cc
|
|
+++ chrome/browser/ui/views/find_bar_host.cc
|
|
@@ -583,6 +583,14 @@ gfx::Rect FindBarHost::GetDialogPosition(gfx::Rect avoid_overlapping_rect) {
|
|
// The BrowserView does Layout for the components that we care about
|
|
// positioning relative to, so we ask it to tell us where we should go.
|
|
gfx::Rect find_bar_bounds = browser_view_->GetFindBarBoundingBox();
|
|
+
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_view_->browser() && browser_view_->browser()->cef_delegate()) {
|
|
+ browser_view_->browser()->cef_delegate()->UpdateFindBarBoundingBox(
|
|
+ &find_bar_bounds);
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (find_bar_bounds.IsEmpty()) {
|
|
return gfx::Rect();
|
|
}
|
|
diff --git chrome/browser/ui/views/frame/browser_frame.cc chrome/browser/ui/views/frame/browser_frame.cc
|
|
index 711d389229e08..780e1b9201c72 100644
|
|
--- chrome/browser/ui/views/frame/browser_frame.cc
|
|
+++ chrome/browser/ui/views/frame/browser_frame.cc
|
|
@@ -115,15 +115,25 @@ ui::ColorProviderKey::SchemeVariant GetSchemeVariant(
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// BrowserFrame, public:
|
|
|
|
+BrowserFrame::BrowserFrame() : BrowserFrame(nullptr) {}
|
|
+
|
|
BrowserFrame::BrowserFrame(BrowserView* browser_view)
|
|
: native_browser_frame_(nullptr),
|
|
root_view_(nullptr),
|
|
browser_frame_view_(nullptr),
|
|
- browser_view_(browser_view) {
|
|
- browser_view_->set_frame(this);
|
|
+ browser_view_(nullptr) {
|
|
set_is_secondary_widget(false);
|
|
// Don't focus anything on creation, selecting a tab will set the focus.
|
|
set_focus_on_creation(false);
|
|
+ if (browser_view)
|
|
+ SetBrowserView(browser_view);
|
|
+}
|
|
+
|
|
+void BrowserFrame::SetBrowserView(BrowserView* browser_view) {
|
|
+ browser_view_ = browser_view;
|
|
+ if (browser_view_) {
|
|
+ browser_view_->set_frame(this);
|
|
+ }
|
|
}
|
|
|
|
BrowserFrame::~BrowserFrame() {}
|
|
@@ -229,10 +239,20 @@ void BrowserFrame::LayoutWebAppWindowTitle(
|
|
}
|
|
|
|
int BrowserFrame::GetTopInset() const {
|
|
+ if (!browser_frame_view_) {
|
|
+ // With CEF the browser may already be part of a larger Views layout. Zero
|
|
+ // out the adjustment in BrowserView::GetTopInsetInBrowserView() so that
|
|
+ // the browser isn't shifted to the top of the window.
|
|
+ return browser_view_->y();
|
|
+ }
|
|
return browser_frame_view_->GetTopInset(false);
|
|
}
|
|
|
|
void BrowserFrame::UpdateThrobber(bool running) {
|
|
+ if (!browser_frame_view_) {
|
|
+ // Not supported with CEF Views-hosted DevTools windows.
|
|
+ return;
|
|
+ }
|
|
browser_frame_view_->UpdateThrobber(running);
|
|
}
|
|
|
|
@@ -241,6 +261,8 @@ BrowserNonClientFrameView* BrowserFrame::GetFrameView() const {
|
|
}
|
|
|
|
bool BrowserFrame::UseCustomFrame() const {
|
|
+ if (!native_browser_frame_)
|
|
+ return true;
|
|
return native_browser_frame_->UseCustomFrame();
|
|
}
|
|
|
|
@@ -255,20 +277,30 @@ bool BrowserFrame::ShouldDrawFrameHeader() const {
|
|
void BrowserFrame::GetWindowPlacement(
|
|
gfx::Rect* bounds,
|
|
ui::mojom::WindowShowState* show_state) const {
|
|
+ if (!native_browser_frame_) {
|
|
+ *show_state = ui::mojom::WindowShowState::kDefault;
|
|
+ return;
|
|
+ }
|
|
return native_browser_frame_->GetWindowPlacement(bounds, show_state);
|
|
}
|
|
|
|
content::KeyboardEventProcessingResult BrowserFrame::PreHandleKeyboardEvent(
|
|
const input::NativeWebKeyboardEvent& event) {
|
|
+ if (!native_browser_frame_)
|
|
+ return content::KeyboardEventProcessingResult::NOT_HANDLED;
|
|
return native_browser_frame_->PreHandleKeyboardEvent(event);
|
|
}
|
|
|
|
bool BrowserFrame::HandleKeyboardEvent(
|
|
const input::NativeWebKeyboardEvent& event) {
|
|
+ if (!native_browser_frame_)
|
|
+ return false;
|
|
return native_browser_frame_->HandleKeyboardEvent(event);
|
|
}
|
|
|
|
void BrowserFrame::OnBrowserViewInitViewsComplete() {
|
|
+ if (!browser_frame_view_)
|
|
+ return;
|
|
browser_frame_view_->OnBrowserViewInitViewsComplete();
|
|
}
|
|
|
|
@@ -369,6 +401,8 @@ ui::ColorProviderKey::ThemeInitializerSupplier* BrowserFrame::GetCustomTheme()
|
|
}
|
|
|
|
void BrowserFrame::OnNativeWidgetWorkspaceChanged() {
|
|
+ if (!browser_view_)
|
|
+ return;
|
|
chrome::SaveWindowWorkspace(browser_view_->browser(), GetWorkspace());
|
|
chrome::SaveWindowVisibleOnAllWorkspaces(browser_view_->browser(),
|
|
IsVisibleOnAllWorkspaces());
|
|
@@ -575,6 +609,13 @@ void BrowserFrame::SelectNativeTheme() {
|
|
return;
|
|
}
|
|
|
|
+ // Always use the NativeTheme for forced color modes.
|
|
+ if (ui::NativeTheme::IsForcedDarkMode() ||
|
|
+ ui::NativeTheme::IsForcedLightMode()) {
|
|
+ SetNativeTheme(native_theme);
|
|
+ return;
|
|
+ }
|
|
+
|
|
// Ignore the system theme for web apps with window-controls-overlay as the
|
|
// display_override so the web contents can blend with the overlay by using
|
|
// the developer-provided theme color for a better experience. Context:
|
|
@@ -640,5 +681,8 @@ bool BrowserFrame::RegenerateFrameOnThemeChange(
|
|
}
|
|
|
|
bool BrowserFrame::IsIncognitoBrowser() const {
|
|
+ if (!browser_view_) {
|
|
+ return true;
|
|
+ }
|
|
return browser_view_->browser()->profile()->IsIncognitoProfile();
|
|
}
|
|
diff --git chrome/browser/ui/views/frame/browser_frame.h chrome/browser/ui/views/frame/browser_frame.h
|
|
index 532705a04c47b..0272f27596df6 100644
|
|
--- chrome/browser/ui/views/frame/browser_frame.h
|
|
+++ chrome/browser/ui/views/frame/browser_frame.h
|
|
@@ -59,6 +59,7 @@ enum class TabDragKind {
|
|
// This is a virtual interface that allows system specific browser frames.
|
|
class BrowserFrame : public views::Widget, public views::ContextMenuController {
|
|
public:
|
|
+ BrowserFrame();
|
|
explicit BrowserFrame(BrowserView* browser_view);
|
|
|
|
BrowserFrame(const BrowserFrame&) = delete;
|
|
@@ -138,7 +139,7 @@ class BrowserFrame : public views::Widget, public views::ContextMenuController {
|
|
|
|
// ThemeService calls this when a user has changed their theme, indicating
|
|
// that it's time to redraw everything.
|
|
- void UserChangedTheme(BrowserThemeChangeType theme_change_type);
|
|
+ virtual void UserChangedTheme(BrowserThemeChangeType theme_change_type);
|
|
|
|
// views::Widget:
|
|
views::internal::RootView* CreateRootView() override;
|
|
@@ -171,22 +172,26 @@ class BrowserFrame : public views::Widget, public views::ContextMenuController {
|
|
void SetTabDragKind(TabDragKind tab_drag_kind);
|
|
TabDragKind tab_drag_kind() const { return tab_drag_kind_; }
|
|
|
|
+ BrowserView* browser_view() const { return browser_view_.get(); }
|
|
+
|
|
protected:
|
|
+ void SetBrowserView(BrowserView* browser_view);
|
|
+
|
|
// views::Widget:
|
|
void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override;
|
|
ui::ColorProviderKey GetColorProviderKey() const override;
|
|
|
|
+ // Select a native theme that is appropriate for the current context. This is
|
|
+ // currently only needed for Linux to switch between the regular NativeTheme
|
|
+ // and the GTK NativeTheme instance.
|
|
+ void SelectNativeTheme();
|
|
+
|
|
private:
|
|
void OnTouchUiChanged();
|
|
|
|
// Callback for MenuRunner.
|
|
void OnMenuClosed();
|
|
|
|
- // Select a native theme that is appropriate for the current context. This is
|
|
- // currently only needed for Linux to switch between the regular NativeTheme
|
|
- // and the GTK NativeTheme instance.
|
|
- void SelectNativeTheme();
|
|
-
|
|
// Regenerate the frame on theme change if necessary. Returns true if
|
|
// regenerated.
|
|
bool RegenerateFrameOnThemeChange(BrowserThemeChangeType theme_change_type);
|
|
diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
|
|
index 8c08f4c3f10fa..721a7b1d5f136 100644
|
|
--- chrome/browser/ui/views/frame/browser_view.cc
|
|
+++ chrome/browser/ui/views/frame/browser_view.cc
|
|
@@ -366,10 +366,6 @@ constexpr base::FeatureParam<base::TimeDelta> kLoadingTabAnimationFrameDelay = {
|
|
&kChangeFrameRateOfLoadingTabAnimation, "loading_tab_animation_frame_delay",
|
|
base::Milliseconds(30)};
|
|
|
|
-// The name of a key to store on the window handle so that other code can
|
|
-// locate this object using just the handle.
|
|
-const char* const kBrowserViewKey = "__BROWSER_VIEW__";
|
|
-
|
|
#if BUILDFLAG(IS_CHROMEOS_ASH)
|
|
// UMA histograms that record animation smoothness for tab loading animation.
|
|
constexpr char kTabLoadingSmoothnessHistogramName[] =
|
|
@@ -769,6 +765,14 @@ class BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate {
|
|
return browser_view_->frame()->GetTopInset() - browser_view_->y();
|
|
}
|
|
|
|
+ void UpdateDialogTopInsetInBrowserView(int* dialog_top_y) const override {
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (auto cef_delegate = browser_view_->browser_->cef_delegate()) {
|
|
+ cef_delegate->UpdateDialogTopInset(dialog_top_y);
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+
|
|
bool IsToolbarVisible() const override {
|
|
return browser_view_->IsToolbarVisible();
|
|
}
|
|
@@ -920,11 +924,21 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// BrowserView, public:
|
|
|
|
+BrowserView::BrowserView() : BrowserView(nullptr) {}
|
|
+
|
|
BrowserView::BrowserView(std::unique_ptr<Browser> browser)
|
|
: views::ClientView(nullptr, nullptr),
|
|
- browser_(std::move(browser)),
|
|
accessibility_mode_observer_(
|
|
std::make_unique<AccessibilityModeObserver>(this)) {
|
|
+ if (browser) {
|
|
+ InitBrowser(std::move(browser));
|
|
+ }
|
|
+}
|
|
+
|
|
+void BrowserView::InitBrowser(std::unique_ptr<Browser> browser) {
|
|
+ DCHECK(!browser_);
|
|
+ browser_ = std::move(browser);
|
|
+
|
|
SetShowIcon(
|
|
::ShouldShowWindowIcon(browser_.get(), AppUsesWindowControlsOverlay()));
|
|
|
|
@@ -1014,8 +1028,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
|
|
contents_container->SetLayoutManager(std::make_unique<ContentsLayoutManager>(
|
|
devtools_web_view_, contents_web_view_, watermark_view_));
|
|
|
|
- toolbar_ = top_container_->AddChildView(
|
|
- std::make_unique<ToolbarView>(browser_.get(), this));
|
|
+ toolbar_ = OverrideCreateToolbar();
|
|
+ if (!toolbar_) {
|
|
+ toolbar_ = new ToolbarView(browser_.get(), this, std::nullopt);
|
|
+ } else {
|
|
+ browser_->set_toolbar_overridden(true);
|
|
+ // Update state that depends on the above flag.
|
|
+ browser_->command_controller()->FullscreenStateChanged();
|
|
+ }
|
|
+ top_container_->AddChildView(base::WrapUnique(toolbar_.get()));
|
|
|
|
contents_separator_ =
|
|
top_container_->AddChildView(std::make_unique<ContentsSeparator>());
|
|
@@ -1095,7 +1116,9 @@ void BrowserView::ToggleCompactModeUI() {
|
|
}
|
|
|
|
BrowserView::~BrowserView() {
|
|
+ if (browser_) {
|
|
browser_->GetFeatures().TearDownPreBrowserViewDestruction();
|
|
+ }
|
|
|
|
// Destroy the top controls slide controller first as it depends on the
|
|
// tabstrip model and the browser frame.
|
|
@@ -1103,7 +1126,9 @@ BrowserView::~BrowserView() {
|
|
|
|
// All the tabs should have been destroyed already. If we were closed by the
|
|
// OS with some tabs than the NativeBrowserFrame should have destroyed them.
|
|
+ if (browser_) {
|
|
DCHECK_EQ(0, browser_->tab_strip_model()->count());
|
|
+ }
|
|
|
|
// Stop the animation timer explicitly here to avoid running it in a nested
|
|
// message loop, which may run by Browser destructor.
|
|
@@ -1112,17 +1137,18 @@ BrowserView::~BrowserView() {
|
|
// Immersive mode may need to reparent views before they are removed/deleted.
|
|
immersive_mode_controller_.reset();
|
|
|
|
- // Reset autofill bubble handler to make sure it does not out-live toolbar,
|
|
- // since it is responsible for showing autofill related bubbles from toolbar's
|
|
- // child views and it is an observer for avatar toolbar button if any.
|
|
- autofill_bubble_handler_.reset();
|
|
+ // If the Toolbar is not overloaded it will be destroyed via
|
|
+ // RemoveAllChildViews().
|
|
+ WillDestroyToolbar();
|
|
|
|
+ if (browser_) {
|
|
auto* global_registry =
|
|
extensions::ExtensionCommandsGlobalRegistry::Get(browser_->profile());
|
|
if (global_registry->registry_for_active_window() ==
|
|
extension_keybinding_registry_.get()) {
|
|
global_registry->set_registry_for_active_window(nullptr);
|
|
}
|
|
+ }
|
|
|
|
// These are raw pointers to child views, so they need to be set to null
|
|
// before `RemoveAllChildViews()` is called to avoid dangling.
|
|
@@ -1703,6 +1729,16 @@ gfx::Point BrowserView::GetThemeOffsetFromBrowserView() const {
|
|
ThemeProperties::kFrameHeightAboveTabs - browser_view_origin.y());
|
|
}
|
|
|
|
+void BrowserView::WillDestroyToolbar() {
|
|
+ // Reset autofill bubble handler to make sure it does not out-live toolbar,
|
|
+ // since it is responsible for showing autofill related bubbles from toolbar's
|
|
+ // child views and it is an observer for avatar toolbar button if any.
|
|
+ autofill_bubble_handler_.reset();
|
|
+
|
|
+ toolbar_ = nullptr;
|
|
+ toolbar_button_provider_ = nullptr;
|
|
+}
|
|
+
|
|
// static:
|
|
BrowserView::DevToolsDockedPlacement BrowserView::GetDevToolsDockedPlacement(
|
|
const gfx::Rect& contents_webview_bounds,
|
|
@@ -2118,9 +2154,14 @@ void BrowserView::OnExclusiveAccessUserInput() {
|
|
|
|
bool BrowserView::ShouldHideUIForFullscreen() const {
|
|
// Immersive mode needs UI for the slide-down top panel.
|
|
- if (immersive_mode_controller_->IsEnabled())
|
|
+ // Avoid callback into |immersive_mode_controller_| during construction.
|
|
+ // See CEF issue #3527.
|
|
+ if (immersive_mode_controller_ &&
|
|
+ immersive_mode_controller_->IsEnabled())
|
|
return false;
|
|
|
|
+ if (!frame_->GetFrameView())
|
|
+ return false;
|
|
return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
|
|
}
|
|
|
|
@@ -3308,7 +3349,8 @@ views::View* BrowserView::GetTopContainer() {
|
|
}
|
|
|
|
DownloadBubbleUIController* BrowserView::GetDownloadBubbleUIController() {
|
|
- DCHECK(toolbar_button_provider_);
|
|
+ if (!toolbar_button_provider_)
|
|
+ return nullptr;
|
|
if (auto* download_button = toolbar_button_provider_->GetDownloadButton())
|
|
return download_button->bubble_controller();
|
|
return nullptr;
|
|
@@ -3890,7 +3932,8 @@ void BrowserView::ReparentTopContainerForEndOfImmersive() {
|
|
if (top_container()->parent() == this)
|
|
return;
|
|
|
|
- overlay_view_->SetVisible(false);
|
|
+ if (overlay_view_)
|
|
+ overlay_view_->SetVisible(false);
|
|
top_container()->DestroyLayer();
|
|
AddChildViewAt(top_container(), 0);
|
|
EnsureFocusOrder();
|
|
@@ -4381,11 +4424,38 @@ void BrowserView::GetAccessiblePanes(std::vector<views::View*>* panes) {
|
|
bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
|
gfx::NativeView child,
|
|
const gfx::Point& location) {
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ const bool frameless_pip =
|
|
+ GetIsPictureInPictureType() &&
|
|
+ !browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR);
|
|
+ if (frameless_pip) {
|
|
+ if (auto frame_view = frame()->GetFrameView()) {
|
|
+ int result = frame_view->NonClientHitTest(location);
|
|
+ if (result == HTTOP || result == HTTOPLEFT || result == HTTOPRIGHT) {
|
|
+ // Allow resize from the top of a frameless window.
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ std::optional<SkRegion> draggable_region;
|
|
+
|
|
// Window for PWAs with window-controls-overlay display override should claim
|
|
// mouse events that fall within the draggable region.
|
|
web_app::AppBrowserController* controller = browser()->app_controller();
|
|
- if (AreDraggableRegionsEnabled() && controller &&
|
|
- controller->draggable_region().has_value()) {
|
|
+ if (AreDraggableRegionsEnabled() && controller) {
|
|
+ draggable_region = controller->draggable_region();
|
|
+ }
|
|
+
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ // Match logic in PictureInPictureBrowserFrameView::NonClientHitTest.
|
|
+ if (!draggable_region.has_value() && frameless_pip) {
|
|
+ draggable_region = browser_->cef_delegate()->GetDraggableRegion();
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (draggable_region.has_value()) {
|
|
// Draggable regions are defined relative to the web contents.
|
|
gfx::Point point_in_contents_web_view_coords(location);
|
|
views::View::ConvertPointToTarget(GetWidget()->GetRootView(),
|
|
@@ -4394,7 +4464,7 @@ bool BrowserView::ShouldDescendIntoChildForEventHandling(
|
|
|
|
// Draggable regions should be ignored for clicks into any browser view's
|
|
// owned widgets, for example alerts, permission prompts or find bar.
|
|
- return !controller->draggable_region()->contains(
|
|
+ return !draggable_region->contains(
|
|
point_in_contents_web_view_coords.x(),
|
|
point_in_contents_web_view_coords.y()) ||
|
|
WidgetOwnedByAnchorContainsPoint(point_in_contents_web_view_coords);
|
|
@@ -4505,8 +4575,10 @@ void BrowserView::Layout(PassKey) {
|
|
|
|
// TODO(jamescook): Why was this in the middle of layout code?
|
|
toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
|
|
- IsToolbarVisible() ? FocusBehavior::ALWAYS : FocusBehavior::NEVER);
|
|
- frame()->GetFrameView()->UpdateMinimumSize();
|
|
+ (IsToolbarVisible() || browser_->toolbar_overridden()) ?
|
|
+ FocusBehavior::ALWAYS : FocusBehavior::NEVER);
|
|
+ if (frame()->GetFrameView())
|
|
+ frame()->GetFrameView()->UpdateMinimumSize();
|
|
|
|
// Some of the situations when the BrowserView is laid out are:
|
|
// - Enter/exit immersive fullscreen mode.
|
|
@@ -4572,6 +4644,11 @@ void BrowserView::AddedToWidget() {
|
|
SetThemeProfileForWindow(GetNativeWindow(), browser_->profile());
|
|
#endif
|
|
|
|
+ // This browser view may already have a custom button provider set (e.g the
|
|
+ // hosted app frame).
|
|
+ if (!toolbar_button_provider_)
|
|
+ SetToolbarButtonProvider(toolbar_);
|
|
+
|
|
toolbar_->Init();
|
|
|
|
// TODO(pbos): Investigate whether the side panels should be creatable when
|
|
@@ -4614,13 +4691,9 @@ void BrowserView::AddedToWidget() {
|
|
|
|
EnsureFocusOrder();
|
|
|
|
- // This browser view may already have a custom button provider set (e.g the
|
|
- // hosted app frame).
|
|
- if (!toolbar_button_provider_)
|
|
- SetToolbarButtonProvider(toolbar_);
|
|
-
|
|
frame_->OnBrowserViewInitViewsComplete();
|
|
- frame_->GetFrameView()->UpdateMinimumSize();
|
|
+ if (frame_->GetFrameView())
|
|
+ frame_->GetFrameView()->UpdateMinimumSize();
|
|
using_native_frame_ = frame_->ShouldUseNativeFrame();
|
|
|
|
MaybeInitializeWebUITabStrip();
|
|
@@ -5006,7 +5079,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen, const int64_t display_id) {
|
|
// Undo our anti-jankiness hacks and force a re-layout.
|
|
in_process_fullscreen_ = false;
|
|
ToolbarSizeChanged(false);
|
|
- frame_->GetFrameView()->OnFullscreenStateChanged();
|
|
+ if (frame_->GetFrameView())
|
|
+ frame_->GetFrameView()->OnFullscreenStateChanged();
|
|
}
|
|
|
|
void BrowserView::RequestFullscreen(bool fullscreen, int64_t display_id) {
|
|
@@ -5512,6 +5586,8 @@ Profile* BrowserView::GetProfile() {
|
|
}
|
|
|
|
void BrowserView::UpdateUIForTabFullscreen() {
|
|
+ if (!frame_->GetFrameView())
|
|
+ return;
|
|
frame()->GetFrameView()->UpdateFullscreenTopUI();
|
|
}
|
|
|
|
@@ -5534,6 +5610,8 @@ void BrowserView::HideDownloadShelf() {
|
|
}
|
|
|
|
bool BrowserView::CanUserExitFullscreen() const {
|
|
+ if (!frame_->GetFrameView())
|
|
+ return true;
|
|
return frame_->GetFrameView()->CanUserExitFullscreen();
|
|
}
|
|
|
|
diff --git chrome/browser/ui/views/frame/browser_view.h chrome/browser/ui/views/frame/browser_view.h
|
|
index bdb273f5134b8..2750336aca016 100644
|
|
--- chrome/browser/ui/views/frame/browser_view.h
|
|
+++ chrome/browser/ui/views/frame/browser_view.h
|
|
@@ -139,11 +139,16 @@ class BrowserView : public BrowserWindow,
|
|
METADATA_HEADER(BrowserView, views::ClientView)
|
|
|
|
public:
|
|
+ BrowserView();
|
|
explicit BrowserView(std::unique_ptr<Browser> browser);
|
|
+ void InitBrowser(std::unique_ptr<Browser> browser);
|
|
BrowserView(const BrowserView&) = delete;
|
|
BrowserView& operator=(const BrowserView&) = delete;
|
|
~BrowserView() override;
|
|
|
|
+ // Key used to bind BrowserView to the Widget with which it is associated.
|
|
+ static constexpr char kBrowserViewKey[] = "__BROWSER_VIEW__";
|
|
+
|
|
void set_frame(BrowserFrame* frame) {
|
|
frame_ = frame;
|
|
paint_as_active_subscription_ =
|
|
@@ -841,6 +846,10 @@ class BrowserView : public BrowserWindow,
|
|
void Copy();
|
|
void Paste();
|
|
|
|
+ // Called during Toolbar destruction to remove dependent objects that have
|
|
+ // dangling references.
|
|
+ virtual void WillDestroyToolbar();
|
|
+
|
|
protected:
|
|
// Enumerates where the devtools are docked relative to the browser's main
|
|
// web contents.
|
|
@@ -864,6 +873,8 @@ class BrowserView : public BrowserWindow,
|
|
const gfx::Rect& contents_webview_bounds,
|
|
const gfx::Rect& local_webview_container_bounds);
|
|
|
|
+ virtual ToolbarView* OverrideCreateToolbar() { return nullptr; }
|
|
+
|
|
private:
|
|
// Do not friend BrowserViewLayout. Use the BrowserViewLayoutDelegate
|
|
// interface to keep these two classes decoupled and testable.
|
|
diff --git chrome/browser/ui/views/frame/browser_view_layout.cc chrome/browser/ui/views/frame/browser_view_layout.cc
|
|
index 148c255ec04d3..edce177e093ac 100644
|
|
--- chrome/browser/ui/views/frame/browser_view_layout.cc
|
|
+++ chrome/browser/ui/views/frame/browser_view_layout.cc
|
|
@@ -53,6 +53,10 @@
|
|
#include "ui/views/window/client_view.h"
|
|
#include "ui/views/window/hit_test_utils.h"
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/views/chrome_views_util.h"
|
|
+#endif
|
|
+
|
|
using views::View;
|
|
using web_modal::ModalDialogHostObserver;
|
|
using web_modal::WebContentsModalDialogHost;
|
|
@@ -103,6 +107,10 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
|
observer_list_.Notify(&ModalDialogHostObserver::OnHostDestroying);
|
|
}
|
|
|
|
+ bool HasObservers() const {
|
|
+ return !observer_list_.empty();
|
|
+ }
|
|
+
|
|
void NotifyPositionRequiresUpdate() {
|
|
observer_list_.Notify(&ModalDialogHostObserver::OnPositionRequiresUpdate);
|
|
}
|
|
@@ -112,7 +120,7 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
|
views::View* view = browser_view_layout_->contents_container_;
|
|
gfx::Rect rect = view->ConvertRectToWidget(view->GetLocalBounds());
|
|
const int middle_x = rect.x() + rect.width() / 2;
|
|
- const int top = browser_view_layout_->dialog_top_y_;
|
|
+ const int top = GetDialogTopY();
|
|
return gfx::Point(middle_x - size.width() / 2, top);
|
|
}
|
|
|
|
@@ -135,7 +143,7 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
|
// universally.
|
|
views::View* view = browser_view_layout_->contents_container_;
|
|
gfx::Rect content_area = view->ConvertRectToWidget(view->GetLocalBounds());
|
|
- const int top = browser_view_layout_->dialog_top_y_;
|
|
+ const int top = GetDialogTopY();
|
|
return gfx::Size(content_area.width(), content_area.bottom() - top);
|
|
}
|
|
|
|
@@ -164,6 +172,13 @@ class BrowserViewLayout::WebContentsModalDialogHostViews
|
|
return host_widget ? host_widget->GetNativeView() : nullptr;
|
|
}
|
|
|
|
+ int GetDialogTopY() const {
|
|
+ int dialog_top_y = browser_view_layout_->dialog_top_y_;
|
|
+ browser_view_layout_->delegate_->UpdateDialogTopInsetInBrowserView(
|
|
+ &dialog_top_y);
|
|
+ return dialog_top_y;
|
|
+ }
|
|
+
|
|
// Add/remove observer.
|
|
void AddObserver(ModalDialogHostObserver* observer) override {
|
|
observer_list_.AddObserver(observer);
|
|
@@ -477,6 +492,8 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
|
|
if (exclusive_access_bubble)
|
|
exclusive_access_bubble->RepositionIfVisible();
|
|
|
|
+ // Avoid unnecessary calls to UpdateDialogTopInsetInBrowserView().
|
|
+ if (dialog_host_->HasObservers()) {
|
|
// Adjust any hosted dialogs if the browser's dialog hosting bounds changed.
|
|
const gfx::Rect dialog_bounds(dialog_host_->GetDialogPosition(gfx::Size()),
|
|
dialog_host_->GetMaximumDialogSize());
|
|
@@ -490,6 +507,7 @@ void BrowserViewLayout::Layout(views::View* browser_view) {
|
|
latest_dialog_bounds_in_screen_ = dialog_bounds_in_screen;
|
|
dialog_host_->NotifyPositionRequiresUpdate();
|
|
}
|
|
+ }
|
|
}
|
|
|
|
gfx::Size BrowserViewLayout::GetPreferredSize(
|
|
@@ -631,6 +649,13 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
|
|
|
|
int BrowserViewLayout::LayoutToolbar(int top) {
|
|
TRACE_EVENT0("ui", "BrowserViewLayout::LayoutToolbar");
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (cef::IsCefView(toolbar_)) {
|
|
+ // CEF may take ownership of the toolbar. Early exit to avoid the DCHECK
|
|
+ // in LayoutManager::SetViewVisibility().
|
|
+ return top;
|
|
+ }
|
|
+#endif
|
|
int browser_view_width = vertical_layout_rect_.width();
|
|
bool toolbar_visible = delegate_->IsToolbarVisible();
|
|
int height = toolbar_visible ? toolbar_->GetPreferredSize().height() : 0;
|
|
diff --git chrome/browser/ui/views/frame/browser_view_layout_delegate.h chrome/browser/ui/views/frame/browser_view_layout_delegate.h
|
|
index 06ff29d3f9b27..65301b6ecf076 100644
|
|
--- chrome/browser/ui/views/frame/browser_view_layout_delegate.h
|
|
+++ chrome/browser/ui/views/frame/browser_view_layout_delegate.h
|
|
@@ -28,6 +28,7 @@ class BrowserViewLayoutDelegate {
|
|
const gfx::Rect& available_space,
|
|
views::Label& window_title_label) const = 0;
|
|
virtual int GetTopInsetInBrowserView() const = 0;
|
|
+ virtual void UpdateDialogTopInsetInBrowserView(int* dialog_top_y) const = 0;
|
|
virtual bool IsToolbarVisible() const = 0;
|
|
virtual bool IsBookmarkBarVisible() const = 0;
|
|
virtual bool IsContentsSeparatorEnabled() const = 0;
|
|
diff --git chrome/browser/ui/views/frame/contents_web_view.cc chrome/browser/ui/views/frame/contents_web_view.cc
|
|
index 71445bfab1824..c77750ea2a820 100644
|
|
--- chrome/browser/ui/views/frame/contents_web_view.cc
|
|
+++ chrome/browser/ui/views/frame/contents_web_view.cc
|
|
@@ -28,6 +28,12 @@ ContentsWebView::ContentsWebView(content::BrowserContext* browser_context)
|
|
: views::WebView(browser_context),
|
|
status_bubble_(nullptr) {
|
|
SetProperty(views::kElementIdentifierKey, kContentsWebViewElementId);
|
|
+
|
|
+ // Mouse events on draggable regions will not be handled by the WebView.
|
|
+ // Avoid the resulting DCHECK in NativeViewHost::OnMousePressed by
|
|
+ // configuring the NativeViewHost not to process events via the view
|
|
+ // hierarchy.
|
|
+ holder()->SetCanProcessEventsWithinSubtree(false);
|
|
}
|
|
|
|
ContentsWebView::~ContentsWebView() {
|
|
diff --git chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
|
|
index 3489ec2810cdf..db6881a0e2923 100644
|
|
--- chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
|
|
+++ chrome/browser/ui/views/frame/picture_in_picture_browser_frame_view.cc
|
|
@@ -618,6 +618,11 @@ PictureInPictureBrowserFrameView::PictureInPictureBrowserFrameView(
|
|
return window->GetProperty(chromeos::kWindowStateTypeKey);
|
|
})));
|
|
#endif
|
|
+
|
|
+ if (!browser_view->browser()->SupportsWindowFeature(
|
|
+ Browser::FEATURE_TITLEBAR)) {
|
|
+ top_bar_container_view_->SetVisible(false);
|
|
+ }
|
|
}
|
|
|
|
PictureInPictureBrowserFrameView::~PictureInPictureBrowserFrameView() {
|
|
@@ -745,18 +750,42 @@ gfx::Rect PictureInPictureBrowserFrameView::GetWindowBoundsForClientBounds(
|
|
|
|
int PictureInPictureBrowserFrameView::NonClientHitTest(
|
|
const gfx::Point& point) {
|
|
- // Allow interacting with the buttons.
|
|
- if (GetLocationIconViewBounds().Contains(point) ||
|
|
- GetBackToTabControlsBounds().Contains(point) ||
|
|
- GetCloseControlsBounds().Contains(point)) {
|
|
- return HTCLIENT;
|
|
+ const bool frameless = !top_bar_container_view_->GetVisible();
|
|
+ if (!frameless) {
|
|
+ // Allow interacting with the buttons.
|
|
+ if (GetLocationIconViewBounds().Contains(point) ||
|
|
+ GetBackToTabControlsBounds().Contains(point) ||
|
|
+ GetCloseControlsBounds().Contains(point)) {
|
|
+ return HTCLIENT;
|
|
+ }
|
|
+
|
|
+ for (size_t i = 0; i < content_setting_views_.size(); i++) {
|
|
+ if (GetContentSettingViewBounds(i).Contains(point)) {
|
|
+ return HTCLIENT;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
- for (size_t i = 0; i < content_setting_views_.size(); i++) {
|
|
- if (GetContentSettingViewBounds(i).Contains(point)) {
|
|
- return HTCLIENT;
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (frameless) {
|
|
+ // Match logic in BrowserView::ShouldDescendIntoChildForEventHandling.
|
|
+ const auto draggable_region =
|
|
+ browser_view()->browser()->cef_delegate()->GetDraggableRegion();
|
|
+ if (draggable_region.has_value()) {
|
|
+ // Draggable regions are defined relative to the web contents.
|
|
+ gfx::Point point_in_contents_web_view_coords(point);
|
|
+ views::View::ConvertPointToTarget(GetWidget()->GetRootView(),
|
|
+ browser_view()->contents_web_view(),
|
|
+ &point_in_contents_web_view_coords);
|
|
+
|
|
+ if (draggable_region->contains(
|
|
+ point_in_contents_web_view_coords.x(),
|
|
+ point_in_contents_web_view_coords.y())) {
|
|
+ return HTCAPTION;
|
|
+ }
|
|
}
|
|
}
|
|
+#endif // BUILDFLAG(ENABLE_CEF)
|
|
|
|
// Allow dragging and resizing the window.
|
|
int window_component = GetHTComponentForFrame(
|
|
@@ -825,7 +854,8 @@ void PictureInPictureBrowserFrameView::Layout(PassKey) {
|
|
gfx::Rect content_area = GetLocalBounds();
|
|
content_area.Inset(FrameBorderInsets());
|
|
gfx::Rect top_bar = content_area;
|
|
- top_bar.set_height(kTopControlsHeight);
|
|
+ top_bar.set_height(
|
|
+ top_bar_container_view_->GetVisible() ? kTopControlsHeight : 0);
|
|
top_bar_container_view_->SetBoundsRect(top_bar);
|
|
#if !BUILDFLAG(IS_ANDROID)
|
|
if (auto_pip_setting_overlay_) {
|
|
@@ -1371,7 +1401,8 @@ gfx::Insets PictureInPictureBrowserFrameView::ResizeBorderInsets() const {
|
|
}
|
|
|
|
int PictureInPictureBrowserFrameView::GetTopAreaHeight() const {
|
|
- return FrameBorderInsets().top() + kTopControlsHeight;
|
|
+ return FrameBorderInsets().top() +
|
|
+ (top_bar_container_view_->GetVisible() ? kTopControlsHeight : 0);
|
|
}
|
|
|
|
gfx::Size PictureInPictureBrowserFrameView::GetNonClientViewAreaSize() const {
|
|
diff --git chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc
|
|
index 33c6444869375..d74818698d81a 100644
|
|
--- chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc
|
|
+++ chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc
|
|
@@ -27,7 +27,8 @@ OmniboxPopupCloser::OmniboxPopupCloser(BrowserView* browser_view)
|
|
OmniboxPopupCloser::~OmniboxPopupCloser() = default;
|
|
|
|
void OmniboxPopupCloser::OnMouseEvent(ui::MouseEvent* event) {
|
|
- if (!browser_view_->browser()->is_delete_scheduled() &&
|
|
+ if (browser_view_->browser() &&
|
|
+ !browser_view_->browser()->is_delete_scheduled() &&
|
|
event->type() == ui::EventType::kMousePressed) {
|
|
LocationBarView* location_bar_view = browser_view_->GetLocationBarView();
|
|
CHECK(location_bar_view);
|
|
diff --git chrome/browser/ui/views/page_action/page_action_icon_controller.cc chrome/browser/ui/views/page_action/page_action_icon_controller.cc
|
|
index 40993f5460555..3bf4fb49b71f3 100644
|
|
--- chrome/browser/ui/views/page_action/page_action_icon_controller.cc
|
|
+++ chrome/browser/ui/views/page_action/page_action_icon_controller.cc
|
|
@@ -98,6 +98,12 @@ void PageActionIconController::Init(const PageActionIconParams& params,
|
|
};
|
|
|
|
for (PageActionIconType type : params.types_enabled) {
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (params.browser && params.browser->cef_delegate() &&
|
|
+ !params.browser->cef_delegate()->IsPageActionIconVisible(type)) {
|
|
+ continue;
|
|
+ }
|
|
+#endif
|
|
switch (type) {
|
|
case PageActionIconType::kPaymentsOfferNotification:
|
|
add_page_action_icon(
|
|
diff --git chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
|
|
index a80a496c99a26..7cb24bf8505de 100644
|
|
--- chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
|
|
+++ chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
|
|
@@ -604,29 +604,41 @@ gfx::Range BrowserTabStripController::ListTabsInGroup(
|
|
}
|
|
|
|
bool BrowserTabStripController::IsFrameCondensed() const {
|
|
+ if (!GetFrameView())
|
|
+ return false;
|
|
return GetFrameView()->IsFrameCondensed();
|
|
}
|
|
|
|
bool BrowserTabStripController::HasVisibleBackgroundTabShapes() const {
|
|
+ if (!GetFrameView())
|
|
+ return false;
|
|
return GetFrameView()->HasVisibleBackgroundTabShapes(
|
|
BrowserFrameActiveState::kUseCurrent);
|
|
}
|
|
|
|
bool BrowserTabStripController::EverHasVisibleBackgroundTabShapes() const {
|
|
+ if (!GetFrameView())
|
|
+ return false;
|
|
return GetFrameView()->EverHasVisibleBackgroundTabShapes();
|
|
}
|
|
|
|
bool BrowserTabStripController::CanDrawStrokes() const {
|
|
+ if (!GetFrameView())
|
|
+ return false;
|
|
return GetFrameView()->CanDrawStrokes();
|
|
}
|
|
|
|
SkColor BrowserTabStripController::GetFrameColor(
|
|
BrowserFrameActiveState active_state) const {
|
|
+ if (!GetFrameView())
|
|
+ return SK_ColorWHITE;
|
|
return GetFrameView()->GetFrameColor(active_state);
|
|
}
|
|
|
|
std::optional<int> BrowserTabStripController::GetCustomBackgroundId(
|
|
BrowserFrameActiveState active_state) const {
|
|
+ if (!GetFrameView())
|
|
+ return std::nullopt;
|
|
return GetFrameView()->GetCustomBackgroundId(active_state);
|
|
}
|
|
|
|
diff --git chrome/browser/ui/views/toolbar/toolbar_view.cc chrome/browser/ui/views/toolbar/toolbar_view.cc
|
|
index 1b494d20b6342..c3eb67da3c3ba 100644
|
|
--- chrome/browser/ui/views/toolbar/toolbar_view.cc
|
|
+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
|
|
@@ -193,7 +193,7 @@ class TabstripLikeBackground : public views::Background {
|
|
void Paint(gfx::Canvas* canvas, views::View* view) const override {
|
|
bool painted = TopContainerBackground::PaintThemeCustomImage(canvas, view,
|
|
browser_view_);
|
|
- if (!painted) {
|
|
+ if (!painted && browser_view_->frame()->GetFrameView()) {
|
|
SkColor frame_color =
|
|
browser_view_->frame()->GetFrameView()->GetFrameColor(
|
|
BrowserFrameActiveState::kUseCurrent);
|
|
@@ -224,12 +224,13 @@ END_METADATA
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// ToolbarView, public:
|
|
|
|
-ToolbarView::ToolbarView(Browser* browser, BrowserView* browser_view)
|
|
+ToolbarView::ToolbarView(Browser* browser, BrowserView* browser_view,
|
|
+ std::optional<DisplayMode> display_mode)
|
|
: AnimationDelegateViews(this),
|
|
browser_(browser),
|
|
browser_view_(browser_view),
|
|
app_menu_icon_controller_(browser->profile(), this),
|
|
- display_mode_(GetDisplayMode(browser)) {
|
|
+ display_mode_(display_mode ? *display_mode : GetDisplayMode(browser)) {
|
|
SetID(VIEW_ID_TOOLBAR);
|
|
|
|
container_view_ = AddChildView(std::make_unique<ContainerView>());
|
|
@@ -258,9 +259,24 @@ ToolbarView::~ToolbarView() {
|
|
|
|
for (const auto& view_and_command : GetViewCommandMap())
|
|
chrome::RemoveCommandObserver(browser_, view_and_command.second, this);
|
|
+
|
|
+ browser_view_->WillDestroyToolbar();
|
|
}
|
|
|
|
void ToolbarView::Init() {
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ using ToolbarButtonType = cef::BrowserDelegate::ToolbarButtonType;
|
|
+ auto button_visible = [this](ToolbarButtonType type) {
|
|
+ if (this->browser_->cef_delegate()) {
|
|
+ return this->browser_->cef_delegate()->IsToolbarButtonVisible(type);
|
|
+ }
|
|
+ return true;
|
|
+ };
|
|
+ #define BUTTON_VISIBLE(type) button_visible(ToolbarButtonType::type)
|
|
+#else
|
|
+ #define BUTTON_VISIBLE(type) true
|
|
+#endif
|
|
+
|
|
#if defined(USE_AURA)
|
|
// Avoid generating too many occlusion tracking calculation events before this
|
|
// function returns. The occlusion status will be computed only once once this
|
|
@@ -283,12 +299,12 @@ void ToolbarView::Init() {
|
|
|
|
auto location_bar = std::make_unique<LocationBarView>(
|
|
browser_, browser_->profile(), browser_->command_controller(), this,
|
|
- display_mode_ != DisplayMode::NORMAL);
|
|
+ display_mode_ != DisplayMode::NORMAL && !browser_->toolbar_overridden());
|
|
// Make sure the toolbar shows by default.
|
|
size_animation_.Reset(1);
|
|
|
|
std::unique_ptr<DownloadToolbarButtonView> download_button;
|
|
- if (download::IsDownloadBubbleEnabled()) {
|
|
+ if (download::IsDownloadBubbleEnabled() && BUTTON_VISIBLE(kDownload)) {
|
|
download_button =
|
|
std::make_unique<DownloadToolbarButtonView>(browser_view_);
|
|
}
|
|
@@ -370,7 +386,8 @@ void ToolbarView::Init() {
|
|
std::unique_ptr<media_router::CastToolbarButton> cast;
|
|
if (!(features::IsToolbarPinningEnabled() &&
|
|
base::FeatureList::IsEnabled(features::kPinnedCastButton))) {
|
|
- if (media_router::MediaRouterEnabled(browser_->profile())) {
|
|
+ if (media_router::MediaRouterEnabled(browser_->profile()) &&
|
|
+ BUTTON_VISIBLE(kCast)) {
|
|
cast = media_router::CastToolbarButton::Create(browser_);
|
|
}
|
|
}
|
|
@@ -383,7 +400,8 @@ void ToolbarView::Init() {
|
|
|
|
std::unique_ptr<send_tab_to_self::SendTabToSelfToolbarIconView>
|
|
send_tab_to_self_button;
|
|
- if (!browser_->profile()->IsOffTheRecord()) {
|
|
+ if (!browser_->profile()->IsOffTheRecord() &&
|
|
+ BUTTON_VISIBLE(kSendTabToSelf)) {
|
|
send_tab_to_self_button =
|
|
std::make_unique<send_tab_to_self::SendTabToSelfToolbarIconView>(
|
|
browser_view_);
|
|
@@ -845,7 +863,8 @@ void ToolbarView::Layout(PassKey) {
|
|
|
|
if (display_mode_ == DisplayMode::NORMAL) {
|
|
LayoutCommon();
|
|
- UpdateClipPath();
|
|
+ if (!browser_->toolbar_overridden())
|
|
+ UpdateClipPath();
|
|
}
|
|
|
|
if (toolbar_controller_) {
|
|
diff --git chrome/browser/ui/views/toolbar/toolbar_view.h chrome/browser/ui/views/toolbar/toolbar_view.h
|
|
index b02224437ad20..81f639f5faf9f 100644
|
|
--- chrome/browser/ui/views/toolbar/toolbar_view.h
|
|
+++ chrome/browser/ui/views/toolbar/toolbar_view.h
|
|
@@ -94,7 +94,8 @@ class ToolbarView : public views::AccessiblePaneView,
|
|
// needs to be displayed.
|
|
};
|
|
|
|
- ToolbarView(Browser* browser, BrowserView* browser_view);
|
|
+ ToolbarView(Browser* browser, BrowserView* browser_view,
|
|
+ std::optional<DisplayMode> display_mode);
|
|
ToolbarView(const ToolbarView&) = delete;
|
|
ToolbarView& operator=(const ToolbarView&) = delete;
|
|
~ToolbarView() override;
|