12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/auto_reset.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h" 12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_dll_resource.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_stats.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/extension_util.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/native_window_notification_source.h" 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/profiles/avatar_menu.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/profiles/profile_avatar_icon_util.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_info_cache.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/profiles/profiles_state.h" 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/search/search.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sessions/tab_restore_service_factory.h" 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/signin/signin_header_helper.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/speech/tts_controller.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/themes/theme_properties.h" 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/browser/themes/theme_service_factory.h" 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/translate/chrome_translate_client.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h" 43ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h" 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_command_controller.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window_state.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_popup_view.h" 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_view.h" 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/search/search_delegate.h" 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/search/search_model.h" 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/search/search_ui.h" 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_menu_model.h" 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/view_ids.h" 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/accelerator_table.h" 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/accessibility/invert_bubble_view.h" 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h" 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/browser_dialogs.h" 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/download/download_in_progress_dialog_view.h" 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/download/download_shelf_view.h" 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/extensions/bookmark_app_bubble_view.h" 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view_layout.h" 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h" 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/frame/contents_layout_manager.h" 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/immersive_mode_controller.h" 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/frame/top_container_view.h" 75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "chrome/browser/ui/views/frame/web_contents_close_handler.h" 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/fullscreen_exit_bubble_views.h" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/infobars/infobar_container_view.h" 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/location_bar/location_icon_view.h" 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/views/profiles/avatar_menu_bubble_view.h" 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/views/profiles/avatar_menu_button.h" 83c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/ui/views/profiles/profile_chooser_view.h" 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "chrome/browser/ui/views/settings_api_bubble_helper_views.h" 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/status_bubble_views.h" 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab.h" 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab_strip.h" 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/reload_button.h" 90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar/toolbar_view.h" 911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/ui/views/translate/translate_bubble_view.h" 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/update_recommended_message_box.h" 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/views/website_settings/permissions_bubble_view.h" 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h" 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/website_settings/permission_bubble_manager.h" 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/window_sizer/window_sizer.h" 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/chromium_strings.h" 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/generated_resources.h" 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/grit/locale_settings.h" 1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/signin/core/common/profile_management_switches.h" 104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "components/translate/core/browser/language_state.h" 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/app/resources/grit/content_resources.h" 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_manager.h" 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/native_web_keyboard_event.h" 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_frame_host.h" 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h" 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h" 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/client/window_tree_client.h" 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/window.h" 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/aura/window_tree_host.h" 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h" 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h" 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/theme_provider.h" 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h" 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h" 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h" 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/rect_conversions.h" 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ui/gfx/screen.h" 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/strings/grit/ui_strings.h" 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "ui/views/controls/button/menu_button.h" 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/textfield/textfield.h" 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/webview/webview.h" 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/external_focus_tracker.h" 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/focus/view_storage.h" 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h" 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/native_widget.h" 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/root_view.h" 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/dialog_delegate.h" 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/windows_version.h" 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/jumplist_win.h" 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/views/win/scoped_fullscreen_visibility.h" 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_ONE_CLICK_SIGNIN) 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/sync/one_click_signin_bubble_delegate.h" 149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "chrome/browser/ui/sync/one_click_signin_bubble_links_delegate.h" 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/sync/one_click_signin_bubble_view.h" 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_CHROMEOS) 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 1551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 1561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NativeWebKeyboardEvent; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::SSLStatus; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::ColumnSet; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::GridLayout; 16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using web_modal::WebContentsModalDialogHost; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The name of a key to store on the window handle so that other code can 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// locate this object using just the handle. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kBrowserViewKey = "__BROWSER_VIEW__"; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The number of milliseconds between loading animation frames. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kLoadingAnimationFrameTimeMs = 30; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(kuan): These functions are temporarily for the bookmark bar while its 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// detached state is at the top of the page; it'll be moved to float on the 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// content page in the very near future, at which time, these local functions 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// will be removed. 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PaintDetachedBookmarkBar(gfx::Canvas* canvas, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DetachableToolbarView* view, 180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) ThemeService* theme_service) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Paint background for detached state; if animating, this is fade in/out. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->DrawColor( 183b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chrome::GetDetachedBookmarkBarBackgroundColor(theme_service)); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Draw the separators above and below bookmark bar; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if animating, these are fading in/out. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColor separator_color = 187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) chrome::GetDetachedBookmarkBarSeparatorColor(theme_service); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DetachableToolbarView::PaintHorizontalBorder(canvas, view, true, 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) separator_color); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The bottom border needs to be 1-px thick in both regular and retina 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // displays, so we can't use DetachableToolbarView::PaintHorizontalBorder 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which paints a 2-px thick border in retina display. 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkPaint paint; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setAntiAlias(false); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sets border to 1-px thick regardless of scale factor. 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setStrokeWidth(0); 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Bottom border is at 50% opacity of top border. 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) paint.setColor(SkColorSetA(separator_color, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkColorGetA(separator_color) / 2)); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Calculate thickness of bottom border as per current scale factor to 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // determine where to draw the 1-px thick border. 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float thickness = views::NonClientFrameView::kClientEdgeThickness / 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) canvas->image_scale(); 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkScalar y = SkIntToScalar(view->height()) - SkFloatToScalar(thickness); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) canvas->sk_canvas()->drawLine(SkIntToScalar(0), y, 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SkIntToScalar(view->width()), y, paint); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PaintAttachedBookmarkBar(gfx::Canvas* canvas, 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DetachableToolbarView* view, 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserView* browser_view, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::HostDesktopType host_desktop_type, 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int toolbar_overlap) { 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Paint background for attached state, this is fade in/out. 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Point background_image_offset = 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser_view->OffsetPointForToolbarBackgroundImage( 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Point(view->GetMirroredX(), view->y())); 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DetachableToolbarView::PaintBackgroundAttachedMode(canvas, 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) view->GetThemeProvider(), view->GetLocalBounds(), 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) background_image_offset, host_desktop_type); 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (view->height() >= toolbar_overlap) { 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Draw the separator below bookmark bar; this is fading in/out. 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DetachableToolbarView::PaintHorizontalBorder(canvas, view, false, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThemeProperties::GetDefaultColor( 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// static 232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const char BrowserView::kViewClassName[] = "BrowserView"; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Delegate implementation for BrowserViewLayout. Usually just forwards calls 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// into BrowserView. 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate { 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public: 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) explicit BrowserViewLayoutDelegateImpl(BrowserView* browser_view) 24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : browser_view_(browser_view) {} 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual ~BrowserViewLayoutDelegateImpl() {} 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // BrowserViewLayoutDelegate overrides: 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual views::View* GetContentsWebView() const OVERRIDE { 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return browser_view_->contents_web_view_; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool DownloadShelfNeedsLayout() const OVERRIDE { 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DownloadShelfView* download_shelf = browser_view_->download_shelf_.get(); 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Re-layout the shelf either if it is visible or if its close animation 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // is currently running. 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return download_shelf && 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) (download_shelf->IsShowing() || download_shelf->IsClosing()); 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool IsTabStripVisible() const OVERRIDE { 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return browser_view_->IsTabStripVisible(); 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual gfx::Rect GetBoundsForTabStripInBrowserView() const OVERRIDE { 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::RectF bounds_f(browser_view_->frame()->GetBoundsForTabStrip( 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_view_->tabstrip())); 264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) views::View::ConvertRectToTarget(browser_view_->parent(), browser_view_, 265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &bounds_f); 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return gfx::ToEnclosingRect(bounds_f); 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual int GetTopInsetInBrowserView() const OVERRIDE { 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return browser_view_->frame()->GetTopInset() - 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) browser_view_->y(); 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual int GetThemeBackgroundXInset() const OVERRIDE { 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(pkotwicz): Return the inset with respect to the left edge of the 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // BrowserView. 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return browser_view_->frame()->GetThemeBackgroundXInset(); 27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool IsToolbarVisible() const OVERRIDE { 28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return browser_view_->IsToolbarVisible(); 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual bool IsBookmarkBarVisible() const OVERRIDE { 28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return browser_view_->IsBookmarkBarVisible(); 28690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE { 2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return browser_view_->fullscreen_exit_bubble(); 2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private: 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserView* browser_view_; 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutDelegateImpl); 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BookmarkExtensionBackground, private: 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This object serves as the views::Background object which is used to layout 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and paint the bookmark bar. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkExtensionBackground : public views::Background { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkExtensionBackground(BrowserView* browser_view, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView* host_view, 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // View methods overridden from views:Background. 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserView* browser_view_; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The view hosting this background. 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView* host_view_; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser_; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BookmarkExtensionBackground); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BookmarkExtensionBackground::BookmarkExtensionBackground( 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserView* browser_view, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DetachableToolbarView* host_view, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* browser) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : browser_view_(browser_view), 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_view_(host_view), 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_(browser) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BookmarkExtensionBackground::Paint(gfx::Canvas* canvas, 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* view) const { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int toolbar_overlap = host_view_->GetToolbarOverlap(); 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!host_view_->IsDetached()) { 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PaintAttachedBookmarkBar(canvas, host_view_, browser_view_, 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_->host_desktop_type(), toolbar_overlap); 337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // As 'hidden' according to the animation is the full in-tab state, we invert 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the value - when current_state is at '0', we expect the bar to be docked. 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch double current_state = 1 - host_view_->GetAnimationValue(); 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ThemeService* ts = 345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ThemeServiceFactory::GetForProfile(browser_->profile()); 346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (current_state == 0.0 || current_state == 1.0) { 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PaintDetachedBookmarkBar(canvas, host_view_, ts); 348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // While animating, set opacity to cross-fade between attached and detached 351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // backgrounds including their respective separators. 352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int detached_alpha = static_cast<uint8>(current_state * 255); 353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int attached_alpha = 255 - detached_alpha; 354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (browser_->bookmark_bar_state() == BookmarkBar::DETACHED) { 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // To animate from attached to detached state: 356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - fade out attached background 357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - fade in detached background. 358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->SaveLayerAlpha(attached_alpha); 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PaintAttachedBookmarkBar(canvas, host_view_, browser_view_, 360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_->host_desktop_type(), 361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch toolbar_overlap); 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->Restore(); 363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->SaveLayerAlpha(detached_alpha); 364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PaintDetachedBookmarkBar(canvas, host_view_, ts); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // To animate from detached to attached state: 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - fade out detached background 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // - fade in attached background. 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->SaveLayerAlpha(detached_alpha); 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PaintDetachedBookmarkBar(canvas, host_view_, ts); 371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->Restore(); 372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->SaveLayerAlpha(attached_alpha); 373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PaintAttachedBookmarkBar(canvas, host_view_, browser_view_, 374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch browser_->host_desktop_type(), 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch toolbar_overlap); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch canvas->Restore(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserView, public: 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BrowserView::BrowserView() 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : views::ClientView(NULL, NULL), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_focused_view_storage_id_( 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ViewStorage::GetInstance()->CreateStorageID()), 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_(NULL), 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) top_container_(NULL), 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabstrip_(NULL), 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_(NULL), 391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) find_bar_host_view_(NULL), 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infobar_container_(NULL), 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) contents_web_view_(NULL), 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) contents_container_(NULL), 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_(false), 3961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) in_process_fullscreen_(false), 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hung_window_detector_(&hung_plugin_action_), 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticker_(0), 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_location_bar_focus_(false), 402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_CHROMEOS) 403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scroll_end_effect_controller_(ScrollEndEffectController::Create()), 404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) activate_modal_dialog_factory_(this) { 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserView::~BrowserView() { 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // All the tabs should have been destroyed already. If we were closed by the 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // OS with some tabs than the NativeBrowserFrame should have destroyed them. 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0, browser_->tab_strip_model()->count()); 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Immersive mode may need to reparent views before they are removed/deleted. 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) immersive_mode_controller_.reset(); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_->tab_strip_model()->RemoveObserver(this); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop hung plugin monitoring. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticker_.Stop(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticker_.UnregisterTickHandler(&hung_window_detector_); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Terminate the jumplist (must be called before browser_->profile() is 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // destroyed. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (jumplist_) { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jumplist_->Terminate(); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We destroy the download shelf before |browser_| to remove its child 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // download views from the set of download observers (since the observed 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // downloads can be destroyed along with |browser_| and the observer 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications will call back into deleted objects). 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserViewLayout* browser_view_layout = GetBrowserViewLayout(); 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (browser_view_layout) 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_view_layout->set_download_shelf(NULL); 43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) download_shelf_.reset(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The TabStrip attaches a listener to the model. Make sure we shut down the 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TabStrip first so that it can cleanly remove the listener. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tabstrip_) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabstrip_->parent()->RemoveChildView(tabstrip_); 44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (browser_view_layout) 44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view_layout->set_tab_strip(NULL); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete tabstrip_; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tabstrip_ = NULL; 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Child views maintain PrefMember attributes that point to 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OffTheRecordProfile's PrefService which gets deleted by ~Browser. 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveAllChildViews(true); 45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) toolbar_ = NULL; 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Explicitly set browser_ to NULL. 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_.reset(); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserView::Init(Browser* browser) { 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_.reset(browser); 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_->tab_strip_model()->AddObserver(this); 460a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch immersive_mode_controller_.reset( 461a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch chrome::CreateImmersiveModeController(browser_->host_desktop_type())); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserView* BrowserView::GetBrowserViewForNativeWindow( 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow window) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return widget ? 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<BrowserView*>(widget->GetNativeWindowProperty( 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kBrowserViewKey)) : NULL; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserView* BrowserView::GetBrowserViewForBrowser(const Browser* browser) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<BrowserView*>(browser->window()); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 478eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid BrowserView::InitStatusBubble() { 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) status_bubble_.reset(new StatusBubbleViews(contents_web_view_)); 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) contents_web_view_->SetStatusBubble(status_bubble_.get()); 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BrowserView::InitPermissionBubbleView() { 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) permission_bubble_view_.reset(new PermissionBubbleViewViews( 485cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetLocationBarView()->location_icon_view())); 486eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 487eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect BrowserView::GetToolbarBounds() const { 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect toolbar_bounds(toolbar_->bounds()); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (toolbar_bounds.IsEmpty()) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return toolbar_bounds; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The apparent toolbar edges are outside the "real" toolbar edges. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) toolbar_bounds.Inset(-views::NonClientFrameView::kClientEdgeThickness, 0); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return toolbar_bounds; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect BrowserView::GetFindBarBoundingBox() const { 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetBrowserViewLayout()->GetFindBarBoundingBox(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int BrowserView::GetTabStripHeight() const { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want to return tabstrip_->height(), but we might be called in the midst 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of layout, when that hasn't yet been updated to reflect the current state. 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // So return what the tabstrip height _ought_ to be right now. 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsTabStripVisible() ? tabstrip_->GetPreferredSize().height() : 0; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Point BrowserView::OffsetPointForToolbarBackgroundImage( 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Point& point) const { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The background image starts tiling horizontally at the window left edge and 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // vertically at the top edge of the horizontal tab strip (or where it would 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be). We expect our parent's origin to be the window origin. 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Point window_point(point + GetMirroredPosition().OffsetFromOrigin()); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_point.Offset(frame_->GetThemeBackgroundXInset(), 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) -frame_->GetTopInset()); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return window_point; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsTabStripVisible() const { 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (immersive_mode_controller_->ShouldHideTopViews() && 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) immersive_mode_controller_->ShouldHideTabIndicators()) 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsOffTheRecord() const { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return browser_->profile()->IsOffTheRecord(); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool BrowserView::IsGuestSession() const { 5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return browser_->profile()->IsGuestSession(); 5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool BrowserView::IsRegularOrGuestSession() const { 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return profiles::IsRegularOrGuestSession(browser_.get()); 5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::ShouldShowAvatar() const { 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_CHROMEOS) 54023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!browser_->is_type_tabbed() && !browser_->is_app()) 54123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 54223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Don't show incognito avatar in the guest session. 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsOffTheRecord() && !IsGuestSession()) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 545a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This function is called via BrowserNonClientFrameView::UpdateAvatarInfo 546a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // during the creation of the BrowserWindow, so browser->window() will not 547a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // yet be set. In this case we can safely return false. 548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!browser_->window()) 549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 550a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return chrome::MultiUserWindowManager::ShouldShowAvatar( 551a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) browser_->window()->GetNativeWindow()); 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else 55323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!IsBrowserTypeNormal()) 55423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsOffTheRecord()) // Desktop guest is incognito and needs avatar. 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return true; 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tests may not have a profile manager. 558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!g_browser_process->profile_manager()) 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileInfoCache& cache = 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->profile_manager()->GetProfileInfoCache(); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cache.GetIndexOfProfileWithPath(browser_->profile()->GetPath()) == 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string::npos) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return AvatarMenu::ShouldShowAvatarMenu(); 568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool BrowserView::GetAccelerator(int cmd_id, 572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::Accelerator* accelerator) const { 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We retrieve the accelerator information for standard accelerators 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // for cut, copy and paste. 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (chrome::GetStandardAcceleratorForCommandId(cmd_id, accelerator)) 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Else, we retrieve the accelerator information from the accelerator table. 5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::map<ui::Accelerator, int>::const_iterator it = 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accelerator_table_.begin(); it != accelerator_table_.end(); ++it) { 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->second == cmd_id) { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *accelerator = it->first; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Else, we retrieve the accelerator information from Ash (if applicable). 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return chrome::GetAshAcceleratorForCommandId( 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cmd_id, browser_->host_desktop_type(), accelerator); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool BrowserView::IsAcceleratorRegistered(const ui::Accelerator& accelerator) { 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return accelerator_table_.find(accelerator) != accelerator_table_.end(); 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebContents* BrowserView::GetActiveWebContents() const { 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return browser_->tab_strip_model()->GetActiveWebContents(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::ImageSkia BrowserView::GetOTRAvatarIcon() const { 5995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return *GetThemeProvider()->GetImageSkiaNamed(IDR_OTR_ICON); 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/////////////////////////////////////////////////////////////////////////////// 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BrowserView, BrowserWindow implementation: 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Show() { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the window is already visible, just activate it. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frame_->IsVisible()) { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Activate(); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Showing the window doesn't make the browser window active right away. 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can cause SetFocusToLocationBar() to skip setting focus to the 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // location bar. To avoid this we explicilty let SetFocusToLocationBar() 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // know that it's ok to steal focus. 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_location_bar_focus_ = true; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setting the focus doesn't work when the window is invisible, so any focus 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // initialization that happened before this will be lost. 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We really "should" restore the focus whenever the window becomes unhidden, 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // but I think initializing is the only time where this can happen where 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // there is some focus change we need to pick up, and this is easier than 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // plumbing through an un-hide message all the way from the frame. 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we do find there are cases where we need to restore the focus on show, 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that should be added and this should be removed. 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestoreFocus(); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Show(); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_location_bar_focus_ = false; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser()->OnWindowDidShow(); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 636a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chrome::MaybeShowInvertBubbleView(this); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::ShowInactive() { 640a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!frame_->IsVisible()) 641a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) frame_->ShowInactive(); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Hide() { 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Not implemented. 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::SetBounds(const gfx::Rect& bounds) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExitFullscreen(); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWidget()->SetBounds(bounds); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Close() { 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Close(); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Activate() { 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Activate(); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Deactivate() { 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Deactivate(); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsActive() const { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_->IsActive(); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::FlashFrame(bool flash) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->FlashFrame(flash); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsAlwaysOnTop() const { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void BrowserView::SetAlwaysOnTop(bool always_on_top) { 6784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Not implemented for browser windows. 6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTIMPLEMENTED(); 6804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeWindow BrowserView::GetNativeWindow() { 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // While the browser destruction is going on, the widget can already be gone, 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // but utility functions like FindBrowserWithWindow will come here and crash. 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We short circuit therefore. 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetWidget()) 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetWidget()->GetTopLevelWidget()->GetNativeWindow(); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserWindowTesting* BrowserView::GetBrowserWindowTesting() { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return this; 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)StatusBubble* BrowserView::GetStatusBubble() { 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return status_bubble_.get(); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only used by ToolbarSizeChanged() below, but placed here because template 7012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // arguments (to base::AutoReset<>) must have external linkage. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum CallState { NORMAL, REENTRANT, REENTRANT_FORCE_FAST_RESIZE }; 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::UpdateTitleBar() { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->UpdateWindowTitle(); 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ShouldShowWindowIcon() && !loading_animation_timer_.IsRunning()) 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->UpdateWindowIcon(); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::BookmarkBarStateChanged( 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkBar::AnimateChangeType change_type) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bookmark_bar_view_.get()) { 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BookmarkBar::State new_state = browser_->bookmark_bar_state(); 715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We don't properly support animating the bookmark bar to and from the 717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // detached state in immersive fullscreen. 718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool detached_changed = (new_state == BookmarkBar::DETACHED) || 719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bookmark_bar_view_->IsDetached(); 720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (detached_changed && immersive_mode_controller_->IsEnabled()) 721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) change_type = BookmarkBar::DONT_ANIMATE_STATE_CHANGE; 722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bookmark_bar_view_->SetBookmarkBarState(new_state, change_type); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (MaybeShowBookmarkBar(GetActiveWebContents())) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::UpdateDevTools() { 7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateDevToolsForContents(GetActiveWebContents(), true); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Layout(); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::UpdateLoadingAnimations(bool should_animate) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_animate) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!loading_animation_timer_.IsRunning()) { 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads are happening, and the timer isn't running, so start it. 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_animation_time_ = base::TimeTicks::Now(); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_animation_timer_.Start(FROM_HERE, 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &BrowserView::LoadingAnimationCallback); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (loading_animation_timer_.IsRunning()) { 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_animation_time_ = base::TimeTicks(); 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loading_animation_timer_.Stop(); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads are now complete, update the state if a task was scheduled. 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadingAnimationCallback(); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::SetStarredState(bool is_starred) { 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLocationBarView()->SetStarToggled(is_starred); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BrowserView::SetTranslateIconToggled(bool is_lit) { 758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetLocationBarView()->SetTranslateIconToggled(is_lit); 759f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 760f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void BrowserView::OnActiveTabChanged(content::WebContents* old_contents, 76268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::WebContents* new_contents, 76368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int index, 76468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int reason) { 76568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(new_contents); 76668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 76768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If |contents_container_| already has the correct WebContents, we can save 76868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // some work. This also prevents extra events from being reported by the 76968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Visibility API under Windows, as ChangeWebContents will briefly hide 77068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the WebContents window. 77168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool change_tab_contents = 77268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) contents_web_view_->web_contents() != new_contents; 77368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 77468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Update various elements that are interested in knowing the current 77568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // WebContents. 77668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 77768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // When we toggle the NTP floating bookmarks bar and/or the info bar, 77868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // we don't want any WebContents to be attached, so that we 77968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // avoid an unnecessary resize and re-layout of a WebContents. 7805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (change_tab_contents) { 78168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) contents_web_view_->SetWebContents(NULL); 7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) devtools_web_view_->SetWebContents(NULL); 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 784e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 7851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Do this before updating InfoBarContainer as the InfoBarContainer may 7861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // callback to us and trigger layout. 7871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (bookmark_bar_view_.get()) { 7881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bookmark_bar_view_->SetBookmarkBarState( 7891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci browser_->bookmark_bar_state(), 7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BookmarkBar::DONT_ANIMATE_STATE_CHANGE); 7911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 7921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 793a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch infobar_container_->ChangeInfoBarManager( 794a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch InfoBarService::FromWebContents(new_contents)); 7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (old_contents && PermissionBubbleManager::FromWebContents(old_contents)) 7975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PermissionBubbleManager::FromWebContents(old_contents)->SetView(NULL); 7985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (new_contents && PermissionBubbleManager::FromWebContents(new_contents)) { 8005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PermissionBubbleManager::FromWebContents(new_contents)->SetView( 8015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) permission_bubble_view_.get()); 8025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 80468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateUIForContents(new_contents); 80568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Layout for DevTools _before_ setting the both main and devtools WebContents 8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to avoid toggling the size of any of them. 8085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateDevToolsForContents(new_contents, !change_tab_contents); 80968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (change_tab_contents) { 811a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch web_contents_close_handler_->ActiveTabChanged(); 81268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) contents_web_view_->SetWebContents(new_contents); 8135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The second layout update should be no-op. It will just set the 8145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // DevTools WebContents. 8155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateDevToolsForContents(new_contents, true); 8165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 81768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 81868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!browser_->tab_strip_model()->closing_all() && GetWidget()->IsActive() && 81968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetWidget()->IsVisible()) { 82068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We only restore focus if our window is visible, to avoid invoking blur 82168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // handlers when we are eventually shown. 822010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_contents->RestoreFocus(); 82368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 82468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 82568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Update all the UI bits. 82668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateTitleBar(); 82768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 82868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::ZoomChangedForActiveTab(bool can_show_bubble) { 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLocationBarView()->ZoomChangedForActiveTab( 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) can_show_bubble && !toolbar_->IsWrenchMenuShowing()); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect BrowserView::GetRestoredBounds() const { 835010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect bounds; 836010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::WindowShowState state; 837010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_->GetWindowPlacement(&bounds, &state); 838010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return bounds; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 841b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)ui::WindowShowState BrowserView::GetRestoredState() const { 842010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) gfx::Rect bounds; 843010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ui::WindowShowState state; 844010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_->GetWindowPlacement(&bounds, &state); 845010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return state; 846b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 847b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect BrowserView::GetBounds() const { 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_->GetWindowBoundsInScreen(); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsMaximized() const { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_->IsMaximized(); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsMinimized() const { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_->IsMinimized(); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Maximize() { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Maximize(); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Minimize() { 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Minimize(); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::Restore() { 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_->Restore(); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::EnterFullscreen( 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, FullscreenExitBubbleType bubble_type) { 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsFullscreen()) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Nothing to do. 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 877a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ProcessFullscreen(true, NORMAL_FULLSCREEN, url, bubble_type); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::ExitFullscreen() { 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsFullscreen()) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Nothing to do. 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 884a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ProcessFullscreen(false, NORMAL_FULLSCREEN, GURL(), FEB_TYPE_NONE); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::UpdateFullscreenExitBubbleContent( 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& url, 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FullscreenExitBubbleType bubble_type) { 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Immersive mode has no exit bubble because it has a visible strip at the 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // top that gives the user a hover target. 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(jamescook): Figure out what to do with mouse-lock. 893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (bubble_type == FEB_TYPE_NONE || ShouldUseImmersiveFullscreenForUrl(url)) { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fullscreen_bubble_.reset(); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (fullscreen_bubble_.get()) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fullscreen_bubble_->UpdateContent(url, bubble_type); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fullscreen_bubble_.reset(new FullscreenExitBubbleViews( 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) this, url, bubble_type)); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BrowserView::ShouldHideUIForFullscreen() const { 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Immersive mode needs UI for the slide-down top panel. 90523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (immersive_mode_controller_->IsEnabled()) 90623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return false; 907f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IsFullscreen(); 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsFullscreen() const { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return frame_->IsFullscreen(); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsFullscreenBubbleVisible() const { 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return fullscreen_bubble_ != NULL; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::SetMetroSnapMode(bool enable) { 9211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOCAL_HISTOGRAM_COUNTS("Metro.SnapModeToggle", enable); 922a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ProcessFullscreen(enable, METRO_SNAP_FULLSCREEN, GURL(), FEB_TYPE_NONE); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BrowserView::IsInMetroSnapMode() const { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_WIN) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::RestoreFocus() { 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* selected_web_contents = GetActiveWebContents(); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (selected_web_contents) 933010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) selected_web_contents->RestoreFocus(); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 936f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void BrowserView::FullscreenStateChanged() { 937f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CHECK(!IsFullscreen()); 938a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ProcessFullscreen(false, NORMAL_FULLSCREEN, GURL(), FEB_TYPE_NONE); 939f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 940f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BrowserView::ToolbarSizeChanged(bool is_animating) { 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The call to InfoBarContainer::SetMaxTopArrowHeight() below can result in 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reentrancy; |call_state| tracks whether we're reentrant. We can't just 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // early-return in this case because we need to layout again so the infobar 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // container's bounds are set correctly. 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static CallState call_state = NORMAL; 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A reentrant call can (and should) use the fast resize path unless both it 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the normal call are both non-animating. 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool use_fast_resize = 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_animating || (call_state == REENTRANT_FORCE_FAST_RESIZE); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_fast_resize) 953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) contents_web_view_->SetFastResize(true); 9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateUIForContents(GetActiveWebContents()); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (use_fast_resize) 956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) contents_web_view_->SetFastResize(false); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Inform the InfoBarContainer that the distance to the location icon may have 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changed. We have to do this after the block above so that the toolbars are 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // laid out correctly for calculating the maximum arrow height below. 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoReset<CallState> resetter(&call_state, 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_animating ? REENTRANT_FORCE_FAST_RESIZE : REENTRANT); 964a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) infobar_container_->SetMaxTopArrowHeight(GetMaxTopInfoBarArrowHeight()); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When transitioning from animating to not animating we need to make sure the 9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // contents_container_ gets layed out. If we don't do this and the bounds 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // haven't changed contents_container_ won't get a Layout out and we'll end up 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with a gray rect because the clip wasn't updated. Note that a reentrant 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call never needs to do this, because after it returns, the normal call 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wrapping it will do it. 973