browser_view.cc revision 0f1bc08d4cfcc34181b0b5cbf065c40f687bf740
1e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// Copyright 2012 The Chromium Authors. All rights reserved. 2e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// Use of this source code is governed by a BSD-style license that can be 3e9629bad30a9f478b336ab46b8e6e02f7f87af46Evan Chu// found in the LICENSE file. 4e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 5e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/frame/browser_view.h" 6e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 7e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <algorithm> 8e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 9e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/auto_reset.h" 10e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/command_line.h" 11e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/i18n/rtl.h" 12e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/memory/scoped_ptr.h" 13e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/metrics/histogram.h" 14e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/prefs/pref_service.h" 15e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "base/strings/string_number_conversions.h" 16e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/app/chrome_command_ids.h" 17e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/app/chrome_dll_resource.h" 18e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/app_mode/app_mode_utils.h" 195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/bookmarks/bookmark_stats.h" 20e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/browser_process.h" 21e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/chrome_notification_types.h" 22e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/extensions/tab_helper.h" 23e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/infobars/infobar_service.h" 24e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/native_window_notification_source.h" 25e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/password_manager/password_manager.h" 26e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/profiles/avatar_menu.h" 27e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/profiles/profile.h" 28e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/profiles/profile_info_cache.h" 29e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/profiles/profile_manager.h" 30e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/search/search.h" 31e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/sessions/tab_restore_service.h" 32e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/sessions/tab_restore_service_factory.h" 33e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/speech/tts_controller.h" 34e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/themes/theme_properties.h" 35e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/themes/theme_service_factory.h" 36e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/translate/translate_tab_helper.h" 37e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" 38e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" 39e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/bookmarks/bookmark_bar_constants.h" 40e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/bookmarks/bookmark_bubble_delegate.h" 41e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h" 42e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser.h" 43e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser_command_controller.h" 44e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser_commands.h" 45e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser_dialogs.h" 46e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser_finder.h" 47e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser_list.h" 48e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/browser_window_state.h" 49e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/ntp_background_util.h" 50e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/omnibox/omnibox_popup_model.h" 51e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/omnibox/omnibox_popup_view.h" 52e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/omnibox/omnibox_view.h" 53e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/search/search_delegate.h" 54e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/search/search_model.h" 55e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/search/search_ui.h" 56e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/tabs/tab_menu_model.h" 57e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/tabs/tab_strip_model.h" 58e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/view_ids.h" 59e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/accelerator_table.h" 60e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/accessibility/invert_bubble_view.h" 61e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/avatar_menu_bubble_view.h" 62e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/avatar_menu_button.h" 63e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 64e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h" 65e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/browser_dialogs.h" 66e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/download/download_in_progress_dialog_view.h" 67e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/download/download_shelf_view.h" 68e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/frame/browser_view_layout.h" 69e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/frame/browser_view_layout_delegate.h" 70e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/frame/contents_container.h" 71e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/frame/immersive_mode_controller.h" 72e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/frame/top_container_view.h" 73e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/fullscreen_exit_bubble_views.h" 74e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/infobars/infobar_container_view.h" 75e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/location_bar/location_bar_view.h" 76e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/location_bar/location_icon_view.h" 77e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" 78e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/omnibox/omnibox_views.h" 79e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/password_generation_bubble_view.h" 80e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/status_bubble_views.h" 81e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/tabs/browser_tab_strip_controller.h" 82e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/tabs/tab.h" 83e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/tabs/tab_strip.h" 84e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/toolbar_view.h" 85e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/translate/translate_bubble_view.h" 86e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/update_recommended_message_box.h" 87e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/website_settings/website_settings_popup_view.h" 88e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/window_sizer/window_sizer.h" 895c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/common/chrome_switches.h" 90e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/common/pref_names.h" 915c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/common/url_constants.h" 925c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "content/public/browser/download_manager.h" 93e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "content/public/browser/native_web_keyboard_event.h" 945c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "content/public/browser/notification_service.h" 95e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "content/public/browser/render_view_host.h" 965c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "content/public/browser/render_widget_host.h" 97e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "content/public/browser/user_metrics.h" 985c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "content/public/browser/web_contents.h" 99d05817f02d578becbf79b46f2599126404c7b413Evan Chu#include "content/public/browser/web_contents_view.h" 100d05817f02d578becbf79b46f2599126404c7b413Evan Chu#include "content/public/common/content_switches.h" 101d05817f02d578becbf79b46f2599126404c7b413Evan Chu#include "grit/chromium_strings.h" 102a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu#include "grit/generated_resources.h" 103a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu#include "grit/locale_settings.h" 104a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu#include "grit/theme_resources.h" 105a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu#include "grit/ui_resources.h" 106a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu#include "grit/ui_strings.h" 107a24be4f06674b2707b57904deaa0dff5a95823bdEvan Chu#include "grit/webkit_resources.h" 108d05817f02d578becbf79b46f2599126404c7b413Evan Chu#include "ui/base/accelerators/accelerator.h" 1095c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/base/accessibility/accessible_view_state.h" 1105c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/base/hit_test.h" 1115c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/base/l10n/l10n_util.h" 11245e68232b8524aca5165dca28b994ec8c11593b1Evan Chu#include "ui/base/resource/resource_bundle.h" 11345e68232b8524aca5165dca28b994ec8c11593b1Evan Chu#include "ui/base/theme_provider.h" 1145c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/events/event_utils.h" 1155c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/gfx/canvas.h" 1165c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/gfx/color_utils.h" 1175c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/gfx/sys_color_change_listener.h" 1185c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/controls/button/menu_button.h" 1195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/controls/single_split_view.h" 1205c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/controls/textfield/textfield.h" 121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "ui/views/controls/webview/webview.h" 1225c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/focus/external_focus_tracker.h" 1235c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/focus/view_storage.h" 1245c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/layout/grid_layout.h" 1255c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/widget/native_widget.h" 1265c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/widget/root_view.h" 1275c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/widget/widget.h" 1285c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/window/dialog_delegate.h" 1295c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1305c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#if defined(USE_ASH) 1315c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ash/launcher/launcher.h" 1325c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ash/launcher/launcher_model.h" 1335c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ash/shell.h" 1345c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/ui/ash/ash_util.h" 1355c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#endif 1365c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1375c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#if defined(USE_AURA) 1385c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/aura/window.h" 1395c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/gfx/screen.h" 1405c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#elif defined(OS_WIN) // !defined(USE_AURA) 1415c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/jumplist_win.h" 142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "chrome/browser/ui/views/omnibox/omnibox_view_win.h" 1435c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/widget/native_widget_win.h" 1445c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "ui/views/win/scoped_fullscreen_visibility.h" 1455c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#endif 1465c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1475c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#if defined(OS_WIN) 1485c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "base/win/windows_version.h" 1495c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "win8/util/win8_util.h" 1505c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#endif 1515c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1525c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#if defined(ENABLE_ONE_CLICK_SIGNIN) 1535c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/ui/sync/one_click_signin_bubble_delegate.h" 1545c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/ui/sync/one_click_signin_bubble_links_delegate.h" 1555c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/ui/views/sync/one_click_signin_bubble_view.h" 1565c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#endif 1575c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1585c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#if defined(OS_CHROMEOS) 1595c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#include "chrome/browser/ui/ash/multi_user_window_manager.h" 1605c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#endif 1615c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1625c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing base::TimeDelta; 1635c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing content::NativeWebKeyboardEvent; 1645c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing content::SSLStatus; 1655c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing content::UserMetricsAction; 1665c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing content::WebContents; 1675c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing views::ColumnSet; 1685c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing views::GridLayout; 1695c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenusing web_modal::WebContentsModalDialogHost; 1705c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1715c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenennamespace { 1725c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen// The name of a key to store on the window handle so that other code can 1735c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen// locate this object using just the handle. 1745c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenconst char* const kBrowserViewKey = "__BROWSER_VIEW__"; 1755c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1765c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen// The number of milliseconds between loading animation frames. 1775c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenconst int kLoadingAnimationFrameTimeMs = 30; 1785c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 1795c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen// TODO(kuan): These functions are temporarily for the bookmark bar while its 180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// detached state is at the top of the page; it'll be moved to float on the 181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// content page in the very near future, at which time, these local functions 182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// will be removed. 183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid PaintDetachedBookmarkBar(gfx::Canvas* canvas, 184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView* view, 185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ThemeService* theme_service) { 186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Paint background for detached state; if animating, this is fade in/out. 187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->DrawColor( 188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::GetDetachedBookmarkBarBackgroundColor(theme_service)); 189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Draw the separators above and below bookmark bar; 190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // if animating, these are fading in/out. 191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project SkColor separator_color = 192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::GetDetachedBookmarkBarSeparatorColor(theme_service); 193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView::PaintHorizontalBorder(canvas, view, true, 194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project separator_color); 195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // The bottom border needs to be 1-px thick in both regular and retina 196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // displays, so we can't use DetachableToolbarView::PaintHorizontalBorder 197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // which paints a 2-px thick border in retina display. 198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project SkPaint paint; 199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project paint.setAntiAlias(false); 200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Sets border to 1-px thick regardless of scale factor. 201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project paint.setStrokeWidth(0); 202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Bottom border is at 50% opacity of top border. 203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project paint.setColor(SkColorSetA(separator_color, 204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project SkColorGetA(separator_color) / 2)); 205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Calculate thickness of bottom border as per current scale factor to 206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // determine where to draw the 1-px thick border. 207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project float thickness = views::NonClientFrameView::kClientEdgeThickness / 208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->image_scale(); 209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project SkScalar y = SkIntToScalar(view->height()) - SkFloatToScalar(thickness); 210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->sk_canvas()->drawLine(SkIntToScalar(0), y, 211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project SkIntToScalar(view->width()), y, paint); 212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid PaintAttachedBookmarkBar(gfx::Canvas* canvas, 215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView* view, 216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BrowserView* browser_view, 217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::HostDesktopType host_desktop_type, 218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int toolbar_overlap) { 219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Paint background for attached state, this is fade in/out. 220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gfx::Point background_image_offset = 221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_view->OffsetPointForToolbarBackgroundImage( 222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gfx::Point(view->GetMirroredX(), view->y())); 223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView::PaintBackgroundAttachedMode(canvas, 224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project view->GetThemeProvider(), view->GetLocalBounds(), 225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project background_image_offset, host_desktop_type); 226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (view->height() >= toolbar_overlap) { 227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Draw the separator below bookmark bar; this is fading in/out. 228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView::PaintHorizontalBorder(canvas, view, false, 229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ThemeProperties::GetDefaultColor( 230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ThemeProperties::COLOR_TOOLBAR_SEPARATOR)); 231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} // namespace 235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// static 237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectconst char BrowserView::kViewClassName[] = "BrowserView"; 238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectnamespace { 240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool ShouldSaveOrRestoreWindowPos() { 242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_WIN) 243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // In Windows 8's single window Metro mode the window is always maximized 244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // (without the WS_MAXIMIZE style). 245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (win8::IsSingleWindowMetroMode()) 246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} // namespace 252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// Delegate implementation for BrowserViewLayout. Usually just forwards calls 256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// into BrowserView. 257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectclass BrowserViewLayoutDelegateImpl : public BrowserViewLayoutDelegate { 258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project public: 259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project explicit BrowserViewLayoutDelegateImpl(BrowserView* browser_view) 260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : browser_view_(browser_view) {} 261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual ~BrowserViewLayoutDelegateImpl() {} 262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // BrowserViewLayoutDelegate overrides: 264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual views::View* GetWindowSwitcherButton() const OVERRIDE { 265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_view_->window_switcher_button(); 266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual bool DownloadShelfNeedsLayout() const OVERRIDE { 269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DownloadShelfView* download_shelf = browser_view_->download_shelf_.get(); 270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Re-layout the shelf either if it is visible or if its close animation 271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // is currently running. 272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return download_shelf && 273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project (download_shelf->IsShowing() || download_shelf->IsClosing()); 274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual bool IsTabStripVisible() const OVERRIDE { 277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_view_->IsTabStripVisible(); 278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual gfx::Rect GetBoundsForTabStrip( 281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project views::View* tab_strip) const OVERRIDE { 282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_view_->frame()->GetBoundsForTabStrip(tab_strip); 283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual bool IsToolbarVisible() const OVERRIDE { 286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_view_->IsToolbarVisible(); 287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual bool IsBookmarkBarVisible() const OVERRIDE { 290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_view_->IsBookmarkBarVisible(); 291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual FullscreenExitBubbleViews* GetFullscreenExitBubble() const OVERRIDE { 294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_view_->fullscreen_exit_bubble(); 295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project private: 298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BrowserView* browser_view_; 299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DISALLOW_COPY_AND_ASSIGN(BrowserViewLayoutDelegateImpl); 301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// BookmarkExtensionBackground, private: 305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// This object serves as the views::Background object which is used to layout 306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// and paint the bookmark bar. 307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectclass BookmarkExtensionBackground : public views::Background { 308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project public: 309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BookmarkExtensionBackground(BrowserView* browser_view, 310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView* host_view, 311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Browser* browser); 312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // View methods overridden from views:Background. 314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE; 315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project private: 317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BrowserView* browser_view_; 318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // The view hosting this background. 320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView* host_view_; 321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Browser* browser_; 323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DISALLOW_COPY_AND_ASSIGN(BookmarkExtensionBackground); 325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectBookmarkExtensionBackground::BookmarkExtensionBackground( 328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BrowserView* browser_view, 329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DetachableToolbarView* host_view, 330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Browser* browser) 331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : browser_view_(browser_view), 332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project host_view_(host_view), 333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_(browser) { 334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BookmarkExtensionBackground::Paint(gfx::Canvas* canvas, 337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project views::View* view) const { 338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int toolbar_overlap = host_view_->GetToolbarOverlap(); 339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!host_view_->IsDetached()) { 340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PaintAttachedBookmarkBar(canvas, host_view_, browser_view_, 341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_->host_desktop_type(), toolbar_overlap); 342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; 343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // As 'hidden' according to the animation is the full in-tab state, we invert 346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // the value - when current_state is at '0', we expect the bar to be docked. 347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project double current_state = 1 - host_view_->GetAnimationValue(); 348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ThemeService* ts = 350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ThemeServiceFactory::GetForProfile(browser_->profile()); 351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (current_state == 0.0 || current_state == 1.0) { 352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PaintDetachedBookmarkBar(canvas, host_view_, ts); 353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; 354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // While animating, set opacity to cross-fade between attached and detached 356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // backgrounds including their respective separators. 357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int detached_alpha = static_cast<uint8>(current_state * 255); 358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int attached_alpha = 255 - detached_alpha; 359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (browser_->bookmark_bar_state() == BookmarkBar::DETACHED) { 360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // To animate from attached to detached state: 361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // - fade out attached background 362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // - fade in detached background. 363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->SaveLayerAlpha(attached_alpha); 364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PaintAttachedBookmarkBar(canvas, host_view_, browser_view_, 365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_->host_desktop_type(), 366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_overlap); 367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->Restore(); 368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->SaveLayerAlpha(detached_alpha); 369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PaintDetachedBookmarkBar(canvas, host_view_, ts); 370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } else { 371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // To animate from detached to attached state: 372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // - fade out detached background 373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // - fade in attached background. 374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->SaveLayerAlpha(detached_alpha); 375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PaintDetachedBookmarkBar(canvas, host_view_, ts); 376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->Restore(); 377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->SaveLayerAlpha(attached_alpha); 378e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project PaintAttachedBookmarkBar(canvas, host_view_, browser_view_, 379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_->host_desktop_type(), 380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_overlap); 381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project canvas->Restore(); 383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// BrowserView, public: 387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectBrowserView::BrowserView() 389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project : views::ClientView(NULL, NULL), 390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project last_focused_view_storage_id_( 391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project views::ViewStorage::GetInstance()->CreateStorageID()), 392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_(NULL), 393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project top_container_(NULL), 394e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tabstrip_(NULL), 395e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_(NULL), 396e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project window_switcher_button_(NULL), 397e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project find_bar_host_view_(NULL), 398e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project infobar_container_(NULL), 399e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_(NULL), 400e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project devtools_container_(NULL), 401e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_container_(NULL), 402e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_split_(NULL), 403e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project devtools_dock_side_(DEVTOOLS_DOCK_SIDE_BOTTOM), 404e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project devtools_window_(NULL), 405e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project initialized_(false), 406e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project in_process_fullscreen_(false), 407e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_WIN) && !defined(USE_AURA) 408e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project hung_window_detector_(&hung_plugin_action_), 409e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ticker_(0), 410e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 411e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project force_location_bar_focus_(false), 412e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project immersive_mode_controller_(chrome::CreateImmersiveModeController()), 413e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_CHROMEOS) 414e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project scroll_end_effect_controller_(ScrollEndEffectController::Create()), 415e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 416e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project color_change_listener_(this), 417e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project activate_modal_dialog_factory_(this) { 418e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 419e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 420e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectBrowserView::~BrowserView() { 421e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Immersive mode may need to reparent views before they are removed/deleted. 422e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project immersive_mode_controller_.reset(); 423e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 424e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_->tab_strip_model()->RemoveObserver(this); 425e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 426e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_WIN) && !defined(USE_AURA) 427e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Stop hung plugin monitoring. 428e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ticker_.Stop(); 429e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ticker_.UnregisterTickHandler(&hung_window_detector_); 430e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 4315c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // Terminate the jumplist (must be called before browser_->profile() is 4325c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // destroyed. 4335c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (jumplist_) { 4345c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen jumplist_->Terminate(); 4355c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen } 4365c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen#endif 4375c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 4385c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // We destroy the download shelf before |browser_| to remove its child 4395c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // download views from the set of download observers (since the observed 4405c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // downloads can be destroyed along with |browser_| and the observer 441e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // notifications will call back into deleted objects). 442e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BrowserViewLayout* browser_view_layout = GetBrowserViewLayout(); 443e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (browser_view_layout) 444e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_view_layout->set_download_shelf(NULL); 445e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project download_shelf_.reset(); 446e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 447e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // The TabStrip attaches a listener to the model. Make sure we shut down the 448e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // TabStrip first so that it can cleanly remove the listener. 449e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (tabstrip_) { 450e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tabstrip_->parent()->RemoveChildView(tabstrip_); 451e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (browser_view_layout) 452e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_view_layout->set_tab_strip(NULL); 453e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project delete tabstrip_; 454e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tabstrip_ = NULL; 455e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 456e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Child views maintain PrefMember attributes that point to 457e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // OffTheRecordProfile's PrefService which gets deleted by ~Browser. 458e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project RemoveAllChildViews(true); 459e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_ = NULL; 460e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 461e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // It is possible that we were forced-closed by the native view system and 462e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // that tabs remain in the browser. Close any such remaining tabs. Detach 463e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // before destroying in hopes of avoiding less callbacks trying to access 464e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // members since destroyed. 465e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 466e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ScopedVector<content::WebContents> contents; 467e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project while (browser_->tab_strip_model()->count()) 468e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents.push_back(browser_->tab_strip_model()->DetachWebContentsAt(0)); 469e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 470e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 471e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Explicitly set browser_ to NULL. 472e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_.reset(); 4735c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 4745c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 4755c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenvoid BrowserView::Init(Browser* browser) { 476df5080d7feca9827fd0306471c54f52ecf185c22Evan Chu browser_.reset(browser); 477df5080d7feca9827fd0306471c54f52ecf185c22Evan Chu browser_->tab_strip_model()->AddObserver(this); 4785c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 4795c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 4805c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen// static 4815c65c3a0f42e174e47fecd4e569606003217ff4eMartijn CoenenBrowserView* BrowserView::GetBrowserViewForNativeWindow( 4825c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen gfx::NativeWindow window) { 4835c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); 4845c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return widget ? 4855c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen reinterpret_cast<BrowserView*>(widget->GetNativeWindowProperty( 4865c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen kBrowserViewKey)) : NULL; 4875c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 4885c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 48945e68232b8524aca5165dca28b994ec8c11593b1Evan Chu// static 49045e68232b8524aca5165dca28b994ec8c11593b1Evan ChuBrowserView* BrowserView::GetBrowserViewForBrowser(const Browser* browser) { 4915c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return static_cast<BrowserView*>(browser->window()); 4925c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 493e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 494e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::InitStatusBubble() { 4955c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen status_bubble_.reset(new StatusBubbleViews(contents_container_)); 4965c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 497e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 4985c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenengfx::Rect BrowserView::GetToolbarBounds() const { 499e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gfx::Rect toolbar_bounds(toolbar_->bounds()); 500e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (toolbar_bounds.IsEmpty()) 501e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return toolbar_bounds; 502e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // The apparent toolbar edges are outside the "real" toolbar edges. 503e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_bounds.Inset(-views::NonClientFrameView::kClientEdgeThickness, 0); 504e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return toolbar_bounds; 505e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 506e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 507e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::Rect BrowserView::GetClientAreaBounds() const { 508e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gfx::Rect container_bounds = contents_container_->bounds(); 509e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gfx::Point container_origin = container_bounds.origin(); 510e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ConvertPointToTarget(this, parent(), &container_origin); 511e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project container_bounds.set_origin(container_origin); 512e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return container_bounds; 513e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 514e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 515e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::Rect BrowserView::GetFindBarBoundingBox() const { 516e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return GetBrowserViewLayout()->GetFindBarBoundingBox(); 517e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 5185c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 5195c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenint BrowserView::GetTabStripHeight() const { 520e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We want to return tabstrip_->height(), but we might be called in the midst 521e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // of layout, when that hasn't yet been updated to reflect the current state. 522e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // So return what the tabstrip height _ought_ to be right now. 523e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return IsTabStripVisible() ? tabstrip_->GetPreferredSize().height() : 0; 524e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 525e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 526e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::Point BrowserView::OffsetPointForToolbarBackgroundImage( 527e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const gfx::Point& point) const { 528e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // The background image starts tiling horizontally at the window left edge and 529e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // vertically at the top edge of the horizontal tab strip (or where it would 530e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // be). We expect our parent's origin to be the window origin. 531e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project gfx::Point window_point(point + GetMirroredPosition().OffsetFromOrigin()); 532e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project window_point.Offset(frame_->GetThemeBackgroundXInset(), 533e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project -frame_->GetTabStripInsets(false).top); 534e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return window_point; 535e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 536e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 537e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsTabStripVisible() const { 538e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (immersive_mode_controller_->ShouldHideTopViews() && 539e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project immersive_mode_controller_->ShouldHideTabIndicators()) 540e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 541e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_->SupportsWindowFeature(Browser::FEATURE_TABSTRIP); 542e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 543e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 544e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsOffTheRecord() const { 545e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_->profile()->IsOffTheRecord(); 546e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 547e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 548e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsGuestSession() const { 549e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_->profile()->IsGuestSession(); 550e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 551e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 552e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsRegularOrGuestSession() const { 553e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Profile* profile = browser_->profile(); 554e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return (profile->IsGuestSession() || !profile->IsOffTheRecord()); 555e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 556e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 557e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint BrowserView::GetOTRIconResourceID() const { 558e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int otr_resource_id = IDR_OTR_ICON; 559e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (ui::GetDisplayLayout() == ui::LAYOUT_TOUCH) { 560e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (IsFullscreen()) 561e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project otr_resource_id = IDR_OTR_ICON_FULLSCREEN; 562e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_WIN) 563e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (win8::IsSingleWindowMetroMode()) 564e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project otr_resource_id = IDR_OTR_ICON_FULLSCREEN; 565e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 566e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 567e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 568e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return otr_resource_id; 569e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 570e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 571e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint BrowserView::GetGuestIconResourceID() const { 572e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return IDR_GUEST_ICON; 573e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 574e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 575e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::ShouldShowAvatar() const { 576e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!IsBrowserTypeNormal()) 577e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 578e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_CHROMEOS) 579e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (IsOffTheRecord() && !IsGuestSession()) 580e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 581e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 582e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Note: In case of the M-31 mode the window manager won't exist. 583e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::MultiUserWindowManager* window_manager = 584e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::MultiUserWindowManager::GetInstance(); 585e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (window_manager) { 586e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // This function is called via BrowserNonClientFrameView::UpdateAvatarInfo 587e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // during the creation of the BrowserWindow, so browser->window() will not 588e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // yet be set. In this case we can safely return false. 589e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!browser_->window()) 590e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 591e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 592e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // If the window is shown on a different desktop than the user, it should 593e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // have the avatar icon. 594e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project aura::Window* window = browser_->window()->GetNativeWindow(); 595e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 596e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Note: When the window manager the window is either on it's owners desktop 597e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // (and shows no icon) or it is now (in which it will show an icon). So we 598e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // can return here. 599e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return !window_manager->IsWindowOnDesktopOfUser( 600e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project window, 601e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project window_manager->GetWindowOwner(window)); 602e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 603e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#else 604e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (IsOffTheRecord()) // Desktop guest is incognito and needs avatar. 605e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 606e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 607e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Tests may not have a profile manager. 608e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!g_browser_process->profile_manager()) 609e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 610e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProfileInfoCache& cache = 611e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project g_browser_process->profile_manager()->GetProfileInfoCache(); 612e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (cache.GetIndexOfProfileWithPath(browser_->profile()->GetPath()) == 613e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project std::string::npos) { 614e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 615e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 616e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 617e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return AvatarMenu::ShouldShowAvatarMenu(); 618e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 619e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 620e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::GetAccelerator(int cmd_id, ui::Accelerator* accelerator) { 621e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We retrieve the accelerator information for standard accelerators 622e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // for cut, copy and paste. 623e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (chrome::GetStandardAcceleratorForCommandId(cmd_id, accelerator)) 624e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 625e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Else, we retrieve the accelerator information from the accelerator table. 626e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project for (std::map<ui::Accelerator, int>::const_iterator it = 627e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project accelerator_table_.begin(); it != accelerator_table_.end(); ++it) { 628e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (it->second == cmd_id) { 629e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *accelerator = it->first; 630e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 631e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 632e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 633e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Else, we retrieve the accelerator information from Ash (if applicable). 634e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return chrome::GetAshAcceleratorForCommandId( 635e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project cmd_id, browser_->host_desktop_type(), accelerator); 636e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 637e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 638e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsAcceleratorRegistered(const ui::Accelerator& accelerator) { 639e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return accelerator_table_.find(accelerator) != accelerator_table_.end(); 640e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 641e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 642e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectWebContents* BrowserView::GetActiveWebContents() const { 643e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_->tab_strip_model()->GetActiveWebContents(); 644e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 645e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 646e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::ImageSkia BrowserView::GetOTRAvatarIcon() const { 647e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return *GetThemeProvider()->GetImageSkiaNamed(GetOTRIconResourceID()); 648e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 649e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 650e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 651e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project// BrowserView, BrowserWindow implementation: 652e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 653e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Show() { 654e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // If the window is already visible, just activate it. 655e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (frame_->IsVisible()) { 656e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Activate(); 657e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; 658e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 659e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 660e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Showing the window doesn't make the browser window active right away. 661e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // This can cause SetFocusToLocationBar() to skip setting focus to the 662e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // location bar. To avoid this we explicilty let SetFocusToLocationBar() 663e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // know that it's ok to steal focus. 664e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project force_location_bar_focus_ = true; 665e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 666df5080d7feca9827fd0306471c54f52ecf185c22Evan Chu // Setting the focus doesn't work when the window is invisible, so any focus 667df5080d7feca9827fd0306471c54f52ecf185c22Evan Chu // initialization that happened before this will be lost. 668df5080d7feca9827fd0306471c54f52ecf185c22Evan Chu // 669e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We really "should" restore the focus whenever the window becomes unhidden, 670e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // but I think initializing is the only time where this can happen where 671e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // there is some focus change we need to pick up, and this is easier than 672e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // plumbing through an un-hide message all the way from the frame. 673e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // 674e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // If we do find there are cases where we need to restore the focus on show, 675e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // that should be added and this should be removed. 676e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project RestoreFocus(); 677e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 678e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Show(); 679e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 680e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project force_location_bar_focus_ = false; 681e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 682e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser()->OnWindowDidShow(); 683e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 684e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::MaybeShowInvertBubbleView(browser_.get(), contents_container_); 685e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 686e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 687e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ShowInactive() { 688e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (frame_->IsVisible()) 689e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; 690e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->ShowInactive(); 691e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 692e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 693e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Hide() { 694e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Not implemented. 695e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 696e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 697e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::SetBounds(const gfx::Rect& bounds) { 698e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ExitFullscreen(); 699e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetWidget()->SetBounds(bounds); 700e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 701e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 702e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Close() { 7035c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen frame_->Close(); 7045c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 705e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 706e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Activate() { 707e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Activate(); 7085c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 7095c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 710e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Deactivate() { 711e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Deactivate(); 712e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 713e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 714e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsActive() const { 715e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return frame_->IsActive(); 716e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 717e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 718e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::FlashFrame(bool flash) { 719e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->FlashFrame(flash); 720e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 721e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 722e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsAlwaysOnTop() const { 723e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 724e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 725e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 726e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::SetAlwaysOnTop(bool always_on_top) { 727e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Not implemented for browser windows. 728e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project NOTIMPLEMENTED(); 729e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 730e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 731e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::NativeWindow BrowserView::GetNativeWindow() { 732e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // While the browser destruction is going on, the widget can already be gone, 733e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // but utility functions like FindBrowserWithWindow will come here and crash. 734e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We short circuit therefore. 735e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!GetWidget()) 736e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return NULL; 737e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return GetWidget()->GetTopLevelWidget()->GetNativeWindow(); 738e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 739e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 740e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectBrowserWindowTesting* BrowserView::GetBrowserWindowTesting() { 741e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return this; 742e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 743e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 744e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectStatusBubble* BrowserView::GetStatusBubble() { 745e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return status_bubble_.get(); 746e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 747e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 748e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectnamespace { 749e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Only used by ToolbarSizeChanged() below, but placed here because template 750e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // arguments (to base::AutoReset<>) must have external linkage. 751e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project enum CallState { NORMAL, REENTRANT, REENTRANT_FORCE_FAST_RESIZE }; 752e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 753e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 754e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::UpdateTitleBar() { 755e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->UpdateWindowTitle(); 756e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (ShouldShowWindowIcon() && !loading_animation_timer_.IsRunning()) 757e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->UpdateWindowIcon(); 758e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 759e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 760e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::BookmarkBarStateChanged( 761e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BookmarkBar::AnimateChangeType change_type) { 762e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (bookmark_bar_view_.get()) { 763e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BookmarkBar::State new_state = browser_->bookmark_bar_state(); 764e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 765e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We don't properly support animating the bookmark bar to and from the 766e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // detached state in immersive fullscreen. 767e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool detached_changed = (new_state == BookmarkBar::DETACHED) || 768e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bookmark_bar_view_->IsDetached(); 769e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (detached_changed && immersive_mode_controller_->IsEnabled()) 770e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project change_type = BookmarkBar::DONT_ANIMATE_STATE_CHANGE; 771e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 772e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bookmark_bar_view_->SetBookmarkBarState(new_state, change_type); 773e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 774df5080d7feca9827fd0306471c54f52ecf185c22Evan Chu if (MaybeShowBookmarkBar(GetActiveWebContents())) 775e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Layout(); 776e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 777e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 778e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::UpdateDevTools() { 779e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project UpdateDevToolsForContents(GetActiveWebContents()); 780e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Layout(); 781e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 782e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 783e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::UpdateLoadingAnimations(bool should_animate) { 784e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (should_animate) { 785e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!loading_animation_timer_.IsRunning()) { 786e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Loads are happening, and the timer isn't running, so start it. 787e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project last_animation_time_ = base::TimeTicks::Now(); 788e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project loading_animation_timer_.Start(FROM_HERE, 789e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project TimeDelta::FromMilliseconds(kLoadingAnimationFrameTimeMs), this, 790e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project &BrowserView::LoadingAnimationCallback); 791e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 7925c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen } else { 7935c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (loading_animation_timer_.IsRunning()) { 794e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project last_animation_time_ = base::TimeTicks(); 795e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project loading_animation_timer_.Stop(); 796e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Loads are now complete, update the state if a task was scheduled. 797e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project LoadingAnimationCallback(); 798e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 799e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 800e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 801e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 802e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::SetStarredState(bool is_starred) { 803e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetLocationBarView()->SetStarToggled(is_starred); 804e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 805e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 806e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::OnActiveTabChanged(content::WebContents* old_contents, 807e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project content::WebContents* new_contents, 808e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int index, 809e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int reason) { 810e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DCHECK(new_contents); 811e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 812e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // If |contents_container_| already has the correct WebContents, we can save 813e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // some work. This also prevents extra events from being reported by the 814e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Visibility API under Windows, as ChangeWebContents will briefly hide 815e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // the WebContents window. 816e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool change_tab_contents = 817e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_->web_contents() != new_contents; 818e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 819e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Update various elements that are interested in knowing the current 820e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // WebContents. 821e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 822e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // When we toggle the NTP floating bookmarks bar and/or the info bar, 823e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // we don't want any WebContents to be attached, so that we 824e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // avoid an unnecessary resize and re-layout of a WebContents. 825e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (change_tab_contents) 826e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_->SetWebContents(NULL); 827e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project infobar_container_->ChangeInfoBarService( 828e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project InfoBarService::FromWebContents(new_contents)); 8295c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (bookmark_bar_view_.get()) { 8305c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen bookmark_bar_view_->SetBookmarkBarState( 8315c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen browser_->bookmark_bar_state(), 8325c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen BookmarkBar::DONT_ANIMATE_STATE_CHANGE); 8335c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen } 834e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project UpdateUIForContents(new_contents); 835e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 836e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Layout for DevTools _before_ setting the main WebContents to avoid 837e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // toggling the size of the main WebContents. 838e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project UpdateDevToolsForContents(new_contents); 839e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 840e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (change_tab_contents) 841e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_->SetWebContents(new_contents); 842e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 843e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!browser_->tab_strip_model()->closing_all() && GetWidget()->IsActive() && 844e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetWidget()->IsVisible()) { 845e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We only restore focus if our window is visible, to avoid invoking blur 846e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // handlers when we are eventually shown. 847e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project new_contents->GetView()->RestoreFocus(); 848e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 849e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 850e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Update all the UI bits. 851e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project UpdateTitleBar(); 852e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 853e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 854e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ZoomChangedForActiveTab(bool can_show_bubble) { 855e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetLocationBarView()->ZoomChangedForActiveTab( 856e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project can_show_bubble && !toolbar_->IsWrenchMenuShowing()); 857e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 858e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 859e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::Rect BrowserView::GetRestoredBounds() const { 860e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return frame_->GetRestoredBounds(); 861e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 862e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 863e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectui::WindowShowState BrowserView::GetRestoredState() const { 864e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (IsMaximized()) 865e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return ui::SHOW_STATE_MAXIMIZED; 8665c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (IsMinimized()) 867e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return ui::SHOW_STATE_MINIMIZED; 868e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return ui::SHOW_STATE_NORMAL; 869e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 870e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 871e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::Rect BrowserView::GetBounds() const { 872e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return frame_->GetWindowBoundsInScreen(); 873e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 874e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 875e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsMaximized() const { 876e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return frame_->IsMaximized(); 877e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 878e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 879e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsMinimized() const { 880e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return frame_->IsMinimized(); 881e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 882e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 883e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Maximize() { 884e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Maximize(); 885e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 886e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 887e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Minimize() { 888e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Minimize(); 889e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 890e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 891e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::Restore() { 892e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->Restore(); 893e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 894e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 895e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::EnterFullscreen( 896e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const GURL& url, FullscreenExitBubbleType bubble_type) { 897e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (IsFullscreen()) 898e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; // Nothing to do. 899e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 900e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProcessFullscreen(true, FOR_DESKTOP, url, bubble_type); 901e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 902e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 903e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ExitFullscreen() { 904e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!IsFullscreen()) 9055c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen return; // Nothing to do. 9065c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 9075c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen ProcessFullscreen(false, FOR_DESKTOP, GURL(), FEB_TYPE_NONE); 9085c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen} 9095c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen 9105c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenenvoid BrowserView::UpdateFullscreenExitBubbleContent( 9115c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen const GURL& url, 9125c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen FullscreenExitBubbleType bubble_type) { 9135c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // Immersive mode has no exit bubble because it has a visible strip at the 9145c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // top that gives the user a hover target. 9155c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen // TODO(jamescook): Figure out what to do with mouse-lock. 9165c65c3a0f42e174e47fecd4e569606003217ff4eMartijn Coenen if (bubble_type == FEB_TYPE_NONE || ShouldUseImmersiveFullscreenForUrl(url)) { 917e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project fullscreen_bubble_.reset(); 918e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } else if (fullscreen_bubble_.get()) { 919e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project fullscreen_bubble_->UpdateContent(url, bubble_type); 920e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } else { 921e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project fullscreen_bubble_.reset(new FullscreenExitBubbleViews( 922e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project this, url, bubble_type)); 923e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 924e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 925e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 926e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::ShouldHideUIForFullscreen() const { 927e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(USE_ASH) 928e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Immersive mode needs UI for the slide-down top panel. 929e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return IsFullscreen() && !immersive_mode_controller_->IsEnabled(); 930e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 931e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return IsFullscreen(); 932e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 933e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 934e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsFullscreen() const { 935e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return frame_->IsFullscreen(); 936e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 937e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 938e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsFullscreenBubbleVisible() const { 939e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return fullscreen_bubble_ != NULL; 940e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 941e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 942e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_WIN) 943e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::SetMetroSnapMode(bool enable) { 944e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project HISTOGRAM_COUNTS("Metro.SnapModeToggle", enable); 945e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ProcessFullscreen(enable, FOR_METRO, GURL(), FEB_TYPE_NONE); 946e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 947e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 948e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsInMetroSnapMode() const { 949e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(USE_AURA) 950e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 951e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#else 952e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return static_cast<views::NativeWidgetWin*>( 953e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->native_widget())->IsInMetroSnapMode(); 954e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 955e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 956e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif // defined(OS_WIN) 957e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 958e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::RestoreFocus() { 959e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project WebContents* selected_web_contents = GetActiveWebContents(); 960e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (selected_web_contents) 961e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project selected_web_contents->GetView()->RestoreFocus(); 962e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 963e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 964e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::SetWindowSwitcherButton(views::Button* button) { 965e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (window_switcher_button_) 966e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project RemoveChildView(window_switcher_button_); 967e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project window_switcher_button_ = button; 968e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 969e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 970e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ToolbarSizeChanged(bool is_animating) { 971e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // The call to InfoBarContainer::SetMaxTopArrowHeight() below can result in 972e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // reentrancy; |call_state| tracks whether we're reentrant. We can't just 973e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // early-return in this case because we need to layout again so the infobar 974e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // container's bounds are set correctly. 975e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project static CallState call_state = NORMAL; 976e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 977e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // A reentrant call can (and should) use the fast resize path unless both it 978e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // and the normal call are both non-animating. 979e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bool use_fast_resize = 980e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project is_animating || (call_state == REENTRANT_FORCE_FAST_RESIZE); 981e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (use_fast_resize) 982e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_->SetFastResize(true); 983e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project UpdateUIForContents(GetActiveWebContents()); 984e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (use_fast_resize) 985e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_->SetFastResize(false); 986e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 987e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Inform the InfoBarContainer that the distance to the location icon may have 988e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // changed. We have to do this after the block above so that the toolbars are 989e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // laid out correctly for calculating the maximum arrow height below. 990e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 991e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project base::AutoReset<CallState> resetter(&call_state, 992e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project is_animating ? REENTRANT_FORCE_FAST_RESIZE : REENTRANT); 993e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project infobar_container_->SetMaxTopArrowHeight(GetMaxTopInfoBarArrowHeight()); 994e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 995e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 996e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // When transitioning from animating to not animating we need to make sure the 997e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // contents_container_ gets layed out. If we don't do this and the bounds 998e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // haven't changed contents_container_ won't get a Layout out and we'll end up 999e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // with a gray rect because the clip wasn't updated. Note that a reentrant 1000e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // call never needs to do this, because after it returns, the normal call 1001e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // wrapping it will do it. 1002e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if ((call_state == NORMAL) && !is_animating) { 1003e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_web_view_->InvalidateLayout(); 1004e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project contents_split_->Layout(); 1005e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1006e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1007e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1008e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source ProjectLocationBar* BrowserView::GetLocationBar() const { 1009e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return GetLocationBarView(); 1010e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1011e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1012e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::SetFocusToLocationBar(bool select_all) { 1013e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // On Windows, changing focus to the location bar causes the browser 1014e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // window to become active. This can steal focus if the user has 1015e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // another window open already. On ChromeOS, changing focus makes a 1016e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // view believe it has a focus even if the widget doens't have a 1017e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // focus. Either cases, we need to ignore this when the browser 1018e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // window isn't active. 1019e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!force_location_bar_focus_ && !IsActive()) 1020e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; 1021e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1022e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Temporarily reveal the top-of-window views (if not already revealed) so 1023e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // that the location bar view is visible and is considered focusable. If the 1024e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // location bar view gains focus, |immersive_mode_controller_| will keep the 1025e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // top-of-window views revealed. 1026e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project scoped_ptr<ImmersiveRevealedLock> focus_reveal_lock( 1027e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project immersive_mode_controller_->GetRevealedLock( 1028e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ImmersiveModeController::ANIMATE_REVEAL_YES)); 1029e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1030e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project LocationBarView* location_bar = GetLocationBarView(); 1031e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (location_bar->IsLocationEntryFocusableInRootView()) { 1032e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Location bar got focus. 1033e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project location_bar->FocusLocation(select_all); 1034e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } else { 1035e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // If none of location bar got focus, 1036e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // then clear focus. 1037e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project views::FocusManager* focus_manager = GetFocusManager(); 1038e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DCHECK(focus_manager); 1039e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project focus_manager->ClearFocus(); 1040e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1041e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1042e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1043e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::UpdateReloadStopState(bool is_loading, bool force) { 1044e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_->reload_button()->ChangeMode( 1045e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project is_loading ? ReloadButton::MODE_STOP : ReloadButton::MODE_RELOAD, force); 1046e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1047e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1048e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::UpdateToolbar(content::WebContents* contents) { 1049e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // We may end up here during destruction. 1050e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (toolbar_) 1051e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_->Update(contents); 1052e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1053e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1054e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::FocusToolbar() { 1055e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Temporarily reveal the top-of-window views (if not already revealed) so 1056e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // that the toolbar is visible and is considered focusable. If the 1057e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // toolbar gains focus, |immersive_mode_controller_| will keep the 1058e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // top-of-window views revealed. 1059e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project scoped_ptr<ImmersiveRevealedLock> focus_reveal_lock( 1060e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project immersive_mode_controller_->GetRevealedLock( 1061e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ImmersiveModeController::ANIMATE_REVEAL_YES)); 1062e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1063e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Start the traversal within the main toolbar. SetPaneFocus stores 1064e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // the current focused view before changing focus. 1065e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_->SetPaneFocus(NULL); 1066e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1067e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1068e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::FocusBookmarksToolbar() { 1069e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DCHECK(!immersive_mode_controller_->IsEnabled()); 1070e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (bookmark_bar_view_.get() && 1071e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bookmark_bar_view_->visible() && 1072e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bookmark_bar_view_->GetPreferredSize().height() != 0) { 1073e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bookmark_bar_view_->SetPaneFocusAndFocusDefault(); 1074e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1075e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1076e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1077e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::FocusInfobars() { 1078e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (infobar_container_->child_count() > 0) 1079e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project infobar_container_->SetPaneFocusAndFocusDefault(); 1080e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1081e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1082e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::FocusAppMenu() { 1083e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Chrome doesn't have a traditional menu bar, but it has a menu button in the 1084e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // main toolbar that plays the same role. If the user presses a key that 1085e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // would typically focus the menu bar, tell the toolbar to focus the menu 1086e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // button. If the user presses the key again, return focus to the previous 1087e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // location. 1088e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // 1089e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Not used on the Mac, which has a normal menu bar. 1090e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (toolbar_->IsAppMenuFocused()) { 1091e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project RestoreFocus(); 1092e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } else { 1093e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project DCHECK(!immersive_mode_controller_->IsEnabled()); 1094e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project toolbar_->SetPaneFocusAndFocusAppMenu(); 1095e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 1096e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1097e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1098e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::RotatePaneFocus(bool forwards) { 1099e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetWidget()->GetFocusManager()->RotatePaneFocus( 1100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project forwards ? 1101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project views::FocusManager::kForward : views::FocusManager::kBackward, 1102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project views::FocusManager::kWrap); 1103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::DestroyBrowser() { 1106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // After this returns other parts of Chrome are going to be shutdown. Close 1107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // the window now so that we are deleted immediately and aren't left holding 1108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // references to deleted objects. 1109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetWidget()->RemoveObserver(this); 1110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project GetLocationBar()->GetLocationEntry()->model()->popup_model()->RemoveObserver( 1111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project this); 1112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->CloseNow(); 1113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsBookmarkBarVisible() const { 1116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR)) 1117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 1118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!bookmark_bar_view_.get()) 1119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 1120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (bookmark_bar_view_->GetPreferredSize().height() == 0) 1121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 1122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // New tab page needs visible bookmarks even when top-views are hidden. 1123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (immersive_mode_controller_->ShouldHideTopViews() && 1124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project !bookmark_bar_view_->IsDetached()) 1125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 1126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return true; 1127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsBookmarkBarAnimating() const { 1130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return bookmark_bar_view_.get() && bookmark_bar_view_->is_animating(); 1131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsTabStripEditable() const { 1134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return tabstrip_->IsTabStripEditable(); 1135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectbool BrowserView::IsToolbarVisible() const { 1138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (immersive_mode_controller_->ShouldHideTopViews()) 1139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return false; 1140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return browser_->SupportsWindowFeature(Browser::FEATURE_TOOLBAR) || 1141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR); 1142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectgfx::Rect BrowserView::GetRootWindowResizerRect() const { 1145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // Views does not support resizer rects because they caused page cycler 1146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project // performance regressions when they were added. See crrev.com/9654 1147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return gfx::Rect(); 1148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::DisableInactiveFrame() { 1151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#if defined(OS_WIN) && !defined(USE_AURA) 1152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project frame_->DisableInactiveRendering(); 1153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif // No tricks are needed to get the right behavior on Linux. 1154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ConfirmAddSearchProvider(TemplateURL* template_url, 1157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project Profile* profile) { 1158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project chrome::EditSearchEngine(GetWidget()->GetNativeWindow(), template_url, NULL, 1159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project profile); 1160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ShowUpdateChromeDialog() { 1163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project UpdateRecommendedMessageBox::Show(GetWidget()->GetNativeWindow()); 1164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid BrowserView::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) { 1167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project scoped_ptr<BookmarkBubbleDelegate> delegate; 1168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project delegate.reset(new BookmarkBubbleSignInDelegate(browser_.get())); 1169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project BookmarkBubbleView::ShowBubble(GetToolbarView()->GetBookmarkBubbleAnchor(), 1171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project bookmark_bar_view_.get(), 1172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project delegate.Pass(), 1173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project browser_->profile(), 1174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project url, 1175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project !already_bookmarked); 1176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 1177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 1178void BrowserView::ShowBookmarkPrompt() { 1179 GetLocationBarView()->ShowBookmarkPrompt(); 1180} 1181 1182void BrowserView::ShowTranslateBubble( 1183 content::WebContents* web_contents, 1184 TranslateBubbleModel::ViewState view_state) { 1185 TranslateTabHelper* translate_tab_helper = 1186 TranslateTabHelper::FromWebContents(web_contents); 1187 LanguageState& language_state = translate_tab_helper->language_state(); 1188 language_state.SetTranslateEnabled(true); 1189 1190 TranslateBubbleView::ShowBubble(GetToolbarView()->GetTranslateBubbleAnchor(), 1191 web_contents, view_state, browser_.get()); 1192} 1193 1194#if defined(ENABLE_ONE_CLICK_SIGNIN) 1195void BrowserView::ShowOneClickSigninBubble( 1196 OneClickSigninBubbleType type, 1197 const string16& email, 1198 const string16& error_message, 1199 const StartSyncCallback& start_sync_callback) { 1200 scoped_ptr<OneClickSigninBubbleDelegate> delegate; 1201 delegate.reset(new OneClickSigninBubbleLinksDelegate(browser())); 1202 1203 views::View* anchor_view; 1204 if (type == BrowserWindow::ONE_CLICK_SIGNIN_BUBBLE_TYPE_BUBBLE) 1205 anchor_view = toolbar_->app_menu(); 1206 else 1207 anchor_view = toolbar_->location_bar(); 1208 1209 OneClickSigninBubbleView::ShowBubble(type, email, error_message, 1210 delegate.Pass(), anchor_view, 1211 start_sync_callback); 1212} 1213#endif 1214 1215void BrowserView::SetDownloadShelfVisible(bool visible) { 1216 // This can be called from the superclass destructor, when it destroys our 1217 // child views. At that point, browser_ is already gone. 1218 if (browser_ == NULL) 1219 return; 1220 1221 if (visible && IsDownloadShelfVisible() != visible) { 1222 // Invoke GetDownloadShelf to force the shelf to be created. 1223 GetDownloadShelf(); 1224 } 1225 1226 if (browser_ != NULL) 1227 browser_->UpdateDownloadShelfVisibility(visible); 1228 1229 // SetDownloadShelfVisible can force-close the shelf, so make sure we lay out 1230 // everything correctly, as if the animation had finished. This doesn't 1231 // matter for showing the shelf, as the show animation will do it. 1232 ToolbarSizeChanged(false); 1233} 1234 1235bool BrowserView::IsDownloadShelfVisible() const { 1236 return download_shelf_.get() && download_shelf_->IsShowing(); 1237} 1238 1239DownloadShelf* BrowserView::GetDownloadShelf() { 1240 if (!download_shelf_.get()) { 1241 download_shelf_.reset(new DownloadShelfView(browser_.get(), this)); 1242 download_shelf_->set_owned_by_client(); 1243 GetBrowserViewLayout()->set_download_shelf(download_shelf_.get()); 1244 } 1245 return download_shelf_.get(); 1246} 1247 1248void BrowserView::ConfirmBrowserCloseWithPendingDownloads( 1249 int download_count, 1250 Browser::DownloadClosePreventionType dialog_type, 1251 bool app_modal, 1252 const base::Callback<void(bool)>& callback) { 1253 DownloadInProgressDialogView::Show( 1254 GetNativeWindow(), download_count, dialog_type, app_modal, callback); 1255} 1256 1257void BrowserView::UserChangedTheme() { 1258 frame_->FrameTypeChanged(); 1259} 1260 1261int BrowserView::GetExtraRenderViewHeight() const { 1262 // Currently this is only used on linux. 1263 return 0; 1264} 1265 1266void BrowserView::WebContentsFocused(WebContents* contents) { 1267 if (contents_web_view_->GetWebContents() == contents) 1268 contents_web_view_->OnWebContentsFocused(contents); 1269 else 1270 devtools_container_->OnWebContentsFocused(contents); 1271} 1272 1273void BrowserView::ShowWebsiteSettings(Profile* profile, 1274 content::WebContents* web_contents, 1275 const GURL& url, 1276 const content::SSLStatus& ssl) { 1277 WebsiteSettingsPopupView::ShowPopup( 1278 GetLocationBarView()->location_icon_view(), profile, 1279 web_contents, url, ssl, browser_.get()); 1280} 1281 1282void BrowserView::ShowAppMenu() { 1283 // Keep the top-of-window views revealed as long as the app menu is visible. 1284 scoped_ptr<ImmersiveRevealedLock> revealed_lock( 1285 immersive_mode_controller_->GetRevealedLock( 1286 ImmersiveModeController::ANIMATE_REVEAL_NO)); 1287 1288 toolbar_->app_menu()->Activate(); 1289} 1290 1291bool BrowserView::PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, 1292 bool* is_keyboard_shortcut) { 1293 *is_keyboard_shortcut = false; 1294 1295 if ((event.type != WebKit::WebInputEvent::RawKeyDown) && 1296 (event.type != WebKit::WebInputEvent::KeyUp)) { 1297 return false; 1298 } 1299 1300#if defined(OS_WIN) && !defined(USE_AURA) 1301 // As Alt+F4 is the close-app keyboard shortcut, it needs processing 1302 // immediately. 1303 if (event.windowsKeyCode == ui::VKEY_F4 && 1304 event.type == WebKit::WebInputEvent::RawKeyDown && 1305 event.modifiers == NativeWebKeyboardEvent::AltKey) { 1306 DefWindowProc(event.os_event.hwnd, event.os_event.message, 1307 event.os_event.wParam, event.os_event.lParam); 1308 return true; 1309 } 1310#endif 1311 1312 views::FocusManager* focus_manager = GetFocusManager(); 1313 DCHECK(focus_manager); 1314 1315 if (focus_manager->shortcut_handling_suspended()) 1316 return false; 1317 1318 ui::Accelerator accelerator( 1319 static_cast<ui::KeyboardCode>(event.windowsKeyCode), 1320 content::GetModifiersFromNativeWebKeyboardEvent(event)); 1321 if (event.type == WebKit::WebInputEvent::KeyUp) 1322 accelerator.set_type(ui::ET_KEY_RELEASED); 1323 1324 // What we have to do here is as follows: 1325 // - If the |browser_| is for an app, do nothing. 1326 // - If the |browser_| is not for an app, and the |accelerator| is not 1327 // associated with the browser (e.g. an Ash shortcut), process it. 1328 // - If the |browser_| is not for an app, and the |accelerator| is associated 1329 // with the browser, and it is a reserved one (e.g. Ctrl+w), process it. 1330 // - If the |browser_| is not for an app, and the |accelerator| is associated 1331 // with the browser, and it is not a reserved one, do nothing. 1332 1333 if (browser_->is_app()) { 1334 // Let all keys fall through to a v1 app's web content, even accelerators. 1335 // We don't have to flip |is_keyboard_shortcut| here. If we do that, the app 1336 // might not be able to see a subsequent Char event. See OnHandleInputEvent 1337 // in content/renderer/render_widget.cc for details. 1338 return false; 1339 } 1340 1341 chrome::BrowserCommandController* controller = browser_->command_controller(); 1342 1343 // Here we need to retrieve the command id (if any) associated to the 1344 // keyboard event. Instead of looking up the command id in the 1345 // |accelerator_table_| by ourselves, we block the command execution of 1346 // the |browser_| object then send the keyboard event to the 1347 // |focus_manager| as if we are activating an accelerator key. 1348 // Then we can retrieve the command id from the |browser_| object. 1349 bool original_block_command_state = controller->block_command_execution(); 1350 controller->SetBlockCommandExecution(true); 1351 // If the |accelerator| is a non-browser shortcut (e.g. Ash shortcut), the 1352 // command execution cannot be blocked and true is returned. However, it is 1353 // okay as long as is_app() is false. See comments in this function. 1354 const bool processed = focus_manager->ProcessAccelerator(accelerator); 1355 const int id = controller->GetLastBlockedCommand(NULL); 1356 controller->SetBlockCommandExecution(original_block_command_state); 1357 1358 // Executing the command may cause |this| object to be destroyed. 1359 if (controller->IsReservedCommandOrKey(id, event)) { 1360 UpdateAcceleratorMetrics(accelerator, id); 1361 return chrome::ExecuteCommand(browser_.get(), id); 1362 } 1363 1364 if (id != -1) { 1365 // |accelerator| is a non-reserved browser shortcut (e.g. Ctrl+f). 1366 if (event.type == WebKit::WebInputEvent::RawKeyDown) 1367 *is_keyboard_shortcut = true; 1368 } else if (processed) { 1369 // |accelerator| is a non-browser shortcut (e.g. F4-F10 on Ash). Report 1370 // that we handled it. 1371 return true; 1372 } 1373 1374 return false; 1375} 1376 1377void BrowserView::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { 1378 unhandled_keyboard_event_handler_.HandleKeyboardEvent(event, 1379 GetFocusManager()); 1380} 1381 1382// TODO(devint): http://b/issue?id=1117225 Cut, Copy, and Paste are always 1383// enabled in the page menu regardless of whether the command will do 1384// anything. When someone selects the menu item, we just act as if they hit 1385// the keyboard shortcut for the command by sending the associated key press 1386// to windows. The real fix to this bug is to disable the commands when they 1387// won't do anything. We'll need something like an overall clipboard command 1388// manager to do that. 1389void BrowserView::Cut() { 1390 // If a WebContent is focused, call RenderWidgetHost::Cut. Otherwise, e.g. if 1391 // Omnibox is focused, send a Ctrl+x key event to Chrome. Using RWH interface 1392 // rather than the fake key event for a WebContent is important since the fake 1393 // event might be consumed by the web content (crbug.com/137908). 1394 DoCutCopyPaste(&content::RenderWidgetHost::Cut, 1395#if defined(OS_WIN) 1396 WM_CUT, 1397#endif 1398 IDS_APP_CUT); 1399} 1400 1401void BrowserView::Copy() { 1402 DoCutCopyPaste(&content::RenderWidgetHost::Copy, 1403#if defined(OS_WIN) 1404 WM_COPY, 1405#endif 1406 IDS_APP_COPY); 1407} 1408 1409void BrowserView::Paste() { 1410 DoCutCopyPaste(&content::RenderWidgetHost::Paste, 1411#if defined(OS_WIN) 1412 WM_PASTE, 1413#endif 1414 IDS_APP_PASTE); 1415} 1416 1417WindowOpenDisposition BrowserView::GetDispositionForPopupBounds( 1418 const gfx::Rect& bounds) { 1419#if defined(OS_WIN) 1420 // If we are in Win8's single window Metro mode, we can't allow popup windows. 1421 return win8::IsSingleWindowMetroMode() ? NEW_BACKGROUND_TAB : NEW_POPUP; 1422#else 1423 return NEW_POPUP; 1424#endif 1425} 1426 1427FindBar* BrowserView::CreateFindBar() { 1428 return chrome::CreateFindBar(this); 1429} 1430 1431WebContentsModalDialogHost* BrowserView::GetWebContentsModalDialogHost() { 1432 return GetBrowserViewLayout()->GetWebContentsModalDialogHost(); 1433} 1434 1435/////////////////////////////////////////////////////////////////////////////// 1436// BrowserView, BrowserWindowTesting implementation: 1437 1438BookmarkBarView* BrowserView::GetBookmarkBarView() const { 1439 return bookmark_bar_view_.get(); 1440} 1441 1442LocationBarView* BrowserView::GetLocationBarView() const { 1443 return toolbar_ ? toolbar_->location_bar() : NULL; 1444} 1445 1446views::View* BrowserView::GetTabContentsContainerView() const { 1447 return contents_web_view_; 1448} 1449 1450ToolbarView* BrowserView::GetToolbarView() const { 1451 return toolbar_; 1452} 1453 1454/////////////////////////////////////////////////////////////////////////////// 1455// BrowserView, TabStripModelObserver implementation: 1456 1457void BrowserView::TabDetachedAt(WebContents* contents, int index) { 1458 // We use index here rather than comparing |contents| because by this time 1459 // the model has already removed |contents| from its list, so 1460 // browser_->GetActiveWebContents() will return NULL or something else. 1461 if (index == browser_->tab_strip_model()->active_index()) { 1462 // We need to reset the current tab contents to NULL before it gets 1463 // freed. This is because the focus manager performs some operations 1464 // on the selected WebContents when it is removed. 1465 contents_web_view_->SetWebContents(NULL); 1466 infobar_container_->ChangeInfoBarService(NULL); 1467 UpdateDevToolsForContents(NULL); 1468 } 1469} 1470 1471void BrowserView::TabDeactivated(WebContents* contents) { 1472 // We do not store the focus when closing the tab to work-around bug 4633. 1473 // Some reports seem to show that the focus manager and/or focused view can 1474 // be garbage at that point, it is not clear why. 1475 if (!contents->IsBeingDestroyed()) 1476 contents->GetView()->StoreFocus(); 1477} 1478 1479void BrowserView::TabStripEmpty() { 1480 // Make sure all optional UI is removed before we are destroyed, otherwise 1481 // there will be consequences (since our view hierarchy will still have 1482 // references to freed views). 1483 UpdateUIForContents(NULL); 1484} 1485 1486/////////////////////////////////////////////////////////////////////////////// 1487// BrowserView, ui::AcceleratorProvider implementation: 1488 1489bool BrowserView::GetAcceleratorForCommandId(int command_id, 1490 ui::Accelerator* accelerator) { 1491 // Let's let the ToolbarView own the canonical implementation of this method. 1492 return toolbar_->GetAcceleratorForCommandId(command_id, accelerator); 1493} 1494 1495/////////////////////////////////////////////////////////////////////////////// 1496// BrowserView, views::WidgetDelegate implementation: 1497 1498bool BrowserView::CanResize() const { 1499 return true; 1500} 1501 1502bool BrowserView::CanMaximize() const { 1503 return true; 1504} 1505 1506bool BrowserView::CanActivate() const { 1507 if (!AppModalDialogQueue::GetInstance()->active_dialog() || 1508 !AppModalDialogQueue::GetInstance()->active_dialog()->native_dialog()) 1509 return true; 1510 1511#if defined(USE_AURA) && defined(OS_CHROMEOS) 1512 // On Aura window manager controls all windows so settings focus via PostTask 1513 // will make only worse because posted task will keep trying to steal focus. 1514 AppModalDialogQueue::GetInstance()->ActivateModalDialog(); 1515#else 1516 // If another browser is app modal, flash and activate the modal browser. This 1517 // has to be done in a post task, otherwise if the user clicked on a window 1518 // that doesn't have the modal dialog the windows keep trying to get the focus 1519 // from each other on Windows. http://crbug.com/141650. 1520 base::MessageLoop::current()->PostTask( 1521 FROM_HERE, 1522 base::Bind(&BrowserView::ActivateAppModalDialog, 1523 activate_modal_dialog_factory_.GetWeakPtr())); 1524#endif 1525 return false; 1526} 1527 1528string16 BrowserView::GetWindowTitle() const { 1529 return browser_->GetWindowTitleForCurrentTab(); 1530} 1531 1532string16 BrowserView::GetAccessibleWindowTitle() const { 1533 if (IsOffTheRecord()) { 1534 return l10n_util::GetStringFUTF16( 1535 IDS_ACCESSIBLE_INCOGNITO_WINDOW_TITLE_FORMAT, 1536 GetWindowTitle()); 1537 } 1538 return GetWindowTitle(); 1539} 1540 1541views::View* BrowserView::GetInitiallyFocusedView() { 1542 return NULL; 1543} 1544 1545bool BrowserView::ShouldShowWindowTitle() const { 1546 // For Ash only, app host windows do not show an icon, crbug.com/119411. 1547 // Child windows (i.e. popups) do show an icon. 1548 if (browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH && 1549 browser_->is_app() && browser_->app_type() == Browser::APP_TYPE_HOST) 1550 return false; 1551 1552 return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); 1553} 1554 1555gfx::ImageSkia BrowserView::GetWindowAppIcon() { 1556 if (browser_->is_app()) { 1557 WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents(); 1558 extensions::TabHelper* extensions_tab_helper = 1559 contents ? extensions::TabHelper::FromWebContents(contents) : NULL; 1560 if (extensions_tab_helper && extensions_tab_helper->GetExtensionAppIcon()) 1561 return gfx::ImageSkia::CreateFrom1xBitmap( 1562 *extensions_tab_helper->GetExtensionAppIcon()); 1563 } 1564 1565 return GetWindowIcon(); 1566} 1567 1568gfx::ImageSkia BrowserView::GetWindowIcon() { 1569 if (browser_->is_app() || browser_->is_type_popup()) 1570 return browser_->GetCurrentPageIcon().AsImageSkia(); 1571 return gfx::ImageSkia(); 1572} 1573 1574bool BrowserView::ShouldShowWindowIcon() const { 1575 // For Ash only, app host windows do not show an icon, crbug.com/119411. 1576 // Child windows (i.e. popups) do show an icon. 1577 if (browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH && 1578 browser_->is_app() && browser_->app_type() == Browser::APP_TYPE_HOST) 1579 return false; 1580 1581 return browser_->SupportsWindowFeature(Browser::FEATURE_TITLEBAR); 1582} 1583 1584bool BrowserView::ExecuteWindowsCommand(int command_id) { 1585 // This function handles WM_SYSCOMMAND, WM_APPCOMMAND, and WM_COMMAND. 1586#if defined(OS_WIN) 1587 if (command_id == IDC_DEBUG_FRAME_TOGGLE) 1588 GetWidget()->DebugToggleFrameType(); 1589 1590 // In Windows 8 metro mode prevent sizing and moving. 1591 if (win8::IsSingleWindowMetroMode()) { 1592 // Windows uses the 4 lower order bits of |notification_code| for type- 1593 // specific information so we must exclude this when comparing. 1594 static const int sc_mask = 0xFFF0; 1595 if (((command_id & sc_mask) == SC_MOVE) || 1596 ((command_id & sc_mask) == SC_SIZE) || 1597 ((command_id & sc_mask) == SC_MAXIMIZE)) 1598 return true; 1599 } 1600#endif 1601 // Translate WM_APPCOMMAND command ids into a command id that the browser 1602 // knows how to handle. 1603 int command_id_from_app_command = GetCommandIDForAppCommandID(command_id); 1604 if (command_id_from_app_command != -1) 1605 command_id = command_id_from_app_command; 1606 1607 return chrome::ExecuteCommand(browser_.get(), command_id); 1608} 1609 1610std::string BrowserView::GetWindowName() const { 1611 return chrome::GetWindowPlacementKey(browser_.get()); 1612} 1613 1614void BrowserView::SaveWindowPlacement(const gfx::Rect& bounds, 1615 ui::WindowShowState show_state) { 1616 // If IsFullscreen() is true, we've just changed into fullscreen mode, and 1617 // we're catching the going-into-fullscreen sizing and positioning calls, 1618 // which we want to ignore. 1619 if (!ShouldSaveOrRestoreWindowPos()) 1620 return; 1621 1622 if (!IsFullscreen() && chrome::ShouldSaveWindowPlacement(browser_.get())) { 1623 WidgetDelegate::SaveWindowPlacement(bounds, show_state); 1624 chrome::SaveWindowPlacement(browser_.get(), bounds, show_state); 1625 } 1626} 1627 1628bool BrowserView::GetSavedWindowPlacement( 1629 const views::Widget* widget, 1630 gfx::Rect* bounds, 1631 ui::WindowShowState* show_state) const { 1632 if (!ShouldSaveOrRestoreWindowPos()) 1633 return false; 1634 chrome::GetSavedWindowBoundsAndShowState(browser_.get(), bounds, show_state); 1635 1636 if (browser_->is_type_popup() && 1637 !browser_->is_app() && 1638 !browser_->is_devtools()) { 1639 // This is non-app popup window. The value passed in |bounds| represents 1640 // two pieces of information: 1641 // - the position of the window, in screen coordinates (outer position). 1642 // - the size of the content area (inner size). 1643 // We need to use these values to determine the appropriate size and 1644 // position of the resulting window. 1645 if (IsToolbarVisible()) { 1646 // If we're showing the toolbar, we need to adjust |*bounds| to include 1647 // its desired height, since the toolbar is considered part of the 1648 // window's client area as far as GetWindowBoundsForClientBounds is 1649 // concerned... 1650 bounds->set_height( 1651 bounds->height() + toolbar_->GetPreferredSize().height()); 1652 } 1653 1654 gfx::Rect window_rect = frame_->non_client_view()-> 1655 GetWindowBoundsForClientBounds(*bounds); 1656 window_rect.set_origin(bounds->origin()); 1657 1658 // When we are given x/y coordinates of 0 on a created popup window, 1659 // assume none were given by the window.open() command. 1660 if (window_rect.x() == 0 && window_rect.y() == 0) { 1661 gfx::Size size = window_rect.size(); 1662 window_rect.set_origin( 1663 WindowSizer::GetDefaultPopupOrigin(size, 1664 browser_->host_desktop_type())); 1665 } 1666 1667 *bounds = window_rect; 1668 *show_state = ui::SHOW_STATE_NORMAL; 1669 } 1670 1671 // We return true because we can _always_ locate reasonable bounds using the 1672 // WindowSizer, and we don't want to trigger the Window's built-in "size to 1673 // default" handling because the browser window has no default preferred 1674 // size. 1675 return true; 1676} 1677 1678views::View* BrowserView::GetContentsView() { 1679 return contents_web_view_; 1680} 1681 1682views::ClientView* BrowserView::CreateClientView(views::Widget* widget) { 1683 return this; 1684} 1685 1686void BrowserView::OnWidgetActivationChanged(views::Widget* widget, 1687 bool active) { 1688 if (active) 1689 BrowserList::SetLastActive(browser_.get()); 1690} 1691 1692void BrowserView::OnWindowBeginUserBoundsChange() { 1693 WebContents* web_contents = GetActiveWebContents(); 1694 if (!web_contents) 1695 return; 1696 web_contents->GetRenderViewHost()->NotifyMoveOrResizeStarted(); 1697} 1698 1699void BrowserView::OnWidgetMove() { 1700 if (!initialized_) { 1701 // Creating the widget can trigger a move. Ignore it until we've initialized 1702 // things. 1703 return; 1704 } 1705 1706 // Cancel any tabstrip animations, some of them may be invalidated by the 1707 // window being repositioned. 1708 // Comment out for one cycle to see if this fixes dist tests. 1709 // tabstrip_->DestroyDragController(); 1710 1711 // status_bubble_ may be NULL if this is invoked during construction. 1712 if (status_bubble_.get()) 1713 status_bubble_->Reposition(); 1714 1715 BookmarkBubbleView::Hide(); 1716 1717 // Close the omnibox popup, if any. 1718 LocationBarView* location_bar_view = GetLocationBarView(); 1719 if (location_bar_view) 1720 location_bar_view->GetLocationEntry()->CloseOmniboxPopup(); 1721} 1722 1723views::Widget* BrowserView::GetWidget() { 1724 return View::GetWidget(); 1725} 1726 1727const views::Widget* BrowserView::GetWidget() const { 1728 return View::GetWidget(); 1729} 1730 1731void BrowserView::GetAccessiblePanes(std::vector<views::View*>* panes) { 1732 // This should be in the order of pane traversal of the panes using F6 1733 // (Windows) or Ctrl+Back/Forward (Chrome OS). If one of these is 1734 // invisible or has no focusable children, it will be automatically 1735 // skipped. 1736 panes->push_back(toolbar_); 1737 if (bookmark_bar_view_.get()) 1738 panes->push_back(bookmark_bar_view_.get()); 1739 if (infobar_container_) 1740 panes->push_back(infobar_container_); 1741 if (download_shelf_.get()) 1742 panes->push_back(download_shelf_.get()); 1743 panes->push_back(GetTabContentsContainerView()); 1744 if (devtools_container_->visible()) 1745 panes->push_back(devtools_container_); 1746} 1747 1748/////////////////////////////////////////////////////////////////////////////// 1749// BrowserView, views::ClientView overrides: 1750 1751bool BrowserView::CanClose() { 1752 // You cannot close a frame for which there is an active originating drag 1753 // session. 1754 if (tabstrip_ && !tabstrip_->IsTabStripCloseable()) 1755 return false; 1756 1757 // Give beforeunload handlers the chance to cancel the close before we hide 1758 // the window below. 1759 if (!browser_->ShouldCloseWindow()) 1760 return false; 1761 1762 bool fast_tab_closing_enabled = 1763 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableFastUnload); 1764 1765 if (!browser_->tab_strip_model()->empty()) { 1766 // Tab strip isn't empty. Hide the frame (so it appears to have closed 1767 // immediately) and close all the tabs, allowing the renderers to shut 1768 // down. When the tab strip is empty we'll be called back again. 1769 frame_->Hide(); 1770 browser_->OnWindowClosing(); 1771 if (fast_tab_closing_enabled) 1772 browser_->tab_strip_model()->CloseAllTabs(); 1773 return false; 1774 } else if (fast_tab_closing_enabled && 1775 !browser_->HasCompletedUnloadProcessing()) { 1776 // The browser needs to finish running unload handlers. 1777 // Hide the frame (so it appears to have closed immediately), and 1778 // the browser will call us back again when it is ready to close. 1779 frame_->Hide(); 1780 return false; 1781 } 1782 1783 // Empty TabStripModel, it's now safe to allow the Window to be closed. 1784 content::NotificationService::current()->Notify( 1785 chrome::NOTIFICATION_WINDOW_CLOSED, 1786 content::Source<gfx::NativeWindow>(frame_->GetNativeWindow()), 1787 content::NotificationService::NoDetails()); 1788 return true; 1789} 1790 1791int BrowserView::NonClientHitTest(const gfx::Point& point) { 1792 return GetBrowserViewLayout()->NonClientHitTest(point); 1793} 1794 1795gfx::Size BrowserView::GetMinimumSize() { 1796 return GetBrowserViewLayout()->GetMinimumSize(); 1797} 1798 1799/////////////////////////////////////////////////////////////////////////////// 1800// BrowserView, views::View overrides: 1801 1802const char* BrowserView::GetClassName() const { 1803 return kViewClassName; 1804} 1805 1806void BrowserView::Layout() { 1807 if (!initialized_ || in_process_fullscreen_) 1808 return; 1809 1810 views::View::Layout(); 1811 1812 // TODO(jamescook): Why was this in the middle of layout code? 1813 toolbar_->location_bar()->SetLocationEntryFocusable(IsToolbarVisible()); 1814 1815 // The status bubble position requires that all other layout finish first. 1816 LayoutStatusBubble(); 1817} 1818 1819void BrowserView::PaintChildren(gfx::Canvas* canvas) { 1820 // Paint the |infobar_container_| last so that it may paint its 1821 // overlapping tabs. 1822 for (int i = 0; i < child_count(); ++i) { 1823 View* child = child_at(i); 1824 if (child != infobar_container_ && !child->layer()) 1825 child->Paint(canvas); 1826 } 1827 1828 infobar_container_->Paint(canvas); 1829} 1830 1831void BrowserView::ViewHierarchyChanged( 1832 const ViewHierarchyChangedDetails& details) { 1833 if (!initialized_ && details.is_add && details.child == this && GetWidget()) { 1834 InitViews(); 1835 initialized_ = true; 1836 } 1837} 1838 1839void BrowserView::ChildPreferredSizeChanged(View* child) { 1840 Layout(); 1841} 1842 1843void BrowserView::GetAccessibleState(ui::AccessibleViewState* state) { 1844 state->role = ui::AccessibilityTypes::ROLE_CLIENT; 1845} 1846 1847/////////////////////////////////////////////////////////////////////////////// 1848// BrowserView, ui::AcceleratorTarget overrides: 1849 1850bool BrowserView::AcceleratorPressed(const ui::Accelerator& accelerator) { 1851#if defined(OS_CHROMEOS) 1852 // If accessibility is enabled, stop speech and return false so that key 1853 // combinations involving Search can be used for extra accessibility 1854 // functionality. 1855 if (accelerator.key_code() == ui::VKEY_LWIN && 1856 g_browser_process->local_state()->GetBoolean( 1857 prefs::kSpokenFeedbackEnabled)) { 1858 TtsController::GetInstance()->Stop(); 1859 return false; 1860 } 1861#endif 1862 1863 std::map<ui::Accelerator, int>::const_iterator iter = 1864 accelerator_table_.find(accelerator); 1865 DCHECK(iter != accelerator_table_.end()); 1866 int command_id = iter->second; 1867 1868 chrome::BrowserCommandController* controller = browser_->command_controller(); 1869 if (!controller->block_command_execution()) 1870 UpdateAcceleratorMetrics(accelerator, command_id); 1871 return chrome::ExecuteCommand(browser_.get(), command_id); 1872} 1873 1874/////////////////////////////////////////////////////////////////////////////// 1875// BrowserView, OmniboxPopupModelObserver overrides: 1876void BrowserView::OnOmniboxPopupShownOrHidden() { 1877 infobar_container_->SetMaxTopArrowHeight(GetMaxTopInfoBarArrowHeight()); 1878} 1879 1880/////////////////////////////////////////////////////////////////////////////// 1881// BrowserView, ImmersiveModeController::Delegate overrides: 1882 1883FullscreenController* BrowserView::GetFullscreenController() { 1884 // Cannot be injected into ImmersiveModeController because it is constructed 1885 // after BrowserView. 1886 return browser()->fullscreen_controller(); 1887} 1888 1889void BrowserView::FullscreenStateChanged() { 1890 if (IsFullscreen()) { 1891 ProcessFullscreen(true, FOR_DESKTOP, GURL(), 1892 FEB_TYPE_BROWSER_FULLSCREEN_EXIT_INSTRUCTION); 1893 } else { 1894 ProcessFullscreen(false, FOR_DESKTOP, GURL(), FEB_TYPE_NONE); 1895 } 1896} 1897 1898void BrowserView::SetImmersiveStyle(bool immersive) { 1899 // Only the tab strip changes its painting style for immersive fullscreen. 1900 if (tabstrip_) 1901 tabstrip_->SetImmersiveStyle(immersive); 1902} 1903 1904WebContents* BrowserView::GetWebContents() { 1905 return GetActiveWebContents(); 1906} 1907 1908/////////////////////////////////////////////////////////////////////////////// 1909// BrowserView, InfoBarContainer::Delegate overrides: 1910 1911SkColor BrowserView::GetInfoBarSeparatorColor() const { 1912 // NOTE: Keep this in sync with ToolbarView::OnPaint()! 1913 return (IsTabStripVisible() || !frame_->ShouldUseNativeFrame()) ? 1914 ThemeProperties::GetDefaultColor( 1915 ThemeProperties::COLOR_TOOLBAR_SEPARATOR) : 1916 SK_ColorBLACK; 1917} 1918 1919void BrowserView::InfoBarContainerStateChanged(bool is_animating) { 1920 ToolbarSizeChanged(is_animating); 1921} 1922 1923bool BrowserView::DrawInfoBarArrows(int* x) const { 1924 if (x) { 1925 const LocationIconView* location_icon_view = 1926 toolbar_->location_bar()->location_icon_view(); 1927 gfx::Point icon_center(location_icon_view->GetImageBounds().CenterPoint()); 1928 ConvertPointToTarget(location_icon_view, this, &icon_center); 1929 *x = icon_center.x(); 1930 } 1931 return true; 1932} 1933 1934bool BrowserView::SplitHandleMoved(views::SingleSplitView* sender) { 1935 for (int i = 0; i < sender->child_count(); ++i) 1936 sender->child_at(i)->InvalidateLayout(); 1937 SchedulePaint(); 1938 Layout(); 1939 return false; 1940} 1941 1942void BrowserView::OnSysColorChange() { 1943 chrome::MaybeShowInvertBubbleView(browser_.get(), contents_container_); 1944} 1945 1946void BrowserView::InitViews() { 1947 GetWidget()->AddObserver(this); 1948 1949 // Stow a pointer to this object onto the window handle so that we can get at 1950 // it later when all we have is a native view. 1951 GetWidget()->SetNativeWindowProperty(kBrowserViewKey, this); 1952 1953 // Stow a pointer to the browser's profile onto the window handle so that we 1954 // can get it later when all we have is a native view. 1955 GetWidget()->SetNativeWindowProperty(Profile::kProfileKey, 1956 browser_->profile()); 1957 1958 // Start a hung plugin window detector for this browser object (as long as 1959 // hang detection is not disabled). 1960 if (!CommandLine::ForCurrentProcess()->HasSwitch( 1961 switches::kDisableHangMonitor)) { 1962 InitHangMonitor(); 1963 } 1964 1965 LoadAccelerators(); 1966 1967 infobar_container_ = new InfoBarContainerView(this); 1968 AddChildView(infobar_container_); 1969 1970 contents_web_view_ = new views::WebView(browser_->profile()); 1971 contents_web_view_->set_id(VIEW_ID_TAB_CONTAINER); 1972 contents_web_view_->SetEmbedFullscreenWidgetMode( 1973 implicit_cast<content::WebContentsDelegate*>(browser_.get())-> 1974 EmbedsFullscreenWidget()); 1975 contents_container_ = new ContentsContainer(contents_web_view_); 1976 1977 SkColor bg_color = GetWidget()->GetThemeProvider()-> 1978 GetColor(ThemeProperties::COLOR_TOOLBAR); 1979 1980 devtools_container_ = new views::WebView(browser_->profile()); 1981 devtools_container_->set_id(VIEW_ID_DEV_TOOLS_DOCKED); 1982 devtools_container_->SetVisible(false); 1983 1984 views::View* contents_container_view = contents_container_; 1985 1986 contents_split_ = new views::SingleSplitView( 1987 contents_container_view, 1988 devtools_container_, 1989 views::SingleSplitView::VERTICAL_SPLIT, 1990 this); 1991 contents_split_->set_id(VIEW_ID_CONTENTS_SPLIT); 1992 contents_split_->SetAccessibleName( 1993 l10n_util::GetStringUTF16(IDS_ACCNAME_WEB_CONTENTS)); 1994 contents_split_->set_background( 1995 views::Background::CreateSolidBackground(bg_color)); 1996 AddChildView(contents_split_); 1997 set_contents_view(contents_split_); 1998 1999 InitStatusBubble(); 2000 2001 // Top container holds tab strip and toolbar and lives at the front of the 2002 // view hierarchy. 2003 top_container_ = new TopContainerView(this); 2004 AddChildView(top_container_); 2005 2006 // TabStrip takes ownership of the controller. 2007 BrowserTabStripController* tabstrip_controller = 2008 new BrowserTabStripController(browser_.get(), 2009 browser_->tab_strip_model()); 2010 tabstrip_ = new TabStrip(tabstrip_controller); 2011 top_container_->AddChildView(tabstrip_); 2012 tabstrip_controller->InitFromModel(tabstrip_); 2013 2014 toolbar_ = new ToolbarView(browser_.get()); 2015 top_container_->AddChildView(toolbar_); 2016 toolbar_->Init(); 2017 2018 // Create do-nothing view for the sake of controlling the z-order of the find 2019 // bar widget. 2020 find_bar_host_view_ = new View(); 2021 AddChildView(find_bar_host_view_); 2022 2023 if (window_switcher_button_) 2024 AddChildView(window_switcher_button_); 2025 2026 immersive_mode_controller_->Init(this, GetWidget(), top_container_); 2027 2028 BrowserViewLayout* browser_view_layout = new BrowserViewLayout; 2029 browser_view_layout->Init(new BrowserViewLayoutDelegateImpl(this), 2030 browser(), 2031 this, 2032 top_container_, 2033 tabstrip_, 2034 toolbar_, 2035 infobar_container_, 2036 contents_split_, 2037 contents_container_, 2038 immersive_mode_controller_.get()); 2039 SetLayoutManager(browser_view_layout); 2040 2041#if defined(OS_WIN) && !defined(USE_AURA) 2042 // Create a custom JumpList and add it to an observer of TabRestoreService 2043 // so we can update the custom JumpList when a tab is added or removed. 2044 if (JumpList::Enabled()) { 2045 load_complete_listener_.reset(new LoadCompleteListener(this)); 2046 } 2047#endif 2048 2049 GetLocationBar()->GetLocationEntry()->model()->popup_model()->AddObserver( 2050 this); 2051} 2052 2053void BrowserView::LoadingAnimationCallback() { 2054 base::TimeTicks now = base::TimeTicks::Now(); 2055 if (!last_animation_time_.is_null()) { 2056 UMA_HISTOGRAM_TIMES( 2057 "Tabs.LoadingAnimationTime", 2058 now - last_animation_time_); 2059 } 2060 last_animation_time_ = now; 2061 if (browser_->is_type_tabbed()) { 2062 // Loading animations are shown in the tab for tabbed windows. We check the 2063 // browser type instead of calling IsTabStripVisible() because the latter 2064 // will return false for fullscreen windows, but we still need to update 2065 // their animations (so that when they come out of fullscreen mode they'll 2066 // be correct). 2067 tabstrip_->UpdateLoadingAnimations(); 2068 } else if (ShouldShowWindowIcon()) { 2069 // ... or in the window icon area for popups and app windows. 2070 WebContents* web_contents = 2071 browser_->tab_strip_model()->GetActiveWebContents(); 2072 // GetActiveWebContents can return NULL for example under Purify when 2073 // the animations are running slowly and this function is called on a timer 2074 // through LoadingAnimationCallback. 2075 frame_->UpdateThrobber(web_contents && web_contents->IsLoading()); 2076 } 2077} 2078 2079void BrowserView::OnLoadCompleted() { 2080#if defined(OS_WIN) && !defined(USE_AURA) 2081 DCHECK(!jumplist_); 2082 jumplist_ = new JumpList(); 2083 jumplist_->AddObserver(browser_->profile()); 2084#endif 2085} 2086 2087BrowserViewLayout* BrowserView::GetBrowserViewLayout() const { 2088 return static_cast<BrowserViewLayout*>(GetLayoutManager()); 2089} 2090 2091void BrowserView::LayoutStatusBubble() { 2092 // In restored mode, the client area has a client edge between it and the 2093 // frame. 2094 int overlap = StatusBubbleViews::kShadowThickness; 2095 // The extra pixels defined by kClientEdgeThickness is only drawn in frame 2096 // content border on windows for non-aura build. 2097#if !defined(USE_ASH) 2098 overlap += 2099 IsMaximized() ? 0 : views::NonClientFrameView::kClientEdgeThickness; 2100#endif 2101 int height = status_bubble_->GetPreferredSize().height(); 2102 int contents_height = status_bubble_->base_view()->bounds().height(); 2103 gfx::Point origin(-overlap, contents_height - height + overlap); 2104 status_bubble_->SetBounds(origin.x(), origin.y(), width() / 3, height); 2105} 2106 2107bool BrowserView::MaybeShowBookmarkBar(WebContents* contents) { 2108 bool show_bookmark_bar = contents && 2109 browser_->SupportsWindowFeature(Browser::FEATURE_BOOKMARKBAR); 2110 if (!show_bookmark_bar && !bookmark_bar_view_.get()) 2111 return false; 2112 if (!bookmark_bar_view_.get()) { 2113 bookmark_bar_view_.reset(new BookmarkBarView(browser_.get(), this)); 2114 bookmark_bar_view_->set_owned_by_client(); 2115 bookmark_bar_view_->set_background( 2116 new BookmarkExtensionBackground(this, 2117 bookmark_bar_view_.get(), 2118 browser_.get())); 2119 bookmark_bar_view_->SetBookmarkBarState( 2120 browser_->bookmark_bar_state(), 2121 BookmarkBar::DONT_ANIMATE_STATE_CHANGE); 2122 GetBrowserViewLayout()->set_bookmark_bar(bookmark_bar_view_.get()); 2123 } 2124 bookmark_bar_view_->SetVisible(show_bookmark_bar); 2125 bookmark_bar_view_->SetPageNavigator(contents); 2126 2127 // Update parenting for the bookmark bar. This may detach it from all views. 2128 bool needs_layout = false; 2129 views::View* new_parent = NULL; 2130 if (show_bookmark_bar) { 2131 if (bookmark_bar_view_->IsDetached()) 2132 new_parent = this; 2133 else 2134 new_parent = top_container_; 2135 } 2136 if (new_parent != bookmark_bar_view_->parent()) { 2137 SetBookmarkBarParent(new_parent); 2138 needs_layout = true; 2139 } 2140 2141 // Check for updates to the desired size. 2142 if (bookmark_bar_view_->GetPreferredSize().height() != 2143 bookmark_bar_view_->height()) 2144 needs_layout = true; 2145 2146 return needs_layout; 2147} 2148 2149void BrowserView::SetBookmarkBarParent(views::View* new_parent) { 2150 if (new_parent == this) { 2151 // Add it underneath |top_container_| or at the end if top container isn't 2152 // found. 2153 int top_container_index = GetIndexOf(top_container_); 2154 if (top_container_index >= 0) 2155 AddChildViewAt(bookmark_bar_view_.get(), top_container_index); 2156 else 2157 AddChildView(bookmark_bar_view_.get()); 2158 } else if (new_parent) { 2159 // No special stacking is required for other parents. 2160 new_parent->AddChildView(bookmark_bar_view_.get()); 2161 } else { 2162 // Bookmark bar is being detached from all views because it is hidden. 2163 bookmark_bar_view_->parent()->RemoveChildView(bookmark_bar_view_.get()); 2164 } 2165} 2166 2167bool BrowserView::MaybeShowInfoBar(WebContents* contents) { 2168 // TODO(beng): Remove this function once the interface between 2169 // InfoBarContainer, DownloadShelfView and WebContents and this 2170 // view is sorted out. 2171 return true; 2172} 2173 2174void BrowserView::UpdateDevToolsForContents(WebContents* web_contents) { 2175 DevToolsWindow* new_devtools_window = web_contents ? 2176 DevToolsWindow::GetDockedInstanceForInspectedTab(web_contents) : NULL; 2177 // Fast return in case of the same window having same orientation. 2178 if (devtools_window_ == new_devtools_window) { 2179 if (!new_devtools_window || 2180 (new_devtools_window->dock_side() == devtools_dock_side_)) { 2181 return; 2182 } 2183 } 2184 2185 // Replace tab contents. 2186 if (devtools_window_ != new_devtools_window) { 2187 devtools_container_->SetWebContents( 2188 new_devtools_window ? new_devtools_window->web_contents() : NULL); 2189 } 2190 2191 // Store last used position. 2192 if (devtools_window_) { 2193 int split_size = contents_split_->GetDividerSize(); 2194 if (devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_RIGHT) { 2195 devtools_window_->SetWidth(contents_split_->width() - 2196 split_size - contents_split_->divider_offset()); 2197 } else if (devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_BOTTOM) { 2198 devtools_window_->SetHeight(contents_split_->height() - 2199 split_size - contents_split_->divider_offset()); 2200 } 2201 } 2202 2203 // Show / hide container if necessary. Changing dock orientation is 2204 // hide + show. 2205 bool should_hide = devtools_window_ && (!new_devtools_window || 2206 devtools_dock_side_ != new_devtools_window->dock_side()); 2207 bool should_show = new_devtools_window && (!devtools_window_ || should_hide); 2208 2209 if (should_hide) 2210 HideDevToolsContainer(); 2211 2212 devtools_window_ = new_devtools_window; 2213 2214 if (should_show) { 2215 devtools_dock_side_ = new_devtools_window->dock_side(); 2216 ShowDevToolsContainer(); 2217 } else if (new_devtools_window) { 2218 UpdateDevToolsSplitPosition(); 2219 contents_split_->Layout(); 2220 } 2221} 2222 2223void BrowserView::ShowDevToolsContainer() { 2224 if (!devtools_focus_tracker_.get()) { 2225 // Install devtools focus tracker when dev tools window is shown for the 2226 // first time. 2227 devtools_focus_tracker_.reset( 2228 new views::ExternalFocusTracker(devtools_container_, 2229 GetFocusManager())); 2230 } 2231 2232 gfx::Size min_devtools_size(devtools_window_->GetMinimumWidth(), 2233 devtools_window_->GetMinimumHeight()); 2234 devtools_container_->SetPreferredSize(min_devtools_size); 2235 2236 devtools_container_->SetVisible(true); 2237 devtools_dock_side_ = devtools_window_->dock_side(); 2238 bool dock_to_right = devtools_dock_side_ == DEVTOOLS_DOCK_SIDE_RIGHT; 2239 contents_split_->set_orientation( 2240 dock_to_right ? views::SingleSplitView::HORIZONTAL_SPLIT 2241 : views::SingleSplitView::VERTICAL_SPLIT); 2242 UpdateDevToolsSplitPosition(); 2243 contents_split_->InvalidateLayout(); 2244 Layout(); 2245} 2246 2247void BrowserView::HideDevToolsContainer() { 2248 // Restore focus to the last focused view when hiding devtools window. 2249 devtools_focus_tracker_->FocusLastFocusedExternalView(); 2250 devtools_container_->SetVisible(false); 2251 contents_split_->InvalidateLayout(); 2252 Layout(); 2253} 2254 2255void BrowserView::UpdateDevToolsSplitPosition() { 2256 contents_split_->set_resize_disabled( 2257 devtools_window_->dock_side() == DEVTOOLS_DOCK_SIDE_MINIMIZED); 2258 int split_size = contents_split_->GetDividerSize(); 2259 if (devtools_window_->dock_side() == DEVTOOLS_DOCK_SIDE_RIGHT) { 2260 int split_offset = contents_split_->width() - split_size - 2261 devtools_window_->GetWidth(contents_split_->width()); 2262 contents_split_->set_divider_offset(split_offset); 2263 } else { 2264 int height = devtools_window_->dock_side() == DEVTOOLS_DOCK_SIDE_MINIMIZED ? 2265 devtools_window_->GetMinimizedHeight() : 2266 devtools_window_->GetHeight(contents_split_->height()); 2267 int split_offset = contents_split_->height() - split_size - height; 2268 contents_split_->set_divider_offset(split_offset); 2269 } 2270} 2271 2272void BrowserView::UpdateUIForContents(WebContents* contents) { 2273 bool needs_layout = MaybeShowBookmarkBar(contents); 2274 // TODO(jamescook): This function always returns true. Remove it and figure 2275 // out when layout is actually required. 2276 needs_layout |= MaybeShowInfoBar(contents); 2277 if (needs_layout) 2278 Layout(); 2279} 2280 2281void BrowserView::ProcessFullscreen(bool fullscreen, 2282 FullscreenType type, 2283 const GURL& url, 2284 FullscreenExitBubbleType bubble_type) { 2285 if (in_process_fullscreen_) 2286 return; 2287 in_process_fullscreen_ = true; 2288 2289 // Reduce jankiness during the following position changes by: 2290 // * Hiding the window until it's in the final position 2291 // * Ignoring all intervening Layout() calls, which resize the webpage and 2292 // thus are slow and look ugly (enforced via |in_process_fullscreen_|). 2293 LocationBarView* location_bar = GetLocationBarView(); 2294#if defined(OS_WIN) && !defined(USE_AURA) 2295 OmniboxViewWin* omnibox_win = 2296 GetOmniboxViewWin(location_bar->GetLocationEntry()); 2297#endif 2298 2299 if (type == FOR_METRO || !fullscreen) { 2300 // Hide the fullscreen bubble as soon as possible, since the mode toggle can 2301 // take enough time for the user to notice. 2302 fullscreen_bubble_.reset(); 2303 } 2304 2305 if (fullscreen) { 2306 // Move focus out of the location bar if necessary. 2307 views::FocusManager* focus_manager = GetFocusManager(); 2308 DCHECK(focus_manager); 2309 // Look for focus in the location bar itself or any child view. 2310 if (location_bar->Contains(focus_manager->GetFocusedView())) 2311 focus_manager->ClearFocus(); 2312 2313#if defined(OS_WIN) && !defined(USE_AURA) 2314 if (omnibox_win) { 2315 // If we don't hide the edit and force it to not show until we come out of 2316 // fullscreen, then if the user was on the New Tab Page, the edit contents 2317 // will appear atop the web contents once we go into fullscreen mode. This 2318 // has something to do with how we move the main window while it's hidden; 2319 // if we don't hide the main window below, we don't get this problem. 2320 omnibox_win->set_force_hidden(true); 2321 ShowWindow(omnibox_win->m_hWnd, SW_HIDE); 2322 } 2323#endif 2324 } 2325#if defined(OS_WIN) && !defined(USE_AURA) 2326 views::ScopedFullscreenVisibility visibility(frame_->GetNativeView()); 2327#endif 2328 2329 if (type == FOR_METRO) { 2330#if defined(OS_WIN) && !defined(USE_AURA) 2331 // Enter metro snap mode. 2332 static_cast<views::NativeWidgetWin*>( 2333 frame_->native_widget())->SetMetroSnapFullscreen(fullscreen); 2334#endif 2335 } else { 2336 // Toggle fullscreen mode. 2337 frame_->SetFullscreen(fullscreen); 2338 } 2339 2340 // Enable immersive before the browser refreshes its list of enabled commands. 2341 if (ShouldUseImmersiveFullscreenForUrl(url)) 2342 immersive_mode_controller_->SetEnabled(fullscreen); 2343 2344 browser_->WindowFullscreenStateChanged(); 2345 2346 if (fullscreen) { 2347 if (!chrome::IsRunningInAppMode() && type != FOR_METRO) 2348 UpdateFullscreenExitBubbleContent(url, bubble_type); 2349 } else { 2350#if defined(OS_WIN) && !defined(USE_AURA) 2351 if (omnibox_win) { 2352 // Show the edit again since we're no longer in fullscreen mode. 2353 omnibox_win->set_force_hidden(false); 2354 ShowWindow(omnibox_win->m_hWnd, SW_SHOW); 2355 } 2356#endif 2357 } 2358 2359 // Undo our anti-jankiness hacks and force a re-layout. We also need to 2360 // recompute the height of the infobar top arrow because toggling in and out 2361 // of fullscreen changes it. Calling ToolbarSizeChanged() will do both these 2362 // things since it computes the arrow height directly and forces a layout 2363 // indirectly via UpdateUIForContents(). Reset |in_process_fullscreen_| in 2364 // order to let the layout occur. 2365 in_process_fullscreen_ = false; 2366 ToolbarSizeChanged(false); 2367} 2368 2369bool BrowserView::ShouldUseImmersiveFullscreenForUrl(const GURL& url) const { 2370#if defined(OS_CHROMEOS) 2371 // Kiosk mode needs the whole screen. 2372 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) 2373 return false; 2374 bool is_browser_fullscreen = url.is_empty(); 2375 return is_browser_fullscreen && IsBrowserTypeNormal(); 2376#else 2377 return false; 2378#endif 2379} 2380 2381void BrowserView::LoadAccelerators() { 2382#if defined(OS_WIN) && !defined(USE_AURA) 2383 HACCEL accelerator_table = AtlLoadAccelerators(IDR_MAINFRAME); 2384 DCHECK(accelerator_table); 2385 2386 // We have to copy the table to access its contents. 2387 int count = CopyAcceleratorTable(accelerator_table, 0, 0); 2388 if (count == 0) { 2389 // Nothing to do in that case. 2390 return; 2391 } 2392 2393 ACCEL* accelerators = static_cast<ACCEL*>(malloc(sizeof(ACCEL) * count)); 2394 CopyAcceleratorTable(accelerator_table, accelerators, count); 2395 2396 views::FocusManager* focus_manager = GetFocusManager(); 2397 DCHECK(focus_manager); 2398 2399 // Let's fill our own accelerator table. 2400 for (int i = 0; i < count; ++i) { 2401 ui::Accelerator accelerator( 2402 static_cast<ui::KeyboardCode>(accelerators[i].key), 2403 ui::GetModifiersFromACCEL(accelerators[i])); 2404 accelerator_table_[accelerator] = accelerators[i].cmd; 2405 2406 // Also register with the focus manager. 2407 focus_manager->RegisterAccelerator( 2408 accelerator, ui::AcceleratorManager::kNormalPriority, this); 2409 } 2410 2411 // We don't need the Windows accelerator table anymore. 2412 free(accelerators); 2413#else 2414 views::FocusManager* focus_manager = GetFocusManager(); 2415 DCHECK(focus_manager); 2416 2417 // Let's fill our own accelerator table. 2418 const bool is_app_mode = chrome::IsRunningInForcedAppMode(); 2419 const std::vector<chrome::AcceleratorMapping> accelerator_list( 2420 chrome::GetAcceleratorList()); 2421 for (std::vector<chrome::AcceleratorMapping>::const_iterator it = 2422 accelerator_list.begin(); it != accelerator_list.end(); ++it) { 2423 // In app mode, only allow accelerators of white listed commands to pass 2424 // through. 2425 if (is_app_mode && !chrome::IsCommandAllowedInAppMode(it->command_id)) 2426 continue; 2427 2428 ui::Accelerator accelerator(it->keycode, it->modifiers); 2429 accelerator_table_[accelerator] = it->command_id; 2430 2431 // Also register with the focus manager. 2432 focus_manager->RegisterAccelerator( 2433 accelerator, ui::AcceleratorManager::kNormalPriority, this); 2434 } 2435#endif 2436} 2437 2438int BrowserView::GetCommandIDForAppCommandID(int app_command_id) const { 2439#if defined(OS_WIN) 2440 switch (app_command_id) { 2441 // NOTE: The order here matches the APPCOMMAND declaration order in the 2442 // Windows headers. 2443 case APPCOMMAND_BROWSER_BACKWARD: return IDC_BACK; 2444 case APPCOMMAND_BROWSER_FORWARD: return IDC_FORWARD; 2445 case APPCOMMAND_BROWSER_REFRESH: return IDC_RELOAD; 2446 case APPCOMMAND_BROWSER_HOME: return IDC_HOME; 2447 case APPCOMMAND_BROWSER_STOP: return IDC_STOP; 2448 case APPCOMMAND_BROWSER_SEARCH: return IDC_FOCUS_SEARCH; 2449 case APPCOMMAND_HELP: return IDC_HELP_PAGE_VIA_KEYBOARD; 2450 case APPCOMMAND_NEW: return IDC_NEW_TAB; 2451 case APPCOMMAND_OPEN: return IDC_OPEN_FILE; 2452 case APPCOMMAND_CLOSE: return IDC_CLOSE_TAB; 2453 case APPCOMMAND_SAVE: return IDC_SAVE_PAGE; 2454 case APPCOMMAND_PRINT: return IDC_PRINT; 2455 case APPCOMMAND_COPY: return IDC_COPY; 2456 case APPCOMMAND_CUT: return IDC_CUT; 2457 case APPCOMMAND_PASTE: return IDC_PASTE; 2458 2459 // TODO(pkasting): http://b/1113069 Handle these. 2460 case APPCOMMAND_UNDO: 2461 case APPCOMMAND_REDO: 2462 case APPCOMMAND_SPELL_CHECK: 2463 default: return -1; 2464 } 2465#else 2466 // App commands are Windows-specific so there's nothing to do here. 2467 return -1; 2468#endif 2469} 2470 2471void BrowserView::InitHangMonitor() { 2472#if defined(OS_WIN) && !defined(USE_AURA) 2473 PrefService* pref_service = g_browser_process->local_state(); 2474 if (!pref_service) 2475 return; 2476 2477 int plugin_message_response_timeout = 2478 pref_service->GetInteger(prefs::kPluginMessageResponseTimeout); 2479 int hung_plugin_detect_freq = 2480 pref_service->GetInteger(prefs::kHungPluginDetectFrequency); 2481 if ((hung_plugin_detect_freq > 0) && 2482 hung_window_detector_.Initialize(GetWidget()->GetNativeView(), 2483 plugin_message_response_timeout)) { 2484 ticker_.set_tick_interval(hung_plugin_detect_freq); 2485 ticker_.RegisterTickHandler(&hung_window_detector_); 2486 ticker_.Start(); 2487 2488 pref_service->SetInteger(prefs::kPluginMessageResponseTimeout, 2489 plugin_message_response_timeout); 2490 pref_service->SetInteger(prefs::kHungPluginDetectFrequency, 2491 hung_plugin_detect_freq); 2492 } 2493#endif 2494} 2495 2496void BrowserView::UpdateAcceleratorMetrics(const ui::Accelerator& accelerator, 2497 int command_id) { 2498 const ui::KeyboardCode key_code = accelerator.key_code(); 2499 if (command_id == IDC_HELP_PAGE_VIA_KEYBOARD && key_code == ui::VKEY_F1) 2500 content::RecordAction(UserMetricsAction("ShowHelpTabViaF1")); 2501 2502 if (command_id == IDC_BOOKMARK_PAGE) 2503 UMA_HISTOGRAM_ENUMERATION("Bookmarks.EntryPoint", 2504 BOOKMARK_ENTRY_POINT_ACCELERATOR, 2505 BOOKMARK_ENTRY_POINT_LIMIT); 2506 2507#if defined(OS_CHROMEOS) 2508 // Collect information about the relative popularity of various accelerators 2509 // on Chrome OS. 2510 switch (command_id) { 2511 case IDC_BACK: 2512 if (key_code == ui::VKEY_BACK) 2513 content::RecordAction(UserMetricsAction("Accel_Back_Backspace")); 2514 else if (key_code == ui::VKEY_BROWSER_BACK) 2515 content::RecordAction(UserMetricsAction("Accel_Back_F1")); 2516 else if (key_code == ui::VKEY_LEFT) 2517 content::RecordAction(UserMetricsAction("Accel_Back_Left")); 2518 break; 2519 case IDC_FORWARD: 2520 if (key_code == ui::VKEY_BACK) 2521 content::RecordAction(UserMetricsAction("Accel_Forward_Backspace")); 2522 else if (key_code == ui::VKEY_BROWSER_FORWARD) 2523 content::RecordAction(UserMetricsAction("Accel_Forward_F2")); 2524 else if (key_code == ui::VKEY_RIGHT) 2525 content::RecordAction(UserMetricsAction("Accel_Forward_Right")); 2526 break; 2527 case IDC_RELOAD: 2528 case IDC_RELOAD_IGNORING_CACHE: 2529 if (key_code == ui::VKEY_R) 2530 content::RecordAction(UserMetricsAction("Accel_Reload_R")); 2531 else if (key_code == ui::VKEY_BROWSER_REFRESH) 2532 content::RecordAction(UserMetricsAction("Accel_Reload_F3")); 2533 break; 2534 case IDC_FOCUS_LOCATION: 2535 if (key_code == ui::VKEY_D) 2536 content::RecordAction(UserMetricsAction("Accel_FocusLocation_D")); 2537 else if (key_code == ui::VKEY_L) 2538 content::RecordAction(UserMetricsAction("Accel_FocusLocation_L")); 2539 break; 2540 case IDC_FOCUS_SEARCH: 2541 if (key_code == ui::VKEY_E) 2542 content::RecordAction(UserMetricsAction("Accel_FocusSearch_E")); 2543 else if (key_code == ui::VKEY_K) 2544 content::RecordAction(UserMetricsAction("Accel_FocusSearch_K")); 2545 break; 2546 default: 2547 // Do nothing. 2548 break; 2549 } 2550#endif 2551} 2552 2553// static 2554BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) { 2555 // Create the view and the frame. The frame will attach itself via the view 2556 // so we don't need to do anything with the pointer. 2557 BrowserView* view = new BrowserView(); 2558 view->Init(browser); 2559 (new BrowserFrame(view))->InitBrowserFrame(); 2560 view->GetWidget()->non_client_view()->SetAccessibleName( 2561 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 2562 return view; 2563} 2564 2565void BrowserView::ShowAvatarBubble(WebContents* web_contents, 2566 const gfx::Rect& rect) { 2567 gfx::Point origin(rect.origin()); 2568 views::View::ConvertPointToScreen(GetTabContentsContainerView(), &origin); 2569 gfx::Rect bounds(origin, rect.size()); 2570 2571 AvatarMenuBubbleView::ShowBubble(this, views::BubbleBorder::TOP_RIGHT, 2572 views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE, bounds, browser_.get()); 2573} 2574 2575void BrowserView::ShowAvatarBubbleFromAvatarButton() { 2576 AvatarMenuButton* button = frame_->GetAvatarMenuButton(); 2577 if (button) 2578 button->ShowAvatarBubble(); 2579} 2580 2581void BrowserView::ShowPasswordGenerationBubble( 2582 const gfx::Rect& rect, 2583 const autofill::PasswordForm& form, 2584 autofill::PasswordGenerator* password_generator) { 2585 // Create a rect in the content bounds that the bubble will point to. 2586 gfx::Point origin(rect.origin()); 2587 views::View::ConvertPointToScreen(GetTabContentsContainerView(), &origin); 2588 gfx::Rect bounds(origin, rect.size()); 2589 2590 // Create the bubble. 2591 WebContents* web_contents = GetActiveWebContents(); 2592 if (!web_contents) 2593 return; 2594 2595 PasswordGenerationBubbleView* bubble = 2596 new PasswordGenerationBubbleView( 2597 form, 2598 bounds, 2599 this, 2600 web_contents->GetRenderViewHost(), 2601 PasswordManager::FromWebContents(web_contents), 2602 password_generator, 2603 browser_.get(), 2604 GetWidget()->GetThemeProvider()); 2605 2606 views::BubbleDelegateView::CreateBubble(bubble); 2607 bubble->SetAlignment(views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR); 2608 bubble->GetWidget()->Show(); 2609} 2610 2611void BrowserView::OverscrollUpdate(int delta_y) { 2612 if (scroll_end_effect_controller_) 2613 scroll_end_effect_controller_->OverscrollUpdate(delta_y); 2614} 2615 2616int BrowserView::GetRenderViewHeightInsetWithDetachedBookmarkBar() { 2617 if (browser_->bookmark_bar_state() != BookmarkBar::DETACHED || 2618 !bookmark_bar_view_.get() || !bookmark_bar_view_->IsDetached()) { 2619 return 0; 2620 } 2621 // Don't use bookmark_bar_view_->height() which won't be the final height if 2622 // the bookmark bar is animating. 2623 return chrome::kNTPBookmarkBarHeight - 2624 bookmark_bar_view_->GetFullyDetachedToolbarOverlap(); 2625} 2626 2627void BrowserView::DoCutCopyPaste(void (content::RenderWidgetHost::*method)(), 2628#if defined(OS_WIN) 2629 int windows_msg_id, 2630#endif 2631 int command_id) { 2632 WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents(); 2633 if (!contents) 2634 return; 2635 if (DoCutCopyPasteForWebContents(contents, method)) 2636 return; 2637 2638 DevToolsWindow* devtools_window = 2639 DevToolsWindow::GetDockedInstanceForInspectedTab(contents); 2640 if (devtools_window && 2641 DoCutCopyPasteForWebContents(devtools_window->web_contents(), method)) { 2642 return; 2643 } 2644 2645 views::FocusManager* focus_manager = GetFocusManager(); 2646 views::View* focused = focus_manager->GetFocusedView(); 2647 if (focused && 2648 (!strcmp(focused->GetClassName(), views::Textfield::kViewClassName) || 2649 !strcmp(focused->GetClassName(), OmniboxViewViews::kViewClassName))) { 2650 views::Textfield* textfield = static_cast<views::Textfield*>(focused); 2651 textfield->ExecuteCommand(command_id); 2652 return; 2653 } 2654 2655#if defined(OS_WIN) && !defined(USE_AURA) 2656 OmniboxView* omnibox_view = GetLocationBarView()->GetLocationEntry(); 2657 if (omnibox_view->model()->has_focus()) { 2658 OmniboxViewWin* omnibox_win = GetOmniboxViewWin(omnibox_view); 2659 ::SendMessage(omnibox_win->GetNativeView(), windows_msg_id, 0, 0); 2660 } 2661#endif 2662} 2663 2664bool BrowserView::DoCutCopyPasteForWebContents( 2665 WebContents* contents, 2666 void (content::RenderWidgetHost::*method)()) { 2667 gfx::NativeView native_view = contents->GetView()->GetContentNativeView(); 2668 if (!native_view) 2669 return false; 2670#if defined(USE_AURA) 2671 if (native_view->HasFocus()) { 2672#elif defined(OS_WIN) 2673 if (native_view == ::GetFocus()) { 2674#endif 2675 (contents->GetRenderViewHost()->*method)(); 2676 return true; 2677 } 2678 2679 return false; 2680} 2681 2682void BrowserView::ActivateAppModalDialog() const { 2683 // If another browser is app modal, flash and activate the modal browser. 2684 AppModalDialog* active_dialog = 2685 AppModalDialogQueue::GetInstance()->active_dialog(); 2686 if (!active_dialog) 2687 return; 2688 2689 Browser* modal_browser = 2690 chrome::FindBrowserWithWebContents(active_dialog->web_contents()); 2691 if (modal_browser && (browser_ != modal_browser)) { 2692 modal_browser->window()->FlashFrame(true); 2693 modal_browser->window()->Activate(); 2694 } 2695 2696 AppModalDialogQueue::GetInstance()->ActivateModalDialog(); 2697} 2698 2699int BrowserView::GetMaxTopInfoBarArrowHeight() { 2700 int top_arrow_height = 0; 2701 // Only show the arrows when not in fullscreen and when there's no omnibox 2702 // popup. 2703 if (!IsFullscreen() && 2704 !GetLocationBar()->GetLocationEntry()->model()->popup_model()->IsOpen()) { 2705 const LocationIconView* location_icon_view = 2706 toolbar_->location_bar()->location_icon_view(); 2707 // The +1 in the next line creates a 1-px gap between icon and arrow tip. 2708 gfx::Point icon_bottom(0, location_icon_view->GetImageBounds().bottom() - 2709 LocationBarView::kIconInternalPadding + 1); 2710 ConvertPointToTarget(location_icon_view, this, &icon_bottom); 2711 gfx::Point infobar_top(0, infobar_container_->GetVerticalOverlap(NULL)); 2712 ConvertPointToTarget(infobar_container_, this, &infobar_top); 2713 top_arrow_height = infobar_top.y() - icon_bottom.y(); 2714 } 2715 return top_arrow_height; 2716} 2717