• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git chrome/browser/ui/browser_command_controller.cc chrome/browser/ui/browser_command_controller.cc
2index 92f10fac6b017..cc53da3a0b32e 100644
3--- chrome/browser/ui/browser_command_controller.cc
4+++ chrome/browser/ui/browser_command_controller.cc
5@@ -368,8 +368,10 @@ bool BrowserCommandController::ExecuteCommandWithDisposition(
6   // CommandUpdaterDelegate and CommandUpdater declare this function so we
7   // choose to not implement CommandUpdaterDelegate inside this class and
8   // therefore command_updater_ doesn't have the delegate set).
9-  if (!SupportsCommand(id) || !IsCommandEnabled(id))
10+  if (!SupportsCommand(id) || !IsCommandEnabled(id)) {
11+    LOG(WARNING) << "Invalid/disabled command " << id;
12     return false;
13+  }
14
15   // No commands are enabled if there is not yet any selected tab.
16   // TODO(pkasting): It seems like we should not need this, because either
17@@ -979,11 +981,13 @@ void BrowserCommandController::TabRestoreServiceLoaded(
18 // BrowserCommandController, private:
19
20 bool BrowserCommandController::IsShowingMainUI() {
21-  return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP);
22+  return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP) ||
23+         browser_->toolbar_overridden();
24 }
25
26 bool BrowserCommandController::IsShowingLocationBar() {
27-  return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR);
28+  return browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR) ||
29+         browser_->toolbar_overridden();
30 }
31
32 void BrowserCommandController::InitCommandState() {
33diff --git chrome/browser/ui/views/frame/browser_frame.cc chrome/browser/ui/views/frame/browser_frame.cc
34index 6264562165ced..d20f970ba1254 100644
35--- chrome/browser/ui/views/frame/browser_frame.cc
36+++ chrome/browser/ui/views/frame/browser_frame.cc
37@@ -73,15 +73,23 @@ bool IsUsingGtkTheme(Profile* profile) {
38 ////////////////////////////////////////////////////////////////////////////////
39 // BrowserFrame, public:
40
41+BrowserFrame::BrowserFrame() : BrowserFrame(nullptr) {}
42+
43 BrowserFrame::BrowserFrame(BrowserView* browser_view)
44     : native_browser_frame_(nullptr),
45       root_view_(nullptr),
46       browser_frame_view_(nullptr),
47-      browser_view_(browser_view) {
48-  browser_view_->set_frame(this);
49+      browser_view_(nullptr) {
50   set_is_secondary_widget(false);
51   // Don't focus anything on creation, selecting a tab will set the focus.
52   set_focus_on_creation(false);
53+  if (browser_view)
54+    InitBrowserView(browser_view);
55+}
56+
57+void BrowserFrame::InitBrowserView(BrowserView* browser_view) {
58+  browser_view_ = browser_view;
59+  browser_view_->set_frame(this);
60 }
61
62 BrowserFrame::~BrowserFrame() {}
63@@ -141,6 +149,12 @@ gfx::Rect BrowserFrame::GetBoundsForTabStripRegion(
64 }
65
66 int BrowserFrame::GetTopInset() const {
67+  if (!browser_frame_view_) {
68+    // With CEF the browser may already be part of a larger Views layout. Zero
69+    // out the adjustment in BrowserView::GetTopInsetInBrowserView() so that
70+    // the browser isn't shifted to the top of the window.
71+    return browser_view_->y();
72+  }
73   return browser_frame_view_->GetTopInset(false);
74 }
75
76@@ -175,15 +189,21 @@ void BrowserFrame::GetWindowPlacement(gfx::Rect* bounds,
77
78 content::KeyboardEventProcessingResult BrowserFrame::PreHandleKeyboardEvent(
79     const content::NativeWebKeyboardEvent& event) {
80+  if (!native_browser_frame_)
81+    return content::KeyboardEventProcessingResult::NOT_HANDLED;
82   return native_browser_frame_->PreHandleKeyboardEvent(event);
83 }
84
85 bool BrowserFrame::HandleKeyboardEvent(
86     const content::NativeWebKeyboardEvent& event) {
87+  if (!native_browser_frame_)
88+    return false;
89   return native_browser_frame_->HandleKeyboardEvent(event);
90 }
91
92 void BrowserFrame::OnBrowserViewInitViewsComplete() {
93+  if (!browser_frame_view_)
94+    return;
95   browser_frame_view_->OnBrowserViewInitViewsComplete();
96 }
97
98@@ -244,6 +264,8 @@ const ui::ThemeProvider* BrowserFrame::GetThemeProvider() const {
99
100 ui::ColorProviderManager::InitializerSupplier* BrowserFrame::GetCustomTheme()
101     const {
102+  if (!browser_view_)
103+    return nullptr;
104   Browser* browser = browser_view_->browser();
105   auto* app_controller = browser->app_controller();
106   // Ignore GTK+ for web apps with window-controls-overlay as the
107@@ -369,7 +391,8 @@ void BrowserFrame::SelectNativeTheme() {
108   // Select between regular, dark and GTK theme.
109   ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
110
111-  if (browser_view_->browser()->profile()->IsIncognitoProfile()) {
112+  if (browser_view_ &&
113+      browser_view_->browser()->profile()->IsIncognitoProfile()) {
114     // If the flag is enabled, then no matter if we are using the default theme
115     // or not we always use the dark ui instance.
116     if (base::FeatureList::IsEnabled(
117diff --git chrome/browser/ui/views/frame/browser_frame.h chrome/browser/ui/views/frame/browser_frame.h
118index 6a1e9abbc66aa..aa9e3ebe2599c 100644
119--- chrome/browser/ui/views/frame/browser_frame.h
120+++ chrome/browser/ui/views/frame/browser_frame.h
121@@ -53,7 +53,9 @@ enum class TabDragKind {
122 // This is a virtual interface that allows system specific browser frames.
123 class BrowserFrame : public views::Widget, public views::ContextMenuController {
124  public:
125+  BrowserFrame();
126   explicit BrowserFrame(BrowserView* browser_view);
127+  void InitBrowserView(BrowserView* browser_view);
128
129   BrowserFrame(const BrowserFrame&) = delete;
130   BrowserFrame& operator=(const BrowserFrame&) = delete;
131diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
132index 8138e50a55072..e01b2274119b8 100644
133--- chrome/browser/ui/views/frame/browser_view.cc
134+++ chrome/browser/ui/views/frame/browser_view.cc
135@@ -291,11 +291,10 @@ using content::WebContents;
136 using views::ColumnSet;
137 using web_modal::WebContentsModalDialogHost;
138
139-namespace {
140+// static
141+const char BrowserView::kBrowserViewKey[] = "__BROWSER_VIEW__";
142
143-// The name of a key to store on the window handle so that other code can
144-// locate this object using just the handle.
145-const char* const kBrowserViewKey = "__BROWSER_VIEW__";
146+namespace {
147
148 #if BUILDFLAG(IS_CHROMEOS_ASH)
149 // UMA histograms that record animation smoothness for tab loading animation.
150@@ -683,11 +682,22 @@ class BrowserView::SidePanelButtonHighlighter : public views::ViewObserver {
151 ///////////////////////////////////////////////////////////////////////////////
152 // BrowserView, public:
153
154+BrowserView::BrowserView() : BrowserView(nullptr) {}
155+
156 BrowserView::BrowserView(std::unique_ptr<Browser> browser)
157     : views::ClientView(nullptr, nullptr),
158-      browser_(std::move(browser)),
159       accessibility_mode_observer_(
160           std::make_unique<AccessibilityModeObserver>(this)) {
161+  if (browser)
162+    InitBrowser(std::move(browser));
163+}
164+
165+void BrowserView::InitBrowser(std::unique_ptr<Browser> browser) {
166+  DCHECK(!browser_);
167+  browser_ = std::move(browser);
168+
169+  immersive_mode_controller_ = chrome::CreateImmersiveModeController();
170+
171   SetShowIcon(::ShouldShowWindowIcon(browser_.get()));
172
173   // In forced app mode, all size controls are always disabled. Otherwise, use
174@@ -701,7 +711,6 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
175   }
176
177   browser_->tab_strip_model()->AddObserver(this);
178-  immersive_mode_controller_ = chrome::CreateImmersiveModeController();
179
180   // Top container holds tab strip region and toolbar and lives at the front of
181   // the view hierarchy.
182@@ -749,8 +758,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
183   contents_container->SetLayoutManager(std::make_unique<ContentsLayoutManager>(
184       devtools_web_view_, contents_web_view_));
185
186-  toolbar_ = top_container_->AddChildView(
187-      std::make_unique<ToolbarView>(browser_.get(), this));
188+  toolbar_ = OverrideCreateToolbar(browser_.get(), this);
189+  if (!toolbar_) {
190+    toolbar_ = new ToolbarView(browser_.get(), this, absl::nullopt);
191+  } else {
192+    browser_->set_toolbar_overridden(true);
193+    // Update state that depends on the above flag.
194+    browser_->command_controller()->FullscreenStateChanged();
195+  }
196+  top_container_->AddChildView(base::WrapUnique(toolbar_.get()));
197
198   contents_separator_ =
199       top_container_->AddChildView(std::make_unique<ContentsSeparator>());
200@@ -1587,6 +1603,8 @@ bool BrowserView::ShouldHideUIForFullscreen() const {
201   if (immersive_mode_controller_->IsEnabled())
202     return false;
203
204+  if (!frame_->GetFrameView())
205+    return false;
206   return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
207 }
208
209@@ -2731,7 +2749,8 @@ BrowserView::GetNativeViewHostsForTopControlsSlide() const {
210 }
211
212 void BrowserView::ReparentTopContainerForEndOfImmersive() {
213-  overlay_view_->SetVisible(false);
214+  if (overlay_view_)
215+    overlay_view_->SetVisible(false);
216   top_container()->DestroyLayer();
217   AddChildViewAt(top_container(), 0);
218   EnsureFocusOrder();
219@@ -3220,8 +3239,10 @@ void BrowserView::Layout() {
220
221   // TODO(jamescook): Why was this in the middle of layout code?
222   toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
223-      IsToolbarVisible() ? FocusBehavior::ALWAYS : FocusBehavior::NEVER);
224-  frame()->GetFrameView()->UpdateMinimumSize();
225+      (IsToolbarVisible() || browser_->toolbar_overridden()) ?
226+          FocusBehavior::ALWAYS : FocusBehavior::NEVER);
227+  if (frame()->GetFrameView())
228+    frame()->GetFrameView()->UpdateMinimumSize();
229
230   // Some of the situations when the BrowserView is laid out are:
231   // - Enter/exit immersive fullscreen mode.
232@@ -3284,6 +3305,11 @@ void BrowserView::AddedToWidget() {
233   SetThemeProfileForWindow(GetNativeWindow(), browser_->profile());
234 #endif
235
236+  // This browser view may already have a custom button provider set (e.g the
237+  // hosted app frame).
238+  if (!toolbar_button_provider_)
239+    SetToolbarButtonProvider(toolbar_);
240+
241   toolbar_->Init();
242
243   // TODO(pbos): Manage this either inside SidePanel or the corresponding button
244@@ -3336,13 +3362,9 @@ void BrowserView::AddedToWidget() {
245
246   EnsureFocusOrder();
247
248-  // This browser view may already have a custom button provider set (e.g the
249-  // hosted app frame).
250-  if (!toolbar_button_provider_)
251-    SetToolbarButtonProvider(toolbar_);
252-
253   frame_->OnBrowserViewInitViewsComplete();
254-  frame_->GetFrameView()->UpdateMinimumSize();
255+  if (frame_->GetFrameView())
256+    frame_->GetFrameView()->UpdateMinimumSize();
257   using_native_frame_ = frame_->ShouldUseNativeFrame();
258
259   MaybeInitializeWebUITabStrip();
260@@ -3761,7 +3783,8 @@ void BrowserView::ProcessFullscreen(bool fullscreen,
261   // Undo our anti-jankiness hacks and force a re-layout.
262   in_process_fullscreen_ = false;
263   ToolbarSizeChanged(false);
264-  frame_->GetFrameView()->OnFullscreenStateChanged();
265+  if (frame_->GetFrameView())
266+    frame_->GetFrameView()->OnFullscreenStateChanged();
267 }
268
269 bool BrowserView::ShouldUseImmersiveFullscreenForUrl(const GURL& url) const {
270@@ -4052,6 +4075,8 @@ Profile* BrowserView::GetProfile() {
271 }
272
273 void BrowserView::UpdateUIForTabFullscreen() {
274+  if (!frame_->GetFrameView())
275+    return;
276   frame()->GetFrameView()->UpdateFullscreenTopUI();
277 }
278
279@@ -4074,6 +4099,8 @@ void BrowserView::HideDownloadShelf() {
280 }
281
282 bool BrowserView::CanUserExitFullscreen() const {
283+  if (!frame_->GetFrameView())
284+    return true;
285   return frame_->GetFrameView()->CanUserExitFullscreen();
286 }
287
288diff --git chrome/browser/ui/views/frame/browser_view.h chrome/browser/ui/views/frame/browser_view.h
289index 02d9793dd5c8d..fe8b0cef88375 100644
290--- chrome/browser/ui/views/frame/browser_view.h
291+++ chrome/browser/ui/views/frame/browser_view.h
292@@ -125,11 +125,16 @@ class BrowserView : public BrowserWindow,
293                     public webapps::AppBannerManager::Observer {
294  public:
295   METADATA_HEADER(BrowserView);
296+  BrowserView();
297   explicit BrowserView(std::unique_ptr<Browser> browser);
298+  void InitBrowser(std::unique_ptr<Browser> browser);
299   BrowserView(const BrowserView&) = delete;
300   BrowserView& operator=(const BrowserView&) = delete;
301   ~BrowserView() override;
302
303+  // Key used to bind BrowserView to the Widget with which it is associated.
304+  static const char kBrowserViewKey[];
305+
306   void set_frame(BrowserFrame* frame) { frame_ = frame; }
307   BrowserFrame* frame() const { return frame_; }
308
309@@ -705,6 +710,12 @@ class BrowserView : public BrowserWindow,
310       const std::map<std::string, std::string>& extra_data) override;
311 #endif
312
313+ protected:
314+  virtual ToolbarView* OverrideCreateToolbar(Browser* browser,
315+                                             BrowserView* browser_view) {
316+    return nullptr;
317+  }
318+
319  private:
320   // Do not friend BrowserViewLayout. Use the BrowserViewLayoutDelegate
321   // interface to keep these two classes decoupled and testable.
322diff --git chrome/browser/ui/views/frame/browser_view_layout.cc chrome/browser/ui/views/frame/browser_view_layout.cc
323index 1d22e4b057c6c..d73b547f09e0b 100644
324--- chrome/browser/ui/views/frame/browser_view_layout.cc
325+++ chrome/browser/ui/views/frame/browser_view_layout.cc
326@@ -40,6 +40,10 @@
327 #include "ui/views/widget/widget.h"
328 #include "ui/views/window/client_view.h"
329
330+#if BUILDFLAG(ENABLE_CEF)
331+#include "cef/libcef/browser/chrome/views/chrome_views_util.h"
332+#endif
333+
334 using views::View;
335 using web_modal::WebContentsModalDialogHost;
336 using web_modal::ModalDialogHostObserver;
337@@ -458,6 +462,11 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
338
339 int BrowserViewLayout::LayoutToolbar(int top) {
340   TRACE_EVENT0("ui", "BrowserViewLayout::LayoutToolbar");
341+  if (cef::IsCefView(toolbar_)) {
342+    // CEF may take ownership of the toolbar. Early exit to avoid the DCHECK
343+    // in LayoutManager::SetViewVisibility().
344+    return top;
345+  }
346   int browser_view_width = vertical_layout_rect_.width();
347   bool toolbar_visible = delegate_->IsToolbarVisible();
348   int height = toolbar_visible ? toolbar_->GetPreferredSize().height() : 0;
349diff --git chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
350index b5706099ce923..07cebc2f8b65f 100644
351--- chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
352+++ chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
353@@ -559,37 +559,53 @@ gfx::Range BrowserTabStripController::ListTabsInGroup(
354 }
355
356 bool BrowserTabStripController::IsFrameCondensed() const {
357+  if (!GetFrameView())
358+    return false;
359   return GetFrameView()->IsFrameCondensed();
360 }
361
362 bool BrowserTabStripController::HasVisibleBackgroundTabShapes() const {
363+  if (!GetFrameView())
364+    return false;
365   return GetFrameView()->HasVisibleBackgroundTabShapes(
366       BrowserFrameActiveState::kUseCurrent);
367 }
368
369 bool BrowserTabStripController::EverHasVisibleBackgroundTabShapes() const {
370+  if (!GetFrameView())
371+    return false;
372   return GetFrameView()->EverHasVisibleBackgroundTabShapes();
373 }
374
375 bool BrowserTabStripController::ShouldPaintAsActiveFrame() const {
376+  if (!GetFrameView())
377+    return false;
378   return GetFrameView()->ShouldPaintAsActive();
379 }
380
381 bool BrowserTabStripController::CanDrawStrokes() const {
382+  if (!GetFrameView())
383+    return false;
384   return GetFrameView()->CanDrawStrokes();
385 }
386
387 SkColor BrowserTabStripController::GetFrameColor(
388     BrowserFrameActiveState active_state) const {
389+  if (!GetFrameView())
390+    return SK_ColorWHITE;
391   return GetFrameView()->GetFrameColor(active_state);
392 }
393
394 SkColor BrowserTabStripController::GetToolbarTopSeparatorColor() const {
395+  if (!GetFrameView())
396+    return SK_ColorWHITE;
397   return GetFrameView()->GetToolbarTopSeparatorColor();
398 }
399
400 absl::optional<int> BrowserTabStripController::GetCustomBackgroundId(
401     BrowserFrameActiveState active_state) const {
402+  if (!GetFrameView())
403+    return absl::nullopt;
404   return GetFrameView()->GetCustomBackgroundId(active_state);
405 }
406
407diff --git chrome/browser/ui/views/toolbar/toolbar_view.cc chrome/browser/ui/views/toolbar/toolbar_view.cc
408index b5098154b2f7e..4a3121cedf083 100644
409--- chrome/browser/ui/views/toolbar/toolbar_view.cc
410+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
411@@ -168,12 +168,13 @@ auto& GetViewCommandMap() {
412 ////////////////////////////////////////////////////////////////////////////////
413 // ToolbarView, public:
414
415-ToolbarView::ToolbarView(Browser* browser, BrowserView* browser_view)
416+ToolbarView::ToolbarView(Browser* browser, BrowserView* browser_view,
417+                         absl::optional<DisplayMode> display_mode)
418     : AnimationDelegateViews(this),
419       browser_(browser),
420       browser_view_(browser_view),
421       app_menu_icon_controller_(browser->profile(), this),
422-      display_mode_(GetDisplayMode(browser)) {
423+      display_mode_(display_mode ? *display_mode : GetDisplayMode(browser)) {
424   SetID(VIEW_ID_TOOLBAR);
425
426   UpgradeDetector::GetInstance()->AddObserver(this);
427@@ -208,7 +209,7 @@ void ToolbarView::Init() {
428 #endif
429   auto location_bar = std::make_unique<LocationBarView>(
430       browser_, browser_->profile(), browser_->command_controller(), this,
431-      display_mode_ != DisplayMode::NORMAL);
432+      display_mode_ != DisplayMode::NORMAL && !browser_->toolbar_overridden());
433   // Make sure the toolbar shows by default.
434   size_animation_.Reset(1);
435
436diff --git chrome/browser/ui/views/toolbar/toolbar_view.h chrome/browser/ui/views/toolbar/toolbar_view.h
437index 79efc97f711f1..6915479340275 100644
438--- chrome/browser/ui/views/toolbar/toolbar_view.h
439+++ chrome/browser/ui/views/toolbar/toolbar_view.h
440@@ -93,7 +93,8 @@ class ToolbarView : public views::AccessiblePaneView,
441                 // needs to be displayed.
442   };
443
444-  ToolbarView(Browser* browser, BrowserView* browser_view);
445+  ToolbarView(Browser* browser, BrowserView* browser_view,
446+              absl::optional<DisplayMode> display_mode);
447   ToolbarView(const ToolbarView&) = delete;
448   ToolbarView& operator=(const ToolbarView&) = delete;
449   ~ToolbarView() override;
450