1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_classifier.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" 12a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/browser/predictors/predictor_database.h" 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/search_engines/template_url_service.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/search_engines/template_url_service_factory.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_view_layout.h" 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/frame/top_container_view.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/infobars/infobar_container_view.h" 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab_strip.h" 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/views/toolbar_view.h" 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/url_constants.h" 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/browser_with_test_window_test.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/scoped_testing_local_state.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/base/testing_browser_process.h" 27a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/test/base/testing_io_thread_state.h" 28a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "content/public/test/test_utils.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "grit/theme_resources.h" 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/controls/single_split_view.h" 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "ui/views/controls/webview/webview.h" 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/input_method/input_method_configuration.h" 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN) 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/views/frame/browser_frame_win.h" 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Tab strip bounds depend on the window frame sizes. 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)gfx::Point ExpectedTabStripOrigin(BrowserView* browser_view) { 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Rect tabstrip_bounds( 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view->frame()->GetBoundsForTabStrip(browser_view->tabstrip())); 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Point tabstrip_origin(tabstrip_bounds.origin()); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) views::View::ConvertPointToTarget(browser_view->parent(), 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view, 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &tabstrip_origin); 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return tabstrip_origin; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Caller owns the returned service. 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedService* CreateTemplateURLService( 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* profile) { 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return new TemplateURLService(static_cast<Profile*>(profile)); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)BrowserContextKeyedService* CreateAutocompleteClassifier( 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) content::BrowserContext* profile) { 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return new AutocompleteClassifier(static_cast<Profile*>(profile)); 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class BrowserViewTest : public BrowserWithTestWindowTest { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserViewTest(); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~BrowserViewTest() {} 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // BrowserWithTestWindowTest overrides: 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() OVERRIDE; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void TearDown() OVERRIDE; 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual TestingProfile* CreateProfile() OVERRIDE; 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual BrowserWindow* CreateBrowserWindow() OVERRIDE; 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void Init(); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserView* browser_view() { return browser_view_; } 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserView* browser_view_; // Not owned. 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ScopedTestingLocalState> local_state_; 86a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch scoped_ptr<predictors::PredictorDatabase> predictor_db_; 87a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch scoped_ptr<chrome::TestingIOThreadState> testing_io_thread_state_; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BrowserViewTest); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BrowserViewTest::BrowserViewTest() 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : browser_view_(NULL) { 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserViewTest::SetUp() { 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Init(); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Memory ownership is tricky here. BrowserView has taken ownership of 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |browser|, so BrowserWithTestWindowTest cannot continue to own it. 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(release_browser()); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void BrowserViewTest::TearDown() { 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Clean up any tabs we opened, otherwise Browser crashes in destruction. 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view_->browser()->tab_strip_model()->CloseAllTabs(); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Ensure the Browser is reset before BrowserWithTestWindowTest cleans up 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // the Profile. 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_view_->GetWidget()->CloseNow(); 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) browser_view_ = NULL; 109a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch content::RunAllPendingInMessageLoop(content::BrowserThread::DB); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) BrowserWithTestWindowTest::TearDown(); 111a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch testing_io_thread_state_.reset(); 112a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch predictor_db_.reset(); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chromeos::input_method::Shutdown(); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) local_state_.reset(NULL); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TestingProfile* BrowserViewTest::CreateProfile() { 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TestingProfile* profile = BrowserWithTestWindowTest::CreateProfile(); 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TemplateURLService is normally NULL during testing. Instant extended 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // needs this service so set a custom factory function. 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TemplateURLServiceFactory::GetInstance()->SetTestingFactory( 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile, &CreateTemplateURLService); 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(jamescook): Eliminate this by introducing a mock toolbar or mock 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // location bar. 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AutocompleteClassifierFactory::GetInstance()->SetTestingFactory( 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile, &CreateAutocompleteClassifier); 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return profile; 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BrowserWindow* BrowserViewTest::CreateBrowserWindow() { 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Allow BrowserWithTestWindowTest to use Browser to create the default 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // BrowserView and BrowserFrame. 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void BrowserViewTest::Init() { 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) local_state_.reset( 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new ScopedTestingLocalState(TestingBrowserProcess::GetGlobal())); 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_CHROMEOS) 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) chromeos::input_method::InitializeForTesting( 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new chromeos::input_method::MockInputMethodManager); 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 145a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch testing_io_thread_state_.reset(new chrome::TestingIOThreadState()); 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserWithTestWindowTest::SetUp(); 147a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch predictor_db_.reset(new predictors::PredictorDatabase(GetProfile())); 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_ = static_cast<BrowserView*>(browser()->window()); 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test basic construction and initialization. 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(BrowserViewTest, BrowserView) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The window is owned by the native widget, not the test class. 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(window()); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |browser_view_| owns the Browser, not the test class. 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser()); 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(browser_view()->browser()); 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Test initial state. 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(browser_view()->IsTabStripVisible()); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser_view()->IsOffTheRecord()); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(IDR_OTR_ICON, browser_view()->GetOTRIconResourceID()); 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser_view()->IsGuestSession()); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser_view()->ShouldShowAvatar()); 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(browser_view()->IsBrowserTypeNormal()); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser_view()->IsFullscreen()); 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser_view()->IsBookmarkBarVisible()); 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(browser_view()->IsBookmarkBarAnimating()); 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Test layout of the top-of-window UI. 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(BrowserViewTest, BrowserViewLayout) { 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BookmarkBarView::DisableAnimationsForTesting(true); 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // |browser_view_| owns the Browser, not the test class. 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Browser* browser = browser_view()->browser(); 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TopContainerView* top_container = browser_view()->top_container(); 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TabStrip* tabstrip = browser_view()->tabstrip(); 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ToolbarView* toolbar = browser_view()->toolbar(); 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) views::SingleSplitView* contents_split = 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view()->GetContentsSplitForTest(); 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) views::WebView* contents_web_view = 18390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view()->GetContentsWebViewForTest(); 18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Start with a single tab open to a normal page. 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AddTab(browser, GURL("about:blank")); 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Verify the view hierarchy. 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(top_container, browser_view()->tabstrip()->parent()); 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(top_container, browser_view()->toolbar()->parent()); 19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(top_container, browser_view()->GetBookmarkBarView()->parent()); 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(browser_view(), browser_view()->infobar_container()->parent()); 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 194ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Find bar host is at the front of the view hierarchy, followed by the top 195ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // container. 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(browser_view()->child_count() - 1, 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) browser_view()->GetIndexOf(browser_view()->find_bar_host_view())); 198ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(browser_view()->child_count() - 2, 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view()->GetIndexOf(top_container)); 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Verify basic layout. 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, top_container->x()); 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, top_container->y()); 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(browser_view()->width(), top_container->width()); 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Tabstrip layout varies based on window frame sizes. 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gfx::Point expected_tabstrip_origin = ExpectedTabStripOrigin(browser_view()); 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(expected_tabstrip_origin.x(), tabstrip->x()); 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(expected_tabstrip_origin.y(), tabstrip->y()); 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, toolbar->x()); 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ( 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tabstrip->bounds().bottom() - 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserViewLayout::kToolbarTabStripVerticalOverlap, 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) toolbar->y()); 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, contents_split->x()); 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(toolbar->bounds().bottom(), contents_split->y()); 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, contents_web_view->x()); 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, contents_web_view->y()); 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Verify bookmark bar visibility. 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BookmarkBarView* bookmark_bar = browser_view()->GetBookmarkBarView(); 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->visible()); 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->IsDetached()); 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR); 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(bookmark_bar->visible()); 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->IsDetached()); 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::ExecuteCommand(browser, IDC_SHOW_BOOKMARK_BAR); 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->visible()); 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->IsDetached()); 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Bookmark bar is reparented to BrowserView on NTP. 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NavigateAndCommitActiveTabWithTitle(browser, 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL(chrome::kChromeUINewTabURL), 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) string16()); 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(bookmark_bar->visible()); 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(bookmark_bar->IsDetached()); 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(browser_view(), bookmark_bar->parent()); 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Find bar host is still at the front of the view hierarchy, followed by 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // the top container. 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(browser_view()->child_count() - 1, 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) browser_view()->GetIndexOf(browser_view()->find_bar_host_view())); 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(browser_view()->child_count() - 2, 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view()->GetIndexOf(top_container)); 24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Bookmark bar layout on NTP. 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(0, bookmark_bar->x()); 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ( 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) tabstrip->bounds().bottom() + 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) toolbar->height() - 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserViewLayout::kToolbarTabStripVerticalOverlap - 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) views::NonClientFrameView::kClientEdgeThickness, 25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bookmark_bar->y()); 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(toolbar->bounds().bottom(), contents_split->y()); 25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Contents view has a "top margin" pushing it below the bookmark bar. 25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(bookmark_bar->height() - 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) views::NonClientFrameView::kClientEdgeThickness, 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) contents_web_view->y()); 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Bookmark bar is parented back to top container on normal page. 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NavigateAndCommitActiveTabWithTitle(browser, 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL("about:blank"), 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) string16()); 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->visible()); 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(bookmark_bar->IsDetached()); 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(top_container, bookmark_bar->parent()); 265ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Top container is still second from front. 266ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch EXPECT_EQ(browser_view()->child_count() - 2, 26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) browser_view()->GetIndexOf(top_container)); 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 26990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BookmarkBarView::DisableAnimationsForTesting(false); 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN) && !defined(USE_AURA) 2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This class provides functionality to test the incognito window/normal window 2757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// switcher button which is added to Windows 8 metro Chrome. 2767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// We create the BrowserView ourselves in the 2777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// BrowserWithTestWindowTest::CreateBrowserWindow function override and add the 2787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// switcher button to the view. We also provide an incognito profile to ensure 2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// that the switcher button is visible. 2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class BrowserViewIncognitoSwitcherTest : public BrowserViewTest { 2817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 2827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Subclass of BrowserView, which overrides the GetRestoreBounds/IsMaximized 2837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // functions to return dummy values. This is needed because we create the 2847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // BrowserView instance ourselves and initialize it with the created Browser 2857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // instance. These functions get called before the underlying Widget is 2867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // initialized which causes a crash while dereferencing a null native_widget_ 2877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // pointer in the Widget class. 2887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) class TestBrowserView : public BrowserView { 2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public: 2907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual ~TestBrowserView() {} 2917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual gfx::Rect GetRestoredBounds() const OVERRIDE { 2937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return gfx::Rect(); 2947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual bool IsMaximized() const OVERRIDE { 2967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 2977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserViewIncognitoSwitcherTest() 3017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : browser_view_(NULL) {} 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void SetUp() OVERRIDE { 3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Init(); 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_->Init(browser()); 3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) (new BrowserFrame(browser_view_))->InitBrowserFrame(); 3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_->SetBounds(gfx::Rect(10, 10, 500, 500)); 3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_->Show(); 3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Memory ownership is tricky here. BrowserView has taken ownership of 3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |browser|, so BrowserWithTestWindowTest cannot continue to own it. 3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(release_browser()); 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual void TearDown() OVERRIDE { 3157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // ok to release the window_ pointer because BrowserViewTest::TearDown 3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // deletes the BrowserView instance created. 3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) release_browser_window(); 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserViewTest::TearDown(); 3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_ = NULL; 3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) virtual BrowserWindow* CreateBrowserWindow() OVERRIDE { 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // We need an incognito profile for the window switcher button to be 3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // visible. 3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // This profile instance is owned by the TestingProfile instance within the 3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // BrowserWithTestWindowTest class. 3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestingProfile* incognito_profile = new TestingProfile(); 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) incognito_profile->set_incognito(true); 3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetProfile()->SetOffTheRecordProfile(incognito_profile); 3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_ = new TestBrowserView(); 3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view_->SetWindowSwitcherButton( 3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) MakeWindowSwitcherButton(NULL, false)); 3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return browser_view_; 3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private: 3387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserView* browser_view_; 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BrowserViewIncognitoSwitcherTest); 3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}; 3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Test whether the windows incognito/normal browser window switcher button 3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// is the event handler for a point within its bounds. The event handler for 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// a point in the View class is dependent on the order in which children are 3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// added to it. This test ensures that we don't regress in the window switcher 3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// functionality when additional children are added to the BrowserView class. 3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(BrowserViewIncognitoSwitcherTest, 3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) BrowserViewIncognitoSwitcherEventHandlerTest) { 3507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |browser_view_| owns the Browser, not the test class. 3517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_FALSE(browser()); 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(browser_view()->browser()); 3537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Test initial state. 3547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_TRUE(browser_view()->IsTabStripVisible()); 3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Validate whether the window switcher button is the target for the position 3567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // passed in. 3577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) gfx::Point switcher_point(browser_view()->window_switcher_button()->x() + 2, 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view()->window_switcher_button()->y()); 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(browser_view()->GetEventHandlerForPoint(switcher_point), 3607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) browser_view()->window_switcher_button()); 3617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 363