• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git chrome/browser/ui/browser_command_controller.cc chrome/browser/ui/browser_command_controller.cc
2index b0bde494f7b6..19b11ac5766d 100644
3--- chrome/browser/ui/browser_command_controller.cc
4+++ chrome/browser/ui/browser_command_controller.cc
5@@ -354,8 +354,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@@ -952,11 +954,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 5aff6e51d218..55a95564fb82 100644
35--- chrome/browser/ui/views/frame/browser_frame.cc
36+++ chrome/browser/ui/views/frame/browser_frame.cc
37@@ -65,15 +65,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@@ -132,6 +140,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@@ -166,15 +180,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@@ -207,7 +227,8 @@ const ui::ThemeProvider* BrowserFrame::GetThemeProvider() const {
99 }
100
101 const ui::NativeTheme* BrowserFrame::GetNativeTheme() const {
102-  if (browser_view_->browser()->profile()->IsIncognitoProfile() &&
103+  if (browser_view_ &&
104+      browser_view_->browser()->profile()->IsIncognitoProfile() &&
105       ThemeServiceFactory::GetForProfile(browser_view_->browser()->profile())
106           ->UsingDefaultTheme()) {
107     return ui::NativeTheme::GetInstanceForDarkUI();
108diff --git chrome/browser/ui/views/frame/browser_frame.h chrome/browser/ui/views/frame/browser_frame.h
109index 050c0e05e4e3..0bbcf4af9a92 100644
110--- chrome/browser/ui/views/frame/browser_frame.h
111+++ chrome/browser/ui/views/frame/browser_frame.h
112@@ -53,7 +53,9 @@ enum class TabDragKind {
113 // This is a virtual interface that allows system specific browser frames.
114 class BrowserFrame : public views::Widget, public views::ContextMenuController {
115  public:
116+  BrowserFrame();
117   explicit BrowserFrame(BrowserView* browser_view);
118+  void InitBrowserView(BrowserView* browser_view);
119   ~BrowserFrame() override;
120
121   // Initialize the frame (creates the underlying native window).
122diff --git chrome/browser/ui/views/frame/browser_view.cc chrome/browser/ui/views/frame/browser_view.cc
123index c33c4327974e..fe470132a090 100644
124--- chrome/browser/ui/views/frame/browser_view.cc
125+++ chrome/browser/ui/views/frame/browser_view.cc
126@@ -576,11 +576,22 @@ class BrowserView::AccessibilityModeObserver : public ui::AXModeObserver {
127 ///////////////////////////////////////////////////////////////////////////////
128 // BrowserView, public:
129
130+BrowserView::BrowserView() : BrowserView(nullptr) {}
131+
132 BrowserView::BrowserView(std::unique_ptr<Browser> browser)
133     : views::ClientView(nullptr, nullptr),
134-      browser_(std::move(browser)),
135       accessibility_mode_observer_(
136           std::make_unique<AccessibilityModeObserver>(this)) {
137+  if (browser)
138+    InitBrowser(std::move(browser));
139+}
140+
141+void BrowserView::InitBrowser(std::unique_ptr<Browser> browser) {
142+  DCHECK(!browser_);
143+  browser_ = std::move(browser);
144+
145+  immersive_mode_controller_ = chrome::CreateImmersiveModeController();
146+
147   SetShowIcon(::ShouldShowWindowIcon(browser_.get()));
148
149   // In forced app mode, all size controls are always disabled. Otherwise, use
150@@ -594,7 +605,6 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
151   }
152
153   browser_->tab_strip_model()->AddObserver(this);
154-  immersive_mode_controller_ = chrome::CreateImmersiveModeController();
155
156   // Top container holds tab strip region and toolbar and lives at the front of
157   // the view hierarchy.
158@@ -638,8 +648,15 @@ BrowserView::BrowserView(std::unique_ptr<Browser> browser)
159   contents_container->SetLayoutManager(std::make_unique<ContentsLayoutManager>(
160       devtools_web_view_, contents_web_view_));
161
162-  toolbar_ = top_container_->AddChildView(
163-      std::make_unique<ToolbarView>(browser_.get(), this));
164+  toolbar_ = OverrideCreateToolbar(browser_.get(), this);
165+  if (!toolbar_) {
166+    toolbar_ = new ToolbarView(browser_.get(), this, base::nullopt);
167+  } else {
168+    browser_->set_toolbar_overridden(true);
169+    // Update state that depends on the above flag.
170+    browser_->command_controller()->FullscreenStateChanged();
171+  }
172+  top_container_->AddChildView(base::WrapUnique(toolbar_));
173
174   contents_separator_ =
175       top_container_->AddChildView(std::make_unique<ContentsSeparator>());
176@@ -1407,6 +1424,8 @@ bool BrowserView::ShouldHideUIForFullscreen() const {
177   if (immersive_mode_controller_->IsEnabled())
178     return false;
179
180+  if (!frame_->GetFrameView())
181+    return false;
182   return frame_->GetFrameView()->ShouldHideTopUIForFullscreen();
183 }
184
185@@ -2427,7 +2446,8 @@ BrowserView::GetNativeViewHostsForTopControlsSlide() const {
186 }
187
188 void BrowserView::ReparentTopContainerForEndOfImmersive() {
189-  overlay_view_->SetVisible(false);
190+  if (overlay_view_)
191+    overlay_view_->SetVisible(false);
192   top_container()->DestroyLayer();
193   AddChildViewAt(top_container(), 0);
194   EnsureFocusOrder();
195@@ -2889,8 +2909,10 @@ void BrowserView::Layout() {
196
197   // TODO(jamescook): Why was this in the middle of layout code?
198   toolbar_->location_bar()->omnibox_view()->SetFocusBehavior(
199-      IsToolbarVisible() ? FocusBehavior::ALWAYS : FocusBehavior::NEVER);
200-  frame()->GetFrameView()->UpdateMinimumSize();
201+      (IsToolbarVisible() || browser_->toolbar_overridden()) ?
202+          FocusBehavior::ALWAYS : FocusBehavior::NEVER);
203+  if (frame()->GetFrameView())
204+    frame()->GetFrameView()->UpdateMinimumSize();
205
206   // Some of the situations when the BrowserView is laid out are:
207   // - Enter/exit immersive fullscreen mode.
208@@ -2947,6 +2969,11 @@ void BrowserView::AddedToWidget() {
209   SetThemeProfileForWindow(GetNativeWindow(), browser_->profile());
210 #endif
211
212+  // This browser view may already have a custom button provider set (e.g the
213+  // hosted app frame).
214+  if (!toolbar_button_provider_)
215+    SetToolbarButtonProvider(toolbar_);
216+
217   toolbar_->Init();
218
219 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
220@@ -2987,13 +3014,9 @@ void BrowserView::AddedToWidget() {
221
222   EnsureFocusOrder();
223
224-  // This browser view may already have a custom button provider set (e.g the
225-  // hosted app frame).
226-  if (!toolbar_button_provider_)
227-    SetToolbarButtonProvider(toolbar_);
228-
229   frame_->OnBrowserViewInitViewsComplete();
230-  frame_->GetFrameView()->UpdateMinimumSize();
231+  if (frame_->GetFrameView())
232+    frame_->GetFrameView()->UpdateMinimumSize();
233   using_native_frame_ = frame_->ShouldUseNativeFrame();
234
235   MaybeInitializeWebUITabStrip();
236diff --git chrome/browser/ui/views/frame/browser_view.h chrome/browser/ui/views/frame/browser_view.h
237index 59ddc0ac10f9..d5f04bfd7ca5 100644
238--- chrome/browser/ui/views/frame/browser_view.h
239+++ chrome/browser/ui/views/frame/browser_view.h
240@@ -112,7 +112,9 @@ class BrowserView : public BrowserWindow,
241                     public webapps::AppBannerManager::Observer {
242  public:
243   METADATA_HEADER(BrowserView);
244+  BrowserView();
245   explicit BrowserView(std::unique_ptr<Browser> browser);
246+  void InitBrowser(std::unique_ptr<Browser> browser);
247   BrowserView(const BrowserView&) = delete;
248   BrowserView& operator=(const BrowserView&) = delete;
249   ~BrowserView() override;
250@@ -624,6 +626,12 @@ class BrowserView : public BrowserWindow,
251     return accessibility_focus_highlight_.get();
252   }
253
254+ protected:
255+  virtual ToolbarView* OverrideCreateToolbar(Browser* browser,
256+                                             BrowserView* browser_view) {
257+    return nullptr;
258+  }
259+
260  private:
261   // Do not friend BrowserViewLayout. Use the BrowserViewLayoutDelegate
262   // interface to keep these two classes decoupled and testable.
263diff --git chrome/browser/ui/views/frame/browser_view_layout.cc chrome/browser/ui/views/frame/browser_view_layout.cc
264index 56ef53cf379d..f0f1057896bd 100644
265--- chrome/browser/ui/views/frame/browser_view_layout.cc
266+++ chrome/browser/ui/views/frame/browser_view_layout.cc
267@@ -415,6 +415,12 @@ int BrowserViewLayout::LayoutWebUITabStrip(int top) {
268
269 int BrowserViewLayout::LayoutToolbar(int top) {
270   TRACE_EVENT0("ui", "BrowserViewLayout::LayoutToolbar");
271+  if (toolbar_->parent() && toolbar_->parent()->GetLayoutManager() != this &&
272+      toolbar_->parent()->GetLayoutManager() != nullptr) {
273+    // CEF may take ownership of the toolbar. Early exit to avoid the DCHECK
274+    // in LayoutManager::SetViewVisibility().
275+    return top;
276+  }
277   int browser_view_width = vertical_layout_rect_.width();
278   bool toolbar_visible = delegate_->IsToolbarVisible();
279   int height = toolbar_visible ? toolbar_->GetPreferredSize().height() : 0;
280diff --git chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
281index 8f35534df18f..c29ebc024aa2 100644
282--- chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
283+++ chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
284@@ -580,37 +580,53 @@ gfx::Range BrowserTabStripController::ListTabsInGroup(
285 }
286
287 bool BrowserTabStripController::IsFrameCondensed() const {
288+  if (!GetFrameView())
289+    return false;
290   return GetFrameView()->IsFrameCondensed();
291 }
292
293 bool BrowserTabStripController::HasVisibleBackgroundTabShapes() const {
294+  if (!GetFrameView())
295+    return false;
296   return GetFrameView()->HasVisibleBackgroundTabShapes(
297       BrowserFrameActiveState::kUseCurrent);
298 }
299
300 bool BrowserTabStripController::EverHasVisibleBackgroundTabShapes() const {
301+  if (!GetFrameView())
302+    return false;
303   return GetFrameView()->EverHasVisibleBackgroundTabShapes();
304 }
305
306 bool BrowserTabStripController::ShouldPaintAsActiveFrame() const {
307+  if (!GetFrameView())
308+    return false;
309   return GetFrameView()->ShouldPaintAsActive();
310 }
311
312 bool BrowserTabStripController::CanDrawStrokes() const {
313+  if (!GetFrameView())
314+    return false;
315   return GetFrameView()->CanDrawStrokes();
316 }
317
318 SkColor BrowserTabStripController::GetFrameColor(
319     BrowserFrameActiveState active_state) const {
320+  if (!GetFrameView())
321+    return SK_ColorWHITE;
322   return GetFrameView()->GetFrameColor(active_state);
323 }
324
325 SkColor BrowserTabStripController::GetToolbarTopSeparatorColor() const {
326+  if (!GetFrameView())
327+    return SK_ColorWHITE;
328   return GetFrameView()->GetToolbarTopSeparatorColor();
329 }
330
331 base::Optional<int> BrowserTabStripController::GetCustomBackgroundId(
332     BrowserFrameActiveState active_state) const {
333+  if (!GetFrameView())
334+    return base::nullopt;
335   return GetFrameView()->GetCustomBackgroundId(active_state);
336 }
337
338diff --git chrome/browser/ui/views/toolbar/toolbar_view.cc chrome/browser/ui/views/toolbar/toolbar_view.cc
339index 5f6e182d017d..be85e6df707d 100644
340--- chrome/browser/ui/views/toolbar/toolbar_view.cc
341+++ chrome/browser/ui/views/toolbar/toolbar_view.cc
342@@ -156,12 +156,13 @@ auto& GetViewCommandMap() {
343 ////////////////////////////////////////////////////////////////////////////////
344 // ToolbarView, public:
345
346-ToolbarView::ToolbarView(Browser* browser, BrowserView* browser_view)
347+ToolbarView::ToolbarView(Browser* browser, BrowserView* browser_view,
348+                         base::Optional<DisplayMode> display_mode)
349     : AnimationDelegateViews(this),
350       browser_(browser),
351       browser_view_(browser_view),
352       app_menu_icon_controller_(browser->profile(), this),
353-      display_mode_(GetDisplayMode(browser)) {
354+      display_mode_(display_mode ? *display_mode : GetDisplayMode(browser)) {
355   SetID(VIEW_ID_TOOLBAR);
356
357   UpgradeDetector::GetInstance()->AddObserver(this);
358@@ -194,7 +195,7 @@ void ToolbarView::Init() {
359 #endif
360   auto location_bar = std::make_unique<LocationBarView>(
361       browser_, browser_->profile(), browser_->command_controller(), this,
362-      display_mode_ != DisplayMode::NORMAL);
363+      display_mode_ != DisplayMode::NORMAL && !browser_->toolbar_overridden());
364   // Make sure the toolbar shows by default.
365   size_animation_.Reset(1);
366
367diff --git chrome/browser/ui/views/toolbar/toolbar_view.h chrome/browser/ui/views/toolbar/toolbar_view.h
368index 99358217419a..425a0741b55a 100644
369--- chrome/browser/ui/views/toolbar/toolbar_view.h
370+++ chrome/browser/ui/views/toolbar/toolbar_view.h
371@@ -87,7 +87,8 @@ class ToolbarView : public views::AccessiblePaneView,
372                 // needs to be displayed.
373   };
374
375-  ToolbarView(Browser* browser, BrowserView* browser_view);
376+  ToolbarView(Browser* browser, BrowserView* browser_view,
377+              base::Optional<DisplayMode> display_mode);
378   ToolbarView(const ToolbarView&) = delete;
379   ToolbarView& operator=(const ToolbarView&) = delete;
380   ~ToolbarView() override;
381