mirror of
https://github.com/aphrody-labs/cef.git
synced 2026-10-14 05:09:23 +00:00
win: dxil.dll is no longer distributed mac: Xcode 27 (macOS 26.6+) is now required
1250 lines
51 KiB
Diff
1250 lines
51 KiB
Diff
diff --git chrome/browser/ui/browser_command_controller.cc chrome/browser/ui/browser_command_controller.cc
|
|
index 921461b9e9bd0423d6d180762d0a06d0a3cd9c94..06c7fb432c8da0ccf3b70806b568c776e222a90e 100644
|
|
--- chrome/browser/ui/browser_command_controller.cc
|
|
+++ chrome/browser/ui/browser_command_controller.cc
|
|
@@ -198,6 +198,10 @@
|
|
#include "chrome/browser/ui/shortcuts/desktop_shortcuts_utils.h"
|
|
#endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN)
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/browser_util.h"
|
|
+#endif
|
|
+
|
|
static_assert(BUILDFLAG(ENABLE_EXTENSIONS));
|
|
|
|
using Extension = extensions::Extension;
|
|
@@ -554,6 +558,12 @@ void BrowserCommandController::ContentRestrictionsChanged() {
|
|
|
|
void BrowserCommandController::FullscreenStateChanged() {
|
|
UpdateCommandsForFullscreenMode();
|
|
+
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_->cef_delegate()) {
|
|
+ browser_->cef_delegate()->WindowFullscreenStateChanged();
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
#if BUILDFLAG(IS_CHROMEOS)
|
|
@@ -641,6 +651,7 @@ bool BrowserCommandController::ExecuteCommandWithDispositionAndContext(
|
|
std::optional<actions::ActionInvocationContext> context,
|
|
base::TimeTicks time_stamp) {
|
|
if (!SupportsCommand(id) || !IsCommandEnabled(id)) {
|
|
+ LOG(WARNING) << "Invalid/disabled command " << id;
|
|
return false;
|
|
}
|
|
|
|
@@ -667,6 +678,13 @@ void BrowserCommandController::HandleCommandWithDisposition(
|
|
base::TimeTicks time_stamp) {
|
|
DCHECK(IsCommandEnabled(id)) << "Invalid/disabled command " << id;
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_->cef_delegate() &&
|
|
+ browser_->cef_delegate()->HandleCommand(id, disposition)) {
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+
|
|
// The order of commands in this switch statement must match the function
|
|
// declaration order in browser.h!
|
|
switch (id) {
|
|
@@ -1712,12 +1730,14 @@ void BrowserCommandController::TabRestoreServiceLoaded(
|
|
|
|
bool BrowserCommandController::IsShowingMainUI() {
|
|
return WindowFeatureController::From(browser_)->SupportsWindowFeature(
|
|
- WindowFeatureController::WindowFeature::kFeatureTabStrip);
|
|
+ WindowFeatureController::WindowFeature::kFeatureTabStrip) ||
|
|
+ cef::BrowserForBWI(browser_)->toolbar_overridden();
|
|
}
|
|
|
|
bool BrowserCommandController::IsShowingLocationBar() {
|
|
return WindowFeatureController::From(browser_)->SupportsWindowFeature(
|
|
- WindowFeatureController::WindowFeature::kFeatureLocationBar);
|
|
+ WindowFeatureController::WindowFeature::kFeatureLocationBar) ||
|
|
+ cef::BrowserForBWI(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 faaded8ad5427c95787fde91961ae6d543902336..292beca4fb2c1ccfb4804acc9cc5151a68d62ad2 100644
|
|
--- chrome/browser/ui/toolbar/app_menu_model.cc
|
|
+++ chrome/browser/ui/toolbar/app_menu_model.cc
|
|
@@ -190,6 +190,10 @@
|
|
#include "content/public/browser/gpu_data_manager.h"
|
|
#endif
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/browser_delegate.h"
|
|
+#endif
|
|
+
|
|
using base::UserMetricsAction;
|
|
using content::WebContents;
|
|
|
|
@@ -778,18 +782,20 @@ FindAndEditSubMenuModel::FindAndEditSubMenuModel(
|
|
AddItemWithStringIdAndVectorIcon(
|
|
this, IDC_FIND, IDS_FIND,
|
|
features::IsRoundedIconsEnabled() ? kFindInPageIcon : kSearchMenuOldIcon);
|
|
- AddSeparator(ui::NORMAL_SEPARATOR);
|
|
- AddItemWithStringIdAndVectorIcon(
|
|
- this, IDC_CUT, IDS_CUT,
|
|
- features::IsRoundedIconsEnabled() ? kContentCutIcon : kCutMenuOldIcon);
|
|
- AddItemWithStringIdAndVectorIcon(this, IDC_COPY, IDS_COPY,
|
|
- features::IsRoundedIconsEnabled()
|
|
- ? vector_icons::kContentCopyIcon
|
|
- : kCopyMenuOldIcon);
|
|
- AddItemWithStringIdAndVectorIcon(this, IDC_PASTE, IDS_PASTE,
|
|
- features::IsRoundedIconsEnabled()
|
|
- ? kContentPasteIcon
|
|
- : kPasteMenuOldIcon);
|
|
+ if (delegate->IsCommandIdVisible(AppMenuModel::kEditMenuPlaceholder)) {
|
|
+ AddSeparator(ui::NORMAL_SEPARATOR);
|
|
+ AddItemWithStringIdAndVectorIcon(
|
|
+ this, IDC_CUT, IDS_CUT,
|
|
+ features::IsRoundedIconsEnabled() ? kContentCutIcon : kCutMenuOldIcon);
|
|
+ AddItemWithStringIdAndVectorIcon(this, IDC_COPY, IDS_COPY,
|
|
+ features::IsRoundedIconsEnabled()
|
|
+ ? vector_icons::kContentCopyIcon
|
|
+ : kCopyMenuOldIcon);
|
|
+ AddItemWithStringIdAndVectorIcon(this, IDC_PASTE, IDS_PASTE,
|
|
+ features::IsRoundedIconsEnabled()
|
|
+ ? kContentPasteIcon
|
|
+ : kPasteMenuOldIcon);
|
|
+ }
|
|
}
|
|
|
|
class SaveAndShareSubMenuModel : public ui::SimpleMenuModel {
|
|
@@ -932,6 +938,57 @@ bool ArePromotionsEnabled() {
|
|
return local_state && local_state->GetBoolean(prefs::kPromotionsEnabled);
|
|
}
|
|
|
|
+#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 = std::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
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -2019,7 +2076,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_->GetProfile())
|
|
->GetGlobalErrorByMenuItemCommandID(command_id);
|
|
@@ -2037,6 +2094,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) {
|
|
@@ -2277,8 +2358,10 @@ void AppMenuModel::Build() {
|
|
SetElementIdentifierAt(GetIndexOfCommandId(IDC_CLEAR_BROWSING_DATA).value(),
|
|
kClearBrowsingDataMenuItem);
|
|
|
|
- AddSeparator(ui::NORMAL_SEPARATOR);
|
|
- CreateZoomMenu();
|
|
+ if (IsCommandIdVisible(AppMenuModel::kZoomMenuPlaceholder)) {
|
|
+ AddSeparator(ui::NORMAL_SEPARATOR);
|
|
+ CreateZoomMenu();
|
|
+ }
|
|
AddSeparator(ui::NORMAL_SEPARATOR);
|
|
|
|
AddItemWithStringIdAndVectorIcon(
|
|
@@ -2431,6 +2514,11 @@ void AppMenuModel::Build() {
|
|
}
|
|
#endif // !BUILDFLAG(IS_CHROMEOS)
|
|
|
|
+#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 7fd1446d69240e26e347487b69998da389b33d7b..59ee3acdf8870bddf7b1c6981fcc618540efde36 100644
|
|
--- chrome/browser/ui/toolbar/app_menu_model.h
|
|
+++ chrome/browser/ui/toolbar/app_menu_model.h
|
|
@@ -310,6 +310,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 GetAcceleratorForCommandId(int command_id,
|
|
ui::Accelerator* accelerator) const override;
|
|
@@ -349,6 +350,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/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
|
|
index b68f089aebf83b82499611404433d430e9971f14..6123e7fe79ad94eac0b7c248d4907a588995b4c0 100644
|
|
--- chrome/browser/ui/views/frame/browser_view.cc
|
|
+++ chrome/browser/ui/views/frame/browser_view.cc
|
|
@@ -419,6 +419,10 @@
|
|
#undef LoadAccelerators
|
|
#endif
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/browser_util.h"
|
|
+#endif
|
|
+
|
|
using base::UserMetricsAction;
|
|
using content::WebContents;
|
|
using input::NativeWebKeyboardEvent;
|
|
@@ -890,11 +894,21 @@ class BrowserView::PipExclusionObserverImpl
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// BrowserView, public:
|
|
|
|
+BrowserView::BrowserView() : BrowserView(nullptr) {}
|
|
+
|
|
BrowserView::BrowserView(BrowserWindowInterface* browser)
|
|
: views::ClientView(nullptr, nullptr),
|
|
exclusive_access_context_(
|
|
- std::make_unique<ExclusiveAccessContextImpl>(*this)),
|
|
- browser_(browser) {
|
|
+ std::make_unique<ExclusiveAccessContextImpl>(*this)) {
|
|
+ if (browser) {
|
|
+ InitBrowser(browser);
|
|
+ }
|
|
+}
|
|
+
|
|
+void BrowserView::InitBrowser(BrowserWindowInterface* browser) {
|
|
+ DCHECK(!browser_);
|
|
+ browser_ = browser;
|
|
+
|
|
if (auto* manager = InitialWebUIWindowMetricsManager::From(browser_.get())) {
|
|
manager->OnBrowserWindowCreated();
|
|
}
|
|
@@ -921,7 +935,8 @@ BrowserView::BrowserView(BrowserWindowInterface* browser)
|
|
SetCanMinimize(false);
|
|
SetCanMaximize(false);
|
|
SetCanFullscreen(false);
|
|
- SetCanResize(true);
|
|
+ SetCanResize(
|
|
+ BrowserInitState::From(&*browser_)->create_params().can_resize);
|
|
} else {
|
|
SetCanResize(
|
|
BrowserInitState::From(&*browser_)->create_params().can_resize);
|
|
@@ -945,8 +960,16 @@ BrowserView::BrowserView(BrowserWindowInterface* browser)
|
|
top_container_ = AddChildView(std::make_unique<TopContainerView>(this));
|
|
top_container_insertion_index_ = GetIndexOf(top_container_.get());
|
|
|
|
- toolbar_ = top_container_->AddChildView(
|
|
- std::make_unique<ToolbarView>(browser_.get(), this));
|
|
+ toolbar_ = OverrideCreateToolbar();
|
|
+ if (!toolbar_) {
|
|
+ toolbar_ = new ToolbarView(browser_.get(), this, std::nullopt);
|
|
+ } else {
|
|
+ cef::BrowserForBWI(browser_.get())->set_toolbar_overridden(true);
|
|
+ // Update state that depends on the above flag.
|
|
+ chrome::BrowserCommandController::From(browser_.get())
|
|
+ ->FullscreenStateChanged();
|
|
+ }
|
|
+ top_container_->AddChildView(base::WrapUnique(toolbar_.get()));
|
|
|
|
top_container_separator_ = top_container_->AddChildView(
|
|
ContentsSeparator::CreateContentsSeparator());
|
|
@@ -1108,6 +1131,10 @@ BrowserView::BrowserView(BrowserWindowInterface* browser)
|
|
}
|
|
|
|
BrowserView::~BrowserView() {
|
|
+ // If the Toolbar is not overloaded it will be destroyed via
|
|
+ // RemoveAllChildViews().
|
|
+ WillDestroyToolbar();
|
|
+
|
|
// Remove the layout manager to avoid dangling. This needs to be earlier than
|
|
// other cleanups that destroy views referenced in the layout manager.
|
|
SetLayoutManager(nullptr);
|
|
@@ -1122,7 +1149,9 @@ BrowserView::~BrowserView() {
|
|
|
|
// All the tabs should have been destroyed already. If we were closed by the
|
|
// OS with some tabs than the BrowserNativeWidget should have destroyed them.
|
|
- DCHECK_EQ(0, browser_->GetTabStripModel()->count());
|
|
+ if (browser_) {
|
|
+ DCHECK_EQ(0, browser_->GetTabStripModel()->count());
|
|
+ }
|
|
|
|
// Stop the animation timer explicitly here to avoid running it in a nested
|
|
// message loop, which may run by Browser destructor.
|
|
@@ -1221,7 +1250,7 @@ void BrowserView::SetDisableRevealerDelayForTesting(bool disable) {
|
|
g_disable_revealer_delay_for_testing = disable;
|
|
}
|
|
|
|
-gfx::Rect BrowserView::GetFindBarBoundingBox() const {
|
|
+gfx::Rect BrowserView::GetFindBarBoundingBoxImpl() const {
|
|
gfx::Rect contents_bounds = multi_contents_view_->ConvertRectToWidget(
|
|
multi_contents_view_->GetLocalBounds());
|
|
|
|
@@ -1243,6 +1272,16 @@ gfx::Rect BrowserView::GetFindBarBoundingBox() const {
|
|
return multi_contents_view_->GetMirroredRect(contents_bounds);
|
|
}
|
|
|
|
+gfx::Rect BrowserView::GetFindBarBoundingBox() const {
|
|
+ auto bounds = GetFindBarBoundingBoxImpl();
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser() && browser()->cef_delegate()) {
|
|
+ browser()->cef_delegate()->UpdateFindBarBoundingBox(&bounds);
|
|
+ }
|
|
+#endif
|
|
+ return bounds;
|
|
+}
|
|
+
|
|
ClientFrameElementInfo BrowserView::GetFrameElementInfo() const {
|
|
// We want to return tabstrip_->height(), but we might be called in the midst
|
|
// of layout, when that hasn't yet been updated to reflect the current state.
|
|
@@ -1967,6 +2006,27 @@ 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();
|
|
+
|
|
+ if (GetBrowserViewLayout()) {
|
|
+ GetBrowserViewLayout()->reset_toolbar();
|
|
+ }
|
|
+
|
|
+ if (toolbar_ && toolbar_->parent()) {
|
|
+ // Remove now instead of waiting for RemoveAllChildViews(), as there is
|
|
+ // otherwise no guarantee that the Toolbar will be removed before the
|
|
+ // BrowserView is removed (and destroyed).
|
|
+ toolbar_->parent()->RemoveChildView(toolbar_);
|
|
+ toolbar_.ClearAndDelete();
|
|
+ } else {
|
|
+ toolbar_ = nullptr;
|
|
+ }
|
|
+}
|
|
+
|
|
bool BrowserView::IsLoadingAnimationRunning() const {
|
|
return !loading_animation_start_.is_null();
|
|
}
|
|
@@ -3174,6 +3234,9 @@ ShowTranslateBubbleResult BrowserView::ShowTranslateBubble(
|
|
|
|
DownloadBubbleUIController* BrowserView::GetDownloadBubbleUIController() {
|
|
#if !BUILDFLAG(IS_CHROMEOS)
|
|
+ if (!browser_) {
|
|
+ return nullptr;
|
|
+ }
|
|
if (auto* download_controller =
|
|
DownloadToolbarUIController::From(browser_.get())) {
|
|
return download_controller->bubble_controller();
|
|
@@ -4095,7 +4158,10 @@ bool BrowserView::GetSavedWindowPlacement(
|
|
}
|
|
|
|
views::View* BrowserView::GetContentsView() {
|
|
- return multi_contents_view_->GetActiveContentsView();
|
|
+ if (multi_contents_view_) {
|
|
+ return multi_contents_view_->GetActiveContentsView();
|
|
+ }
|
|
+ return nullptr;
|
|
}
|
|
|
|
views::ClientView* BrowserView::CreateClientView(views::Widget* widget) {
|
|
@@ -4272,9 +4338,22 @@ void BrowserView::DeleteBrowserWindow() {
|
|
// before the frame is destroyed to mitigate UAF risk.
|
|
browser_widget_->SaveWindowPlacementIfNeeded();
|
|
|
|
- browser_widget_.reset();
|
|
- // BrowserWidget owns BrowserView in its views::View hierarchy and `this` will
|
|
- // not be valid after this returns.
|
|
+ const bool views_hosted =
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ browser() && browser()->cef_delegate() &&
|
|
+ browser()->cef_delegate()->IsViewsHosted();
|
|
+#else
|
|
+ false;
|
|
+#endif
|
|
+
|
|
+ if (views_hosted) {
|
|
+ // The BrowserWidget is owned by CefWindowWidgetDelegate.
|
|
+ browser_widget_.release();
|
|
+ } else {
|
|
+ browser_widget_.reset();
|
|
+ // BrowserWidget owns BrowserView in its views::View hierarchy and `this`
|
|
+ // will not be valid after this returns.
|
|
+ }
|
|
}
|
|
|
|
void BrowserView::SetForceShowBookmarkBarFlag(
|
|
@@ -4532,12 +4611,39 @@ 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() &&
|
|
+ !WindowFeatureController::From(browser_.get())
|
|
+ ->SupportsWindowFeature(
|
|
+ WindowFeatureController::WindowFeature::kFeatureTitleBar);
|
|
+ if (frameless_pip) {
|
|
+ int result = GetFrameView()->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 =
|
|
web_app::AppBrowserController::From(browser());
|
|
- 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()) {
|
|
gfx::Point point_in_browser_view_coords(location);
|
|
views::View::ConvertPointToTarget(GetWidget()->GetRootView(), this,
|
|
&point_in_browser_view_coords);
|
|
@@ -4550,9 +4656,8 @@ 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(
|
|
- point_in_contents_web_view_coords.x(),
|
|
- point_in_contents_web_view_coords.y()) ||
|
|
+ return !draggable_region->contains(point_in_contents_web_view_coords.x(),
|
|
+ point_in_contents_web_view_coords.y()) ||
|
|
WidgetOwnedByAnchorContainsPoint(point_in_browser_view_coords);
|
|
}
|
|
|
|
@@ -4888,7 +4993,9 @@ void BrowserView::Layout(PassKey) {
|
|
LayoutSuperclass<views::View>(this);
|
|
|
|
// TODO(jamescook): Why was this in the middle of layout code?
|
|
- toolbar_->location_bar()->UpdateFocusBehavior(IsToolbarVisible());
|
|
+ toolbar_->location_bar()->UpdateFocusBehavior(
|
|
+ IsToolbarVisible() ||
|
|
+ cef::BrowserForBWI(browser_.get())->toolbar_overridden());
|
|
GetFrameView()->UpdateMinimumSize();
|
|
|
|
if (omnibox::IsWebUIOmniboxInBrowserViewEnabled()) {
|
|
@@ -5176,6 +5283,16 @@ void BrowserView::AddedToWidget() {
|
|
fallback_popup_anchor_ = std::make_unique<views::ViewSubregionAnchor>(
|
|
kFallbackPopupAnchorElementId, *this);
|
|
|
|
+ if (browser_->GetWindow()) {
|
|
+ // Initialize the browser features that rely on the browser window now that
|
|
+ // it is initialized. This will instead be called from the Browser
|
|
+ // constructor for default Chrome UI windows.
|
|
+ // TODO(cef): Remove BrowserForBWI cast once InitPostWindowConstruction
|
|
+ // takes BrowserWindowInterface* (upstream change pending).
|
|
+ browser_->GetFeatures().InitPostWindowConstruction(
|
|
+ cef::BrowserForBWI(browser_.get()));
|
|
+ }
|
|
+
|
|
initialized_ = true;
|
|
}
|
|
|
|
diff --git chrome/browser/ui/views/frame/browser_view.h chrome/browser/ui/views/frame/browser_view.h
|
|
index 6c4807bbaaf0a8e12e1a2df8545b4b55f491c297..9cc40ae854a363a98f1c8f3b7be44d0ab366957d 100644
|
|
--- chrome/browser/ui/views/frame/browser_view.h
|
|
+++ chrome/browser/ui/views/frame/browser_view.h
|
|
@@ -151,7 +151,9 @@ class BrowserView : public BrowserWindow,
|
|
// locate this object using just the handle.
|
|
static constexpr char kBrowserViewKey[] = "__BROWSER_VIEW__";
|
|
|
|
+ BrowserView();
|
|
explicit BrowserView(BrowserWindowInterface* browser);
|
|
+ void InitBrowser(BrowserWindowInterface* browser);
|
|
BrowserView(const BrowserView&) = delete;
|
|
BrowserView& operator=(const BrowserView&) = delete;
|
|
~BrowserView() override;
|
|
@@ -823,10 +825,16 @@ class BrowserView : public BrowserWindow,
|
|
bool IsLockedFullscreen() const;
|
|
#endif
|
|
|
|
- protected:
|
|
+ // Called during Toolbar destruction to remove dependent objects that have
|
|
+ // dangling references.
|
|
+ virtual void WillDestroyToolbar();
|
|
+
|
|
// BrowserWindow:
|
|
void DeleteBrowserWindow() final;
|
|
|
|
+ protected:
|
|
+ virtual ToolbarView* OverrideCreateToolbar() { return nullptr; }
|
|
+
|
|
private:
|
|
// Do not friend BrowserViewLayout. Use the BrowserViewLayoutDelegate
|
|
// interface to keep these two classes decoupled and testable.
|
|
@@ -1093,11 +1101,13 @@ class BrowserView : public BrowserWindow,
|
|
class ExclusiveAccessContextImpl;
|
|
std::unique_ptr<ExclusiveAccessContextImpl> exclusive_access_context_;
|
|
|
|
+ gfx::Rect GetFindBarBoundingBoxImpl() const;
|
|
+
|
|
// The BrowserWidget that owns this view.
|
|
std::unique_ptr<BrowserWidget> browser_widget_;
|
|
|
|
// The owning BrowserWindowInterface object. `browser_` will outlive this.
|
|
- const raw_ptr<BrowserWindowInterface> browser_;
|
|
+ raw_ptr<BrowserWindowInterface> browser_;
|
|
|
|
base::CallbackListSubscription chip_visibility_subscription_;
|
|
|
|
diff --git chrome/browser/ui/views/frame/browser_widget.cc chrome/browser/ui/views/frame/browser_widget.cc
|
|
index 6a221594b09f0b8fa10e4b8bbca05a0e52e52a58..e1037567bb95ec02defe4c08890439a22a1fbcda 100644
|
|
--- chrome/browser/ui/views/frame/browser_widget.cc
|
|
+++ chrome/browser/ui/views/frame/browser_widget.cc
|
|
@@ -100,16 +100,29 @@ bool IsUsingLinuxSystemTheme(Profile* profile) {
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// BrowserWidget, public:
|
|
|
|
+BrowserWidget::BrowserWidget() : BrowserWidget(nullptr) {}
|
|
+
|
|
BrowserWidget::BrowserWidget(BrowserView* browser_view)
|
|
: browser_native_widget_(nullptr),
|
|
root_view_(nullptr),
|
|
browser_frame_view_(nullptr),
|
|
- browser_view_(browser_view) {
|
|
+ browser_view_(nullptr) {
|
|
// Don't focus anything on creation, selecting a tab will set the focus.
|
|
set_focus_on_creation(false);
|
|
+ if (browser_view) {
|
|
+ SetBrowserView(browser_view);
|
|
+ }
|
|
views::WidgetStationarityMonitor::GetInstance().TrackWidget(*this);
|
|
}
|
|
|
|
+void BrowserWidget::SetBrowserFrameView(BrowserFrameView* browser_frame_view) {
|
|
+ browser_frame_view_ = browser_frame_view;
|
|
+}
|
|
+
|
|
+void BrowserWidget::SetBrowserView(BrowserView* browser_view) {
|
|
+ browser_view_ = browser_view;
|
|
+}
|
|
+
|
|
BrowserWidget::~BrowserWidget() {
|
|
set_widget_closed();
|
|
|
|
@@ -128,7 +141,11 @@ BrowserWidget::~BrowserWidget() {
|
|
// Do this here and not in ~BrowserView() as BrowserWindowFeatures may attempt
|
|
// to read state on the BrowserWidget as they undergo destruction, and
|
|
// BrowserWidget state is destroyed at the end of this scope.
|
|
- browser_view_->browser()->GetFeatures().TearDownPreBrowserWindowDestruction();
|
|
+ if (browser_view_ && browser_view_->browser()) {
|
|
+ browser_view_->browser()
|
|
+ ->GetFeatures()
|
|
+ .TearDownPreBrowserWindowDestruction();
|
|
+ }
|
|
}
|
|
|
|
void BrowserWidget::InitBrowserWidget() {
|
|
@@ -253,6 +270,8 @@ void BrowserWidget::GetWindowPlacement(
|
|
ui::mojom::WindowShowState* show_state) const {
|
|
if (browser_native_widget_) {
|
|
browser_native_widget_->GetWindowPlacement(bounds, show_state);
|
|
+ } else {
|
|
+ *show_state = ui::mojom::WindowShowState::kDefault;
|
|
}
|
|
}
|
|
|
|
@@ -385,6 +404,9 @@ ui::ColorProviderKey::ThemeInitializerSupplier* BrowserWidget::GetCustomTheme()
|
|
}
|
|
|
|
void BrowserWidget::OnNativeWidgetWorkspaceChanged() {
|
|
+ if (!browser_view_) {
|
|
+ return;
|
|
+ }
|
|
chrome::SaveWindowWorkspace(browser_view_->browser(), GetWorkspace());
|
|
chrome::SaveWindowVisibleOnAllWorkspaces(browser_view_->browser(),
|
|
IsVisibleOnAllWorkspaces());
|
|
@@ -553,6 +575,13 @@ void BrowserWidget::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:
|
|
@@ -567,17 +596,23 @@ void BrowserWidget::SelectNativeTheme() {
|
|
}
|
|
|
|
void BrowserWidget::OnTouchUiChanged() {
|
|
- client_view()->InvalidateLayout();
|
|
-
|
|
- // For standard browser frame, if we do not invalidate the FrameView
|
|
- // the client window bounds will not be properly updated which could cause
|
|
- // visual artifacts. See crbug.com/40112464 for details.
|
|
- if (non_client_view()->frame_view()) {
|
|
- // Note that invalidating a view invalidates all of its ancestors, so it is
|
|
- // not necessary to also invalidate the NonClientView or RootView here.
|
|
- non_client_view()->frame_view()->InvalidateLayout();
|
|
- } else {
|
|
- non_client_view()->InvalidateLayout();
|
|
+ // client_view() is null when there is no NonClientView (e.g. CEF Chrome-style
|
|
+ // browsers with a native parent use TYPE_CONTROL). See CEF issue #3941.
|
|
+ if (client_view()) {
|
|
+ client_view()->InvalidateLayout();
|
|
+ }
|
|
+
|
|
+ if (non_client_view()) {
|
|
+ // For standard browser frame, if we do not invalidate the FrameView
|
|
+ // the client window bounds will not be properly updated which could cause
|
|
+ // visual artifacts. See crbug.com/40112464 for details.
|
|
+ if (non_client_view()->frame_view()) {
|
|
+ // Note that invalidating a view invalidates all of its ancestors, so it
|
|
+ // is not necessary to also invalidate the NonClientView or RootView here.
|
|
+ non_client_view()->frame_view()->InvalidateLayout();
|
|
+ } else {
|
|
+ non_client_view()->InvalidateLayout();
|
|
+ }
|
|
}
|
|
GetRootView()->InvalidateLayout();
|
|
}
|
|
@@ -616,6 +651,9 @@ bool BrowserWidget::RegenerateFrameOnThemeChange(
|
|
}
|
|
|
|
bool BrowserWidget::IsIncognitoBrowser() const {
|
|
+ if (!browser_view_) {
|
|
+ return true;
|
|
+ }
|
|
return browser_view_->browser()->GetProfile()->IsIncognitoProfile();
|
|
}
|
|
|
|
diff --git chrome/browser/ui/views/frame/browser_widget.h chrome/browser/ui/views/frame/browser_widget.h
|
|
index d384a2c99a1c1d8f160de20ea8518a6a4cc5ab71..39937dca7434763b3baa82600c7c9e73a6c01573 100644
|
|
--- chrome/browser/ui/views/frame/browser_widget.h
|
|
+++ chrome/browser/ui/views/frame/browser_widget.h
|
|
@@ -58,6 +58,7 @@ enum class TabDragKind {
|
|
class BrowserWidget : public views::Widget,
|
|
public views::ContextMenuController {
|
|
public:
|
|
+ BrowserWidget();
|
|
explicit BrowserWidget(BrowserView* browser_view);
|
|
|
|
BrowserWidget(const BrowserWidget&) = delete;
|
|
@@ -98,7 +99,7 @@ class BrowserWidget : public views::Widget,
|
|
|
|
// 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;
|
|
@@ -132,11 +133,21 @@ class BrowserWidget : public views::Widget,
|
|
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 SetBrowserFrameView(BrowserFrameView* browser_frame_view);
|
|
+ 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:
|
|
const ui::ThemeProvider* GetBaseThemeProvider() const;
|
|
|
|
@@ -146,11 +157,6 @@ class BrowserWidget : public views::Widget,
|
|
// 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/layout/browser_view_layout.cc chrome/browser/ui/views/frame/layout/browser_view_layout.cc
|
|
index 778997a0f1aec1982a2421bb18faf5918347af51..9f7f99605e186c11220b9f6d6787e1818b173379 100644
|
|
--- chrome/browser/ui/views/frame/layout/browser_view_layout.cc
|
|
+++ chrome/browser/ui/views/frame/layout/browser_view_layout.cc
|
|
@@ -24,6 +24,10 @@
|
|
#include "ui/views/widget/widget.h"
|
|
#include "ui/views/widget/widget_observer.h"
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/views/chrome_views_util.h"
|
|
+#endif
|
|
+
|
|
using web_modal::ModalDialogHostObserver;
|
|
using web_modal::WebContentsModalDialogHost;
|
|
|
|
@@ -66,6 +70,8 @@ class BrowserViewLayout::BrowserModalDialogHostViews
|
|
observer_list_.Notify(&ModalDialogHostObserver::OnHostDestroying);
|
|
}
|
|
|
|
+ bool HasObservers() const { return !observer_list_.empty(); }
|
|
+
|
|
void NotifyPositionRequiresUpdate() override {
|
|
observer_list_.Notify(&ModalDialogHostObserver::OnPositionRequiresUpdate);
|
|
}
|
|
@@ -221,18 +227,21 @@ void BrowserViewLayout::UpdateBubbles() {
|
|
exclusive_access_bubble->RepositionIfVisible();
|
|
}
|
|
|
|
- // 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());
|
|
- const gfx::Rect host_widget_bounds =
|
|
- dialog_host_->GetHostWidget()
|
|
- ? dialog_host_->GetHostWidget()->GetClientAreaBoundsInScreen()
|
|
- : gfx::Rect();
|
|
- const gfx::Rect dialog_bounds_in_screen =
|
|
- dialog_bounds + host_widget_bounds.OffsetFromOrigin();
|
|
- if (latest_dialog_bounds_in_screen_ != dialog_bounds_in_screen) {
|
|
- latest_dialog_bounds_in_screen_ = dialog_bounds_in_screen;
|
|
- dialog_host_->NotifyPositionRequiresUpdate();
|
|
+ // 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());
|
|
+ const gfx::Rect host_widget_bounds =
|
|
+ dialog_host_->GetHostWidget()
|
|
+ ? dialog_host_->GetHostWidget()->GetClientAreaBoundsInScreen()
|
|
+ : gfx::Rect();
|
|
+ const gfx::Rect dialog_bounds_in_screen =
|
|
+ dialog_bounds + host_widget_bounds.OffsetFromOrigin();
|
|
+ if (latest_dialog_bounds_in_screen_ != dialog_bounds_in_screen) {
|
|
+ latest_dialog_bounds_in_screen_ = dialog_bounds_in_screen;
|
|
+ dialog_host_->NotifyPositionRequiresUpdate();
|
|
+ }
|
|
}
|
|
}
|
|
|
|
diff --git chrome/browser/ui/views/frame/layout/browser_view_layout.h chrome/browser/ui/views/frame/layout/browser_view_layout.h
|
|
index c84c47a1190f9acd9602e6cc06badcbf81cf00a2..a2bb1d25ea23b8eb2b3c6763739d0f65a9f4d130 100644
|
|
--- chrome/browser/ui/views/frame/layout/browser_view_layout.h
|
|
+++ chrome/browser/ui/views/frame/layout/browser_view_layout.h
|
|
@@ -136,6 +136,8 @@ class BrowserViewLayout : public views::LayoutManager {
|
|
return views_.side_panel_animation_content;
|
|
}
|
|
|
|
+ void reset_toolbar() { views_.toolbar = nullptr; }
|
|
+
|
|
// views::LayoutManager overrides:
|
|
gfx::Size GetPreferredSize(
|
|
const views::View* host,
|
|
diff --git chrome/browser/ui/views/frame/layout/browser_view_layout_delegate.h chrome/browser/ui/views/frame/layout/browser_view_layout_delegate.h
|
|
index ac03bc00a00a9e127479f9da46b8bfb68da5fe98..b695949269ea20fee3c421ab72e0ca0d81f33831 100644
|
|
--- chrome/browser/ui/views/frame/layout/browser_view_layout_delegate.h
|
|
+++ chrome/browser/ui/views/frame/layout/browser_view_layout_delegate.h
|
|
@@ -46,6 +46,7 @@ class BrowserViewLayoutDelegate {
|
|
bool use_browser_bounds) const = 0;
|
|
virtual WindowState GetBrowserWindowState() const = 0;
|
|
virtual views::LayoutAlignment GetWindowTitleAlignment() const = 0;
|
|
+ virtual void UpdateDialogTopInsetInBrowserView(int* dialog_top_y) const = 0;
|
|
virtual bool IsToolbarVisible() const = 0;
|
|
virtual bool IsBookmarkBarVisible() const = 0;
|
|
virtual bool IsInfobarVisible() const = 0;
|
|
diff --git chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.cc chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.cc
|
|
index 162cb0487882a40ed6324115d5e58eb3cca97186..fdf3895be6aa8d4444849c45e1266eed1cf36cfb 100644
|
|
--- chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.cc
|
|
+++ chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.cc
|
|
@@ -35,19 +35,23 @@
|
|
#include "chrome/browser/ui/window_feature_controller/window_feature_controller.h"
|
|
#endif
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/browser_delegate.h"
|
|
+#endif
|
|
+
|
|
BrowserViewLayoutDelegateImpl::BrowserViewLayoutDelegateImpl(
|
|
BrowserView& browser_view)
|
|
: browser_view_(browser_view) {
|
|
- PrefService* prefs = browser_view_->GetProfile()->GetPrefs();
|
|
- tab_search_pinned_to_tab_strip_ =
|
|
- prefs->GetBoolean(prefs::kTabSearchPinnedToTabstrip);
|
|
-
|
|
- pref_registrar_.Init(prefs);
|
|
- pref_registrar_.Add(
|
|
- prefs::kTabSearchPinnedToTabstrip,
|
|
- base::BindRepeating(
|
|
- &BrowserViewLayoutDelegateImpl::OnTabSearchPinnedStateChanged,
|
|
- base::Unretained(this)));
|
|
+ PrefService* prefs = browser_view_->GetProfile()->GetPrefs();
|
|
+ tab_search_pinned_to_tab_strip_ =
|
|
+ prefs->GetBoolean(prefs::kTabSearchPinnedToTabstrip);
|
|
+
|
|
+ pref_registrar_.Init(prefs);
|
|
+ pref_registrar_.Add(
|
|
+ prefs::kTabSearchPinnedToTabstrip,
|
|
+ base::BindRepeating(
|
|
+ &BrowserViewLayoutDelegateImpl::OnTabSearchPinnedStateChanged,
|
|
+ base::Unretained(this)));
|
|
}
|
|
BrowserViewLayoutDelegateImpl::~BrowserViewLayoutDelegateImpl() = default;
|
|
|
|
@@ -144,6 +148,15 @@ views::LayoutAlignment BrowserViewLayoutDelegateImpl::GetWindowTitleAlignment()
|
|
return GetFrameView()->GetWindowTitleAlignment();
|
|
}
|
|
|
|
+void BrowserViewLayoutDelegateImpl::UpdateDialogTopInsetInBrowserView(
|
|
+ int* dialog_top_y) const {
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (auto cef_delegate = browser_view_->browser()->cef_delegate()) {
|
|
+ cef_delegate->UpdateDialogTopInset(dialog_top_y);
|
|
+ }
|
|
+#endif
|
|
+}
|
|
+
|
|
bool BrowserViewLayoutDelegateImpl::IsToolbarVisible() const {
|
|
return browser_view_->IsToolbarVisible();
|
|
}
|
|
diff --git chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.h chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.h
|
|
index df5a04fcd0006b93ce966079c65eff6fe5684d65..b726f843b05aff31ad75e3f085ea2853febd38ec 100644
|
|
--- chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.h
|
|
+++ chrome/browser/ui/views/frame/layout/browser_view_layout_delegate_impl.h
|
|
@@ -30,6 +30,7 @@ class BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate {
|
|
bool use_browser_bounds) const override;
|
|
WindowState GetBrowserWindowState() const override;
|
|
views::LayoutAlignment GetWindowTitleAlignment() const override;
|
|
+ void UpdateDialogTopInsetInBrowserView(int* dialog_top_y) const override;
|
|
bool IsToolbarVisible() const override;
|
|
bool IsBookmarkBarVisible() const override;
|
|
bool IsInfobarVisible() const override;
|
|
diff --git chrome/browser/ui/views/frame/layout/browser_view_layout_impl.cc chrome/browser/ui/views/frame/layout/browser_view_layout_impl.cc
|
|
index 32dc2739b9e326625d5dbcb7d18623c147e8209e..b0a5644023cf8d2cf2d9ccba1130417ea49d2d29 100644
|
|
--- chrome/browser/ui/views/frame/layout/browser_view_layout_impl.cc
|
|
+++ chrome/browser/ui/views/frame/layout/browser_view_layout_impl.cc
|
|
@@ -221,7 +221,16 @@ void BrowserViewLayoutImpl::Layout(views::View* host) {
|
|
|
|
auto params = delegate().GetBrowserLayoutParams(/*use_browser_bounds=*/true);
|
|
if (params.IsEmpty()) {
|
|
- return;
|
|
+ // Layout params are empty during early initialization (before the frame
|
|
+ // view has been laid out). Fall back to using the host's local bounds
|
|
+ // as the visual client area to allow layout to proceed with valid bounds.
|
|
+ // This prevents View::Layout's for-loop from triggering child layouts
|
|
+ // with 0x0 bounds.
|
|
+ params.visual_client_area = host->GetLocalBounds();
|
|
+ if (params.IsEmpty()) {
|
|
+ // Host also has no bounds yet, can't perform layout.
|
|
+ return;
|
|
+ }
|
|
}
|
|
|
|
DoPreLayoutComputations(params);
|
|
@@ -353,11 +362,13 @@ void BrowserViewLayoutImpl::OnGlassModeChanged() {}
|
|
int BrowserViewLayoutImpl::GetDialogTop(const ProposedLayout& layout) const {
|
|
const int kConstrainedWindowOverlap = 3;
|
|
const auto* const browser_view = views().browser_view.get();
|
|
+ int dialog_top_y = kConstrainedWindowOverlap;
|
|
if (const auto toolbar_rect =
|
|
layout.GetBoundsFor(views().toolbar, browser_view)) {
|
|
- return toolbar_rect->bottom() - kConstrainedWindowOverlap;
|
|
+ dialog_top_y = toolbar_rect->bottom() - kConstrainedWindowOverlap;
|
|
}
|
|
- return kConstrainedWindowOverlap;
|
|
+ delegate().UpdateDialogTopInsetInBrowserView(&dialog_top_y);
|
|
+ return dialog_top_y;
|
|
}
|
|
|
|
int BrowserViewLayoutImpl::GetDialogBottom(const ProposedLayout& layout) const {
|
|
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 59bdfa1e118091ea37ba235fb47b05797fdb16ed..69a4e327752488204cf046ac62b25b84be782ccb 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
|
|
@@ -29,6 +29,7 @@
|
|
#include "chrome/browser/ui/views/picture_in_picture/picture_in_picture_bounds_change_animation.h"
|
|
#include "chrome/browser/ui/views/picture_in_picture/picture_in_picture_tucker.h"
|
|
#include "chrome/browser/ui/views/picture_in_picture/pip_top_bar_animation_controller.h"
|
|
+#include "chrome/browser/ui/window_feature_controller/window_feature_controller.h"
|
|
#include "chrome/grit/generated_resources.h"
|
|
#include "components/omnibox/browser/location_bar_model_impl.h"
|
|
#include "components/vector_icons/vector_icons.h"
|
|
@@ -75,6 +76,11 @@
|
|
#if BUILDFLAG(ENABLE_EXTENSIONS_CORE)
|
|
#include "extensions/common/constants.h"
|
|
#endif // BUILDFLAG(ENABLE_EXTENSIONS_CORE)
|
|
+
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "ui/views/controls/webview/webview.h"
|
|
+#endif
|
|
+
|
|
namespace {
|
|
|
|
constexpr int kWindowIconImageSize = 16;
|
|
@@ -346,6 +352,12 @@ PictureInPictureBrowserFrameView::PictureInPictureBrowserFrameView(
|
|
IsOverlayViewVisible()) {
|
|
PictureInPictureWindowManager::GetInstance()->ClearCachedBounds();
|
|
}
|
|
+
|
|
+ if (!WindowFeatureController::From(browser_view->browser())
|
|
+ ->SupportsWindowFeature(
|
|
+ WindowFeatureController::WindowFeature::kFeatureTitleBar)) {
|
|
+ top_bar_container_view_->SetVisible(false);
|
|
+ }
|
|
}
|
|
|
|
PictureInPictureBrowserFrameView::~PictureInPictureBrowserFrameView() {
|
|
@@ -452,18 +464,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 =
|
|
+ GetBrowserView()->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(),
|
|
+ GetBrowserView()->GetActiveContentsWebView(),
|
|
+ &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(
|
|
@@ -528,7 +564,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_) {
|
|
@@ -1004,7 +1041,8 @@ gfx::Insets PictureInPictureBrowserFrameView::FrameBorderInsets() 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/location_bar/location_bar_view.cc chrome/browser/ui/views/location_bar/location_bar_view.cc
|
|
index bac174d0b227aa593d369b6e2e7f7b58179f2c16..cbc4b2936dddd2745b236f44a86c84b23f09ae44 100644
|
|
--- chrome/browser/ui/views/location_bar/location_bar_view.cc
|
|
+++ chrome/browser/ui/views/location_bar/location_bar_view.cc
|
|
@@ -171,6 +171,10 @@
|
|
#include "chrome/browser/web_applications/web_app_tab_helper.h"
|
|
#endif
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/browser_util.h"
|
|
+#endif
|
|
+
|
|
namespace {
|
|
|
|
int IncrementalMinimumWidth(const views::View* view) {
|
|
@@ -197,6 +201,14 @@ bool CanHostWebUIOmnibox(BrowserWindowInterface* browser, bool is_popup_mode) {
|
|
if (!browser) {
|
|
return true;
|
|
}
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser->cef_delegate() && browser->cef_delegate()->IsViewsHosted() &&
|
|
+ !cef::BrowserForBWI(browser)->toolbar_overridden()) {
|
|
+ // CEF initializes a fallback toolbar even when none is configured.
|
|
+ // Only create WebUI popups for a configured Chrome toolbar.
|
|
+ return false;
|
|
+ }
|
|
+#endif
|
|
return !web_app::AppBrowserController::IsWebApp(browser) &&
|
|
browser->GetType() != BrowserWindowInterface::Type::TYPE_DEVTOOLS;
|
|
}
|
|
@@ -396,7 +408,7 @@ void LocationBarView::Init() {
|
|
}
|
|
}
|
|
|
|
- // Default to the legacy popup view for web apps, devtools, and popup windows.
|
|
+ // Default to the legacy popup view when WebUI popups are not supported.
|
|
// When the legacy `OmniboxPopupViewViews` is deprecated we will need to
|
|
// ensure that a null `omnibox_popup_view_` doesn't cause any issues (or aim
|
|
// for a cleaner solution).
|
|
@@ -479,6 +491,18 @@ void LocationBarView::Init() {
|
|
page_action_items = page_actions::GetActivePageActionItems(*browser_);
|
|
}
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+ if (browser_ && browser_->cef_delegate()) {
|
|
+ const auto& properties_provider =
|
|
+ page_actions::PageActionPropertiesProvider();
|
|
+ std::erase_if(page_action_items, [&](actions::ActionItem* item) {
|
|
+ const auto& props =
|
|
+ properties_provider.GetProperties(item->GetActionId().value());
|
|
+ return !browser_->cef_delegate()->IsPageActionIconVisible(props.type);
|
|
+ });
|
|
+ }
|
|
+#endif
|
|
+
|
|
static constexpr int kBetweenIconSpacing = 8;
|
|
const page_actions::PageActionViewParams page_action_params{
|
|
.icon_size =
|
|
diff --git chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc
|
|
index f3468b8df860303d49052587004ca1e0f501d4fd..44c59704cad310c5f577470eb3b0e2c431cb9a6c 100644
|
|
--- chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc
|
|
+++ chrome/browser/ui/views/omnibox/omnibox_popup_closer.cc
|
|
@@ -59,7 +59,8 @@ OmniboxPopupCloser::~OmniboxPopupCloser() = default;
|
|
|
|
void OmniboxPopupCloser::OnMouseEvent(ui::MouseEvent* event) {
|
|
// Close the omnibox popup if the click is outside the omnibox view.
|
|
- if (!browser_view_->browser()->IsDeleteScheduled()) {
|
|
+ if (browser_view_->browser() &&
|
|
+ !browser_view_->browser()->IsDeleteScheduled()) {
|
|
LocationBar* location_bar = browser_view_->GetLocationBar();
|
|
CHECK(location_bar);
|
|
if (location_bar->ShouldCloseOmniboxPopup(event)) {
|
|
diff --git chrome/browser/ui/views/toolbar/toolbar_view.cc chrome/browser/ui/views/toolbar/toolbar_view.cc
|
|
index 136f1c7c87a446ff5192a58f87f874800f09375d..3177568b2663a824f308a94d6874585fec0ecc26 100644
|
|
--- chrome/browser/ui/views/toolbar/toolbar_view.cc
|
|
+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
|
|
@@ -43,6 +43,7 @@
|
|
#include "chrome/browser/themes/theme_properties.h"
|
|
#include "chrome/browser/ui/actions/chrome_action_id.h"
|
|
#include "chrome/browser/ui/ai_overlay_dialog/ai_overlay_dialog_controller.h"
|
|
+#include "chrome/browser/ui/browser.h"
|
|
#include "chrome/browser/ui/browser_actions.h"
|
|
#include "chrome/browser/ui/browser_command_controller.h"
|
|
#include "chrome/browser/ui/browser_commands.h"
|
|
@@ -182,6 +183,10 @@
|
|
#include "ui/aura/window_occlusion_tracker.h"
|
|
#endif
|
|
|
|
+#if BUILDFLAG(ENABLE_CEF)
|
|
+#include "cef/libcef/browser/chrome/browser_util.h"
|
|
+#endif
|
|
+
|
|
using base::UserMetricsAction;
|
|
using content::WebContents;
|
|
|
|
@@ -269,12 +274,13 @@ void SetRefreshMargins(views::View* button, bool expanded) {
|
|
DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(ToolbarView, kToolbarElementId);
|
|
|
|
ToolbarView::ToolbarView(BrowserWindowInterface* browser,
|
|
- BrowserView* browser_view)
|
|
+ BrowserView* browser_view,
|
|
+ std::optional<DisplayMode> display_mode)
|
|
: AnimationDelegateViews(this),
|
|
browser_(browser),
|
|
browser_view_(browser_view),
|
|
app_menu_icon_controller_(browser->GetProfile(), this),
|
|
- display_mode_(GetDisplayMode(browser)) {
|
|
+ display_mode_(display_mode ? *display_mode : GetDisplayMode(browser)) {
|
|
// WebApp type-browsers set their own ToolbarButtonProvider.
|
|
if (!web_app::AppBrowserController::IsWebApp(browser)) {
|
|
scoped_unowned_user_data_.emplace(browser_->GetUnownedUserDataHost(),
|
|
@@ -314,6 +320,8 @@ ToolbarView::~ToolbarView() {
|
|
for (const auto& view_and_command : GetViewCommandMap()) {
|
|
chrome::RemoveCommandObserver(browser_, view_and_command.second, this);
|
|
}
|
|
+
|
|
+ browser_view_->WillDestroyToolbar();
|
|
}
|
|
|
|
// Forwards the early teardown request to both the embedded and detached WebUI
|
|
@@ -328,6 +336,19 @@ void ToolbarView::DestroyWebUIToolbarWebContents() {
|
|
}
|
|
|
|
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
|
|
@@ -348,7 +369,8 @@ void ToolbarView::Init() {
|
|
location_bar_view = std::make_unique<LocationBarView>(
|
|
browser_, browser_->GetProfile(),
|
|
chrome::BrowserCommandController::From(browser_), this,
|
|
- display_mode_ != DisplayMode::kNormal);
|
|
+ display_mode_ != DisplayMode::kNormal &&
|
|
+ !cef::BrowserForBWI(browser_)->toolbar_overridden());
|
|
}
|
|
|
|
// Make sure the toolbar shows by default.
|
|
@@ -421,7 +443,7 @@ void ToolbarView::Init() {
|
|
|
|
std::unique_ptr<MediaToolbarButtonView> media_button;
|
|
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX)
|
|
- if (!features::IsWebUIMediaButtonEnabled()) {
|
|
+ if (!features::IsWebUIMediaButtonEnabled() && BUTTON_VISIBLE(kMedia)) {
|
|
media_button = std::make_unique<MediaToolbarButtonView>(
|
|
browser_view_, std::make_unique<MediaToolbarButtonContextualMenu>(
|
|
browser_->GetProfile()));
|
|
@@ -556,7 +578,8 @@ void ToolbarView::Init() {
|
|
// Only show the Battery Saver button when it is not controlled by the OS. On
|
|
// ChromeOS the battery icon in the shelf shows the same information.
|
|
if (!performance_manager::user_tuning::IsBatterySaverModeManagedByOS() &&
|
|
- !features::IsWebUIBatterySaverButtonEnabled()) {
|
|
+ !features::IsWebUIBatterySaverButtonEnabled() &&
|
|
+ BUTTON_VISIBLE(kBatterySaver)) {
|
|
battery_saver_button_ =
|
|
AddChildView(std::make_unique<BatterySaverButton>(browser_));
|
|
}
|
|
@@ -613,7 +636,7 @@ void ToolbarView::Init() {
|
|
avatar_ = AddChildView(std::make_unique<AvatarToolbarButton>(browser_));
|
|
bool show_avatar_toolbar_button =
|
|
AvatarToolbarButtonInterface::CanShowForProfile(browser_->GetProfile());
|
|
- avatar_->SetVisible(show_avatar_toolbar_button);
|
|
+ avatar_->SetVisible(show_avatar_toolbar_button && BUTTON_VISIBLE(kAvatar));
|
|
}
|
|
|
|
// Only manage the overflow button when there are at least some views
|
|
diff --git chrome/browser/ui/views/toolbar/toolbar_view.h chrome/browser/ui/views/toolbar/toolbar_view.h
|
|
index 50e546251e9f8021683a6929593205daefbb0596..57c9e8d4659ddab00fc3cd30be8af5f3bbfbb8b1 100644
|
|
--- chrome/browser/ui/views/toolbar/toolbar_view.h
|
|
+++ chrome/browser/ui/views/toolbar/toolbar_view.h
|
|
@@ -113,7 +113,9 @@ class ToolbarView : public views::AccessiblePaneView,
|
|
|
|
DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kToolbarElementId);
|
|
|
|
- ToolbarView(BrowserWindowInterface* browser, BrowserView* browser_view);
|
|
+ ToolbarView(BrowserWindowInterface* browser,
|
|
+ BrowserView* browser_view,
|
|
+ std::optional<DisplayMode> display_mode);
|
|
ToolbarView(const ToolbarView&) = delete;
|
|
ToolbarView& operator=(const ToolbarView&) = delete;
|
|
~ToolbarView() override;
|