OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/frame/browser_view.h" | 5 #include "chrome/browser/ui/views/frame/browser_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 #include "ui/base/resource/resource_bundle.h" | 128 #include "ui/base/resource/resource_bundle.h" |
129 #include "ui/base/theme_provider.h" | 129 #include "ui/base/theme_provider.h" |
130 #include "ui/content_accelerators/accelerator_util.h" | 130 #include "ui/content_accelerators/accelerator_util.h" |
131 #include "ui/events/event_utils.h" | 131 #include "ui/events/event_utils.h" |
132 #include "ui/gfx/canvas.h" | 132 #include "ui/gfx/canvas.h" |
133 #include "ui/gfx/color_utils.h" | 133 #include "ui/gfx/color_utils.h" |
134 #include "ui/gfx/geometry/rect_conversions.h" | 134 #include "ui/gfx/geometry/rect_conversions.h" |
135 #include "ui/gfx/screen.h" | 135 #include "ui/gfx/screen.h" |
136 #include "ui/strings/grit/ui_strings.h" | 136 #include "ui/strings/grit/ui_strings.h" |
137 #include "ui/views/controls/button/menu_button.h" | 137 #include "ui/views/controls/button/menu_button.h" |
| 138 #include "ui/views/controls/single_split_view.h" |
| 139 #include "ui/views/controls/single_split_view_listener.h" |
138 #include "ui/views/controls/textfield/textfield.h" | 140 #include "ui/views/controls/textfield/textfield.h" |
139 #include "ui/views/controls/webview/webview.h" | 141 #include "ui/views/controls/webview/webview.h" |
140 #include "ui/views/focus/external_focus_tracker.h" | 142 #include "ui/views/focus/external_focus_tracker.h" |
141 #include "ui/views/focus/view_storage.h" | 143 #include "ui/views/focus/view_storage.h" |
| 144 #include "ui/views/layout/box_layout.h" |
142 #include "ui/views/layout/grid_layout.h" | 145 #include "ui/views/layout/grid_layout.h" |
143 #include "ui/views/widget/native_widget.h" | 146 #include "ui/views/widget/native_widget.h" |
144 #include "ui/views/widget/root_view.h" | 147 #include "ui/views/widget/root_view.h" |
145 #include "ui/views/widget/widget.h" | 148 #include "ui/views/widget/widget.h" |
146 #include "ui/views/window/dialog_delegate.h" | 149 #include "ui/views/window/dialog_delegate.h" |
147 | 150 |
148 #if defined(USE_AURA) | 151 #if defined(USE_AURA) |
149 #include "ui/aura/client/window_tree_client.h" | 152 #include "ui/aura/client/window_tree_client.h" |
150 #include "ui/aura/window.h" | 153 #include "ui/aura/window.h" |
151 #include "ui/aura/window_tree_host.h" | 154 #include "ui/aura/window_tree_host.h" |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 paint.setColor(color); | 564 paint.setColor(color); |
562 canvas->sk_canvas()->drawRect(gfx::RectFToSkRect(bounds), paint); | 565 canvas->sk_canvas()->drawRect(gfx::RectFToSkRect(bounds), paint); |
563 canvas->Restore(); | 566 canvas->Restore(); |
564 } | 567 } |
565 | 568 |
566 void BrowserView::InitStatusBubble() { | 569 void BrowserView::InitStatusBubble() { |
567 status_bubble_.reset(new StatusBubbleViews(contents_web_view_)); | 570 status_bubble_.reset(new StatusBubbleViews(contents_web_view_)); |
568 contents_web_view_->SetStatusBubble(status_bubble_.get()); | 571 contents_web_view_->SetStatusBubble(status_bubble_.get()); |
569 } | 572 } |
570 | 573 |
| 574 bool BrowserView::SplitHandleMoved(views::SingleSplitView* sender) { |
| 575 for (int i = 0; i < sender->child_count(); ++i) |
| 576 sender->child_at(i)->InvalidateLayout(); |
| 577 SchedulePaint(); |
| 578 Layout(); |
| 579 return false; |
| 580 } |
| 581 |
571 gfx::Rect BrowserView::GetToolbarBounds() const { | 582 gfx::Rect BrowserView::GetToolbarBounds() const { |
572 gfx::Rect toolbar_bounds(toolbar_->bounds()); | 583 gfx::Rect toolbar_bounds(toolbar_->bounds()); |
573 if (toolbar_bounds.IsEmpty()) | 584 if (toolbar_bounds.IsEmpty()) |
574 return toolbar_bounds; | 585 return toolbar_bounds; |
575 // The apparent toolbar edges are outside the "real" toolbar edges. | 586 // The apparent toolbar edges are outside the "real" toolbar edges. |
576 toolbar_bounds.Inset(-views::NonClientFrameView::kClientEdgeThickness, 0); | 587 toolbar_bounds.Inset(-views::NonClientFrameView::kClientEdgeThickness, 0); |
577 return toolbar_bounds; | 588 return toolbar_bounds; |
578 } | 589 } |
579 | 590 |
580 gfx::Rect BrowserView::GetFindBarBoundingBox() const { | 591 gfx::Rect BrowserView::GetFindBarBoundingBox() const { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 } | 686 } |
676 | 687 |
677 WebContents* BrowserView::GetActiveWebContents() const { | 688 WebContents* BrowserView::GetActiveWebContents() const { |
678 return browser_->tab_strip_model()->GetActiveWebContents(); | 689 return browser_->tab_strip_model()->GetActiveWebContents(); |
679 } | 690 } |
680 | 691 |
681 gfx::ImageSkia BrowserView::GetOTRAvatarIcon() const { | 692 gfx::ImageSkia BrowserView::GetOTRAvatarIcon() const { |
682 return *GetThemeProvider()->GetImageSkiaNamed(IDR_OTR_ICON); | 693 return *GetThemeProvider()->GetImageSkiaNamed(IDR_OTR_ICON); |
683 } | 694 } |
684 | 695 |
| 696 void BrowserView::ShowSidebar(content::WebContents* sidebar_contents) { |
| 697 UpdateSidebarForContents(sidebar_contents); |
| 698 } |
| 699 |
| 700 void BrowserView::HideSidebar() { |
| 701 UpdateSidebarForContents(nullptr); |
| 702 } |
| 703 |
685 /////////////////////////////////////////////////////////////////////////////// | 704 /////////////////////////////////////////////////////////////////////////////// |
686 // BrowserView, BrowserWindow implementation: | 705 // BrowserView, BrowserWindow implementation: |
687 | 706 |
688 void BrowserView::Show() { | 707 void BrowserView::Show() { |
689 #if !defined(OS_WIN) | 708 #if !defined(OS_WIN) |
690 // The Browser associated with this browser window must become the active | 709 // The Browser associated with this browser window must become the active |
691 // browser at the time |Show()| is called. This is the natural behavior under | 710 // browser at the time |Show()| is called. This is the natural behavior under |
692 // Windows and Ash, but other platforms will not trigger | 711 // Windows and Ash, but other platforms will not trigger |
693 // OnWidgetActivationChanged() until we return to the runloop. Therefore any | 712 // OnWidgetActivationChanged() until we return to the runloop. Therefore any |
694 // calls to Browser::GetLastActive() will return the wrong result if we do not | 713 // calls to Browser::GetLastActive() will return the wrong result if we do not |
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1332 anchor_view = toolbar_->app_menu(); | 1351 anchor_view = toolbar_->app_menu(); |
1333 else | 1352 else |
1334 anchor_view = toolbar_->location_bar(); | 1353 anchor_view = toolbar_->location_bar(); |
1335 | 1354 |
1336 OneClickSigninBubbleView::ShowBubble(type, email, error_message, | 1355 OneClickSigninBubbleView::ShowBubble(type, email, error_message, |
1337 delegate.Pass(), anchor_view, | 1356 delegate.Pass(), anchor_view, |
1338 start_sync_callback); | 1357 start_sync_callback); |
1339 } | 1358 } |
1340 #endif | 1359 #endif |
1341 | 1360 |
| 1361 int BrowserView::GetSidebarWidth() const { |
| 1362 if (!sidebar_container_ || !sidebar_container_->visible()) |
| 1363 return 0; |
| 1364 return sidebar_split_->divider_offset(); |
| 1365 } |
| 1366 |
1342 void BrowserView::SetDownloadShelfVisible(bool visible) { | 1367 void BrowserView::SetDownloadShelfVisible(bool visible) { |
1343 // This can be called from the superclass destructor, when it destroys our | 1368 // This can be called from the superclass destructor, when it destroys our |
1344 // child views. At that point, browser_ is already gone. | 1369 // child views. At that point, browser_ is already gone. |
1345 if (!browser_) | 1370 if (!browser_) |
1346 return; | 1371 return; |
1347 | 1372 |
1348 if (visible && IsDownloadShelfVisible() != visible) { | 1373 if (visible && IsDownloadShelfVisible() != visible) { |
1349 // Invoke GetDownloadShelf to force the shelf to be created. | 1374 // Invoke GetDownloadShelf to force the shelf to be created. |
1350 GetDownloadShelf(); | 1375 GetDownloadShelf(); |
1351 } | 1376 } |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 // the model has already removed |contents| from its list, so | 1618 // the model has already removed |contents| from its list, so |
1594 // browser_->GetActiveWebContents() will return null or something else. | 1619 // browser_->GetActiveWebContents() will return null or something else. |
1595 if (index == browser_->tab_strip_model()->active_index()) { | 1620 if (index == browser_->tab_strip_model()->active_index()) { |
1596 // We need to reset the current tab contents to null before it gets | 1621 // We need to reset the current tab contents to null before it gets |
1597 // freed. This is because the focus manager performs some operations | 1622 // freed. This is because the focus manager performs some operations |
1598 // on the selected WebContents when it is removed. | 1623 // on the selected WebContents when it is removed. |
1599 web_contents_close_handler_->ActiveTabChanged(); | 1624 web_contents_close_handler_->ActiveTabChanged(); |
1600 contents_web_view_->SetWebContents(nullptr); | 1625 contents_web_view_->SetWebContents(nullptr); |
1601 infobar_container_->ChangeInfoBarManager(nullptr); | 1626 infobar_container_->ChangeInfoBarManager(nullptr); |
1602 UpdateDevToolsForContents(nullptr, true); | 1627 UpdateDevToolsForContents(nullptr, true); |
| 1628 UpdateSidebarForContents(nullptr); |
1603 } | 1629 } |
1604 } | 1630 } |
1605 | 1631 |
1606 void BrowserView::TabDeactivated(WebContents* contents) { | 1632 void BrowserView::TabDeactivated(WebContents* contents) { |
1607 if (PermissionBubbleManager::FromWebContents(contents)) | 1633 if (PermissionBubbleManager::FromWebContents(contents)) |
1608 PermissionBubbleManager::FromWebContents(contents)->HideBubble(); | 1634 PermissionBubbleManager::FromWebContents(contents)->HideBubble(); |
1609 | 1635 |
1610 // We do not store the focus when closing the tab to work-around bug 4633. | 1636 // We do not store the focus when closing the tab to work-around bug 4633. |
1611 // Some reports seem to show that the focus manager and/or focused view can | 1637 // Some reports seem to show that the focus manager and/or focused view can |
1612 // be garbage at that point, it is not clear why. | 1638 // be garbage at that point, it is not clear why. |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2070 devtools_web_view_->SetVisible(false); | 2096 devtools_web_view_->SetVisible(false); |
2071 | 2097 |
2072 contents_container_ = new views::View(); | 2098 contents_container_ = new views::View(); |
2073 contents_container_->set_background(views::Background::CreateSolidBackground( | 2099 contents_container_->set_background(views::Background::CreateSolidBackground( |
2074 ThemeProperties::GetDefaultColor( | 2100 ThemeProperties::GetDefaultColor( |
2075 ThemeProperties::COLOR_CONTROL_BACKGROUND))); | 2101 ThemeProperties::COLOR_CONTROL_BACKGROUND))); |
2076 contents_container_->AddChildView(devtools_web_view_); | 2102 contents_container_->AddChildView(devtools_web_view_); |
2077 contents_container_->AddChildView(contents_web_view_); | 2103 contents_container_->AddChildView(contents_web_view_); |
2078 contents_container_->SetLayoutManager(new ContentsLayoutManager( | 2104 contents_container_->SetLayoutManager(new ContentsLayoutManager( |
2079 devtools_web_view_, contents_web_view_)); | 2105 devtools_web_view_, contents_web_view_)); |
2080 AddChildView(contents_container_); | 2106 |
2081 set_contents_view(contents_container_); | 2107 sidebar_web_view_ = new views::WebView(browser_->profile()); |
| 2108 sidebar_web_view_->set_id(VIEW_ID_SIDE_BAR_VIEW); |
| 2109 sidebar_web_view_->SetVisible(false); |
| 2110 |
| 2111 sidebar_container_ = new views::View(); |
| 2112 sidebar_container_->AddChildView(sidebar_web_view_); |
| 2113 sidebar_container_->set_id(VIEW_ID_SIDE_BAR_CONTAINER); |
| 2114 sidebar_container_->SetVisible(false); |
| 2115 |
| 2116 sidebar_split_ = new views::SingleSplitView( |
| 2117 contents_container_, sidebar_container_, |
| 2118 views::SingleSplitView::HORIZONTAL_SPLIT, this); |
| 2119 |
| 2120 sidebar_split_->set_id(VIEW_ID_SIDE_BAR_SPLIT); |
| 2121 sidebar_split_->set_background(views::Background::CreateSolidBackground( |
| 2122 GetWidget()->GetThemeProvider()->GetColor( |
| 2123 ThemeProperties::COLOR_TOOLBAR))); |
| 2124 sidebar_split_->set_resize_leading_on_bounds_change(false); |
| 2125 AddChildView(sidebar_split_); |
| 2126 set_contents_view(sidebar_split_); |
2082 | 2127 |
2083 // Top container holds tab strip and toolbar and lives at the front of the | 2128 // Top container holds tab strip and toolbar and lives at the front of the |
2084 // view hierarchy. | 2129 // view hierarchy. |
2085 top_container_ = new TopContainerView(this); | 2130 top_container_ = new TopContainerView(this); |
2086 AddChildView(top_container_); | 2131 AddChildView(top_container_); |
2087 | 2132 |
2088 // TabStrip takes ownership of the controller. | 2133 // TabStrip takes ownership of the controller. |
2089 BrowserTabStripController* tabstrip_controller = | 2134 BrowserTabStripController* tabstrip_controller = |
2090 new BrowserTabStripController(browser_.get(), | 2135 new BrowserTabStripController(browser_.get(), |
2091 browser_->tab_strip_model()); | 2136 browser_->tab_strip_model()); |
2092 tabstrip_ = new TabStrip(tabstrip_controller); | 2137 tabstrip_ = new TabStrip(tabstrip_controller); |
2093 top_container_->AddChildView(tabstrip_); | 2138 top_container_->AddChildView(tabstrip_); |
2094 tabstrip_controller->InitFromModel(tabstrip_); | 2139 tabstrip_controller->InitFromModel(tabstrip_); |
2095 | 2140 |
2096 toolbar_ = new ToolbarView(browser_.get()); | 2141 toolbar_ = new ToolbarView(browser_.get()); |
2097 top_container_->AddChildView(toolbar_); | 2142 top_container_->AddChildView(toolbar_); |
2098 toolbar_->Init(); | 2143 toolbar_->Init(); |
2099 | 2144 |
2100 InitStatusBubble(); | 2145 InitStatusBubble(); |
2101 | 2146 |
2102 // Create do-nothing view for the sake of controlling the z-order of the find | 2147 // Create do-nothing view for the sake of controlling the z-order of the find |
2103 // bar widget. | 2148 // bar widget. |
2104 find_bar_host_view_ = new View(); | 2149 find_bar_host_view_ = new View(); |
2105 AddChildView(find_bar_host_view_); | 2150 AddChildView(find_bar_host_view_); |
2106 | 2151 |
2107 immersive_mode_controller_->Init(this); | 2152 immersive_mode_controller_->Init(this); |
2108 | 2153 |
2109 BrowserViewLayout* browser_view_layout = new BrowserViewLayout; | 2154 BrowserViewLayout* browser_view_layout = new BrowserViewLayout; |
2110 browser_view_layout->Init(new BrowserViewLayoutDelegateImpl(this), | 2155 browser_view_layout->Init( |
2111 browser(), | 2156 new BrowserViewLayoutDelegateImpl(this), browser(), this, top_container_, |
2112 this, | 2157 tabstrip_, toolbar_, infobar_container_, sidebar_split_, |
2113 top_container_, | 2158 GetContentsLayoutManager(), immersive_mode_controller_.get()); |
2114 tabstrip_, | |
2115 toolbar_, | |
2116 infobar_container_, | |
2117 contents_container_, | |
2118 GetContentsLayoutManager(), | |
2119 immersive_mode_controller_.get()); | |
2120 SetLayoutManager(browser_view_layout); | 2159 SetLayoutManager(browser_view_layout); |
2121 | 2160 |
2122 #if defined(OS_WIN) | 2161 #if defined(OS_WIN) |
2123 // Create a custom JumpList and add it to an observer of TabRestoreService | 2162 // Create a custom JumpList and add it to an observer of TabRestoreService |
2124 // so we can update the custom JumpList when a tab is added or removed. | 2163 // so we can update the custom JumpList when a tab is added or removed. |
2125 if (JumpList::Enabled()) { | 2164 if (JumpList::Enabled()) { |
2126 load_complete_listener_.reset(new LoadCompleteListener(this)); | 2165 load_complete_listener_.reset(new LoadCompleteListener(this)); |
2127 } | 2166 } |
2128 #endif | 2167 #endif |
2129 | 2168 |
2130 GetLocationBar()->GetOmniboxView()->model()->popup_model()->AddObserver(this); | 2169 GetLocationBar()->GetOmniboxView()->model()->popup_model()->AddObserver(this); |
2131 } | 2170 } |
2132 | 2171 |
| 2172 void BrowserView::UpdateSidebarForContents( |
| 2173 content::WebContents* sidebar_contents) { |
| 2174 if (!sidebar_container_) |
| 2175 return; // Happens when sidebar is not allowed. |
| 2176 |
| 2177 bool visible = nullptr != sidebar_contents; |
| 2178 |
| 2179 bool should_show = visible && !sidebar_container_->visible(); |
| 2180 bool should_hide = !visible && sidebar_container_->visible(); |
| 2181 |
| 2182 sidebar_web_view_->SetWebContents(sidebar_contents); |
| 2183 |
| 2184 // Update sidebar UI width. |
| 2185 if (should_show) { |
| 2186 // Restore split offset. |
| 2187 int sidebar_width = g_browser_process->local_state()->GetInteger( |
| 2188 prefs::kExtensionSidebarWidth); |
| 2189 if (sidebar_width < 0) { |
| 2190 // By default sidebar width is 1/7th of the current page content width. |
| 2191 sidebar_width = sidebar_split_->width() / 7; |
| 2192 } |
| 2193 int min_sidebar_width = sidebar_split_->GetMinimumSize().width(); |
| 2194 // Not allowed to be wider than 50% of the split-view's frame |
| 2195 sidebar_width = std::min(sidebar_split_->width() / 2 - min_sidebar_width, |
| 2196 std::max(min_sidebar_width, sidebar_width)); |
| 2197 sidebar_split_->set_divider_offset(sidebar_split_->width() - sidebar_width); |
| 2198 |
| 2199 sidebar_container_->SetVisible(true); |
| 2200 sidebar_web_view_->SetVisible(true); |
| 2201 sidebar_split_->InvalidateLayout(); |
| 2202 Layout(); |
| 2203 |
| 2204 } else if (should_hide) { |
| 2205 // Store split offset when hiding sidebar only. |
| 2206 g_browser_process->local_state()->SetInteger( |
| 2207 prefs::kExtensionSidebarWidth, |
| 2208 sidebar_split_->width() - sidebar_split_->divider_offset()); |
| 2209 |
| 2210 sidebar_container_->SetVisible(false); |
| 2211 sidebar_split_->InvalidateLayout(); |
| 2212 Layout(); |
| 2213 } |
| 2214 } |
| 2215 |
2133 void BrowserView::LoadingAnimationCallback() { | 2216 void BrowserView::LoadingAnimationCallback() { |
2134 base::TimeTicks now = base::TimeTicks::Now(); | 2217 base::TimeTicks now = base::TimeTicks::Now(); |
2135 if (!last_animation_time_.is_null()) { | 2218 if (!last_animation_time_.is_null()) { |
2136 UMA_HISTOGRAM_TIMES( | 2219 UMA_HISTOGRAM_TIMES( |
2137 "Tabs.LoadingAnimationTime", | 2220 "Tabs.LoadingAnimationTime", |
2138 now - last_animation_time_); | 2221 now - last_animation_time_); |
2139 } | 2222 } |
2140 last_animation_time_ = now; | 2223 last_animation_time_ = now; |
2141 if (browser_->is_type_tabbed()) { | 2224 if (browser_->is_type_tabbed()) { |
2142 // Loading animations are shown in the tab for tabbed windows. We check the | 2225 // Loading animations are shown in the tab for tabbed windows. We check the |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 return immersive_mode_controller()->IsEnabled(); | 2706 return immersive_mode_controller()->IsEnabled(); |
2624 } | 2707 } |
2625 | 2708 |
2626 views::Widget* BrowserView::GetBubbleAssociatedWidget() { | 2709 views::Widget* BrowserView::GetBubbleAssociatedWidget() { |
2627 return GetWidget(); | 2710 return GetWidget(); |
2628 } | 2711 } |
2629 | 2712 |
2630 gfx::Rect BrowserView::GetTopContainerBoundsInScreen() { | 2713 gfx::Rect BrowserView::GetTopContainerBoundsInScreen() { |
2631 return top_container_->GetBoundsInScreen(); | 2714 return top_container_->GetBoundsInScreen(); |
2632 } | 2715 } |
OLD | NEW |