window_sizer_ash_unittest.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ash/screen_ash.h" 6#include "ash/shell.h" 7#include "ash/test/ash_test_base.h" 8#include "ash/test/test_shell_delegate.h" 9#include "ash/wm/window_resizer.h" 10#include "ash/wm/window_util.h" 11#include "base/compiler_specific.h" 12#include "chrome/browser/ui/browser.h" 13#include "chrome/browser/ui/window_sizer/window_sizer_common_unittest.h" 14#include "chrome/common/chrome_switches.h" 15#include "chrome/test/base/testing_profile.h" 16#include "content/public/test/render_view_test.h" 17#include "testing/gtest/include/gtest/gtest.h" 18#include "ui/aura/client/activation_client.h" 19#include "ui/aura/client/aura_constants.h" 20#include "ui/aura/env.h" 21#include "ui/aura/root_window.h" 22#include "ui/aura/test/test_windows.h" 23 24typedef ash::test::AshTestBase WindowSizerAshTest; 25 26namespace { 27 28// A browser window proxy which is able to associate an aura native window with 29// it. 30class TestBrowserWindowAura : public TestBrowserWindow { 31 public: 32 // |native_window| will still be owned by the caller after the constructor 33 // was called. 34 explicit TestBrowserWindowAura(aura::Window* native_window) 35 : native_window_(native_window) { 36 } 37 virtual ~TestBrowserWindowAura() {} 38 39 // TestBrowserWindow overrides: 40 virtual void Show() OVERRIDE { 41 native_window_->Show(); 42 Activate(); 43 } 44 virtual void Hide() OVERRIDE { 45 native_window_->Hide(); 46 } 47 virtual void Activate() OVERRIDE { 48 GetActivationClient( 49 native_window_->GetRootWindow())->ActivateWindow(native_window_.get()); 50 } 51 virtual gfx::NativeWindow GetNativeWindow() OVERRIDE { 52 return native_window_.get(); 53 } 54 virtual gfx::Rect GetBounds() const OVERRIDE { 55 return native_window_->bounds(); 56 } 57 58 Browser* browser() { return browser_.get(); } 59 60 void CreateBrowser(const Browser::CreateParams& params) { 61 Browser::CreateParams create_params = params; 62 create_params.window = this; 63 browser_.reset(new Browser(create_params)); 64 if (browser_->is_type_tabbed() || browser_->is_app()) 65 ash::wm::SetWindowPositionManaged(native_window_.get(), true); 66 } 67 68 private: 69 scoped_ptr<Browser> browser_; 70 scoped_ptr<aura::Window> native_window_; 71 72 DISALLOW_COPY_AND_ASSIGN(TestBrowserWindowAura); 73}; 74 75int AlignToGridRoundDown(int location, int grid_size) { 76 if (grid_size <= 1 || location % grid_size == 0) 77 return location; 78 return location / grid_size * grid_size; 79} 80 81scoped_ptr<TestBrowserWindowAura> CreateTestBrowserWindow( 82 aura::Window* window, 83 const gfx::Rect& bounds, 84 const Browser::CreateParams& params) { 85 if (!bounds.IsEmpty()) 86 window->SetBounds(bounds); 87 scoped_ptr<TestBrowserWindowAura> browser_window( 88 new TestBrowserWindowAura(window)); 89 browser_window->CreateBrowser(params); 90 return browser_window.Pass(); 91} 92 93} // namespace 94 95// Test that the window is sized appropriately for the first run experience 96// where the default window bounds calculation is invoked. 97TEST_F(WindowSizerAshTest, DefaultSizeCase) { 98 int grid = WindowSizer::kDesktopBorderSize; 99 { // 4:3 monitor case, 1024x768, no taskbar 100 gfx::Rect window_bounds; 101 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), 102 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); 103 EXPECT_EQ(gfx::Rect(WindowSizer::kDesktopBorderSize, 104 WindowSizer::kDesktopBorderSize, 105 1024 - WindowSizer::kDesktopBorderSize * 2, 106 768 - WindowSizer::kDesktopBorderSize), 107 window_bounds); 108 } 109 110 { // 4:3 monitor case, 1024x768, taskbar on bottom 111 gfx::Rect window_bounds; 112 GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), 113 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), 114 &window_bounds); 115 EXPECT_EQ(gfx::Rect(WindowSizer::kDesktopBorderSize, 116 WindowSizer::kDesktopBorderSize, 117 1024 - WindowSizer::kDesktopBorderSize * 2, 118 AlignToGridRoundDown( 119 taskbar_bottom_work_area.height() - 120 WindowSizer::kDesktopBorderSize, grid)), 121 window_bounds); 122 } 123 124 { // 4:3 monitor case, 1024x768, taskbar on right 125 gfx::Rect window_bounds; 126 GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), 127 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), 128 &window_bounds); 129 EXPECT_EQ(gfx::Rect(WindowSizer::kDesktopBorderSize, 130 WindowSizer::kDesktopBorderSize, 131 AlignToGridRoundDown( 132 taskbar_right_work_area.width() - 133 WindowSizer::kDesktopBorderSize * 2, grid), 134 768 - WindowSizer::kDesktopBorderSize), 135 window_bounds); 136 } 137 138 { // 4:3 monitor case, 1024x768, taskbar on left 139 gfx::Rect window_bounds; 140 GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), 141 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), 142 &window_bounds); 143 EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + 144 WindowSizer::kDesktopBorderSize, 145 WindowSizer::kDesktopBorderSize, 146 AlignToGridRoundDown( 147 taskbar_left_work_area.width() - 148 WindowSizer::kDesktopBorderSize * 2, grid), 149 AlignToGridRoundDown( 150 taskbar_left_work_area.height() - 151 WindowSizer::kDesktopBorderSize, grid)), 152 window_bounds); 153 } 154 155 { // 4:3 monitor case, 1024x768, taskbar on top 156 gfx::Rect window_bounds; 157 GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), 158 gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), 159 &window_bounds); 160 EXPECT_EQ(gfx::Rect(WindowSizer::kDesktopBorderSize, 161 taskbar_top_work_area.y() + 162 WindowSizer::kDesktopBorderSize, 163 1024 - WindowSizer::kDesktopBorderSize * 2, 164 AlignToGridRoundDown( 165 taskbar_top_work_area.height() - 166 WindowSizer::kDesktopBorderSize, grid)), 167 window_bounds); 168 } 169 170 { // 4:3 monitor case, 1280x1024 171 gfx::Rect window_bounds; 172 GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), 173 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); 174 EXPECT_EQ(gfx::Rect((1280 - WindowSizer::kMaximumWindowWidth) / 2, 175 WindowSizer::kDesktopBorderSize, 176 WindowSizer::kMaximumWindowWidth, 177 1024 - WindowSizer::kDesktopBorderSize), 178 window_bounds); 179 } 180 181 { // 4:3 monitor case, 1600x1200 182 gfx::Rect window_bounds; 183 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), 184 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); 185 EXPECT_EQ(gfx::Rect((1600 - WindowSizer::kMaximumWindowWidth) / 2, 186 WindowSizer::kDesktopBorderSize, 187 WindowSizer::kMaximumWindowWidth, 188 1200 - WindowSizer::kDesktopBorderSize), 189 window_bounds); 190 } 191 192 { // 16:10 monitor case, 1680x1050 193 gfx::Rect window_bounds; 194 GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), 195 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); 196 EXPECT_EQ(gfx::Rect((1680 - WindowSizer::kMaximumWindowWidth) / 2, 197 WindowSizer::kDesktopBorderSize, 198 WindowSizer::kMaximumWindowWidth, 199 AlignToGridRoundDown( 200 1050 - WindowSizer::kDesktopBorderSize, 201 grid)), 202 window_bounds); 203 } 204 205 { // 16:10 monitor case, 1920x1200 206 gfx::Rect window_bounds; 207 GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), 208 gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); 209 EXPECT_EQ(gfx::Rect((1920 - WindowSizer::kMaximumWindowWidth) / 2, 210 WindowSizer::kDesktopBorderSize, 211 WindowSizer::kMaximumWindowWidth, 212 1200 - WindowSizer::kDesktopBorderSize), 213 window_bounds); 214 } 215} 216 217// Test that the next opened window is positioned appropriately given the 218// bounds of an existing window of the same type. 219TEST_F(WindowSizerAshTest, LastWindowBoundsCase) { 220 { // normal, in the middle of the screen somewhere. 221 gfx::Rect window_bounds; 222 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 223 gfx::Rect(WindowSizer::kDesktopBorderSize, 224 WindowSizer::kDesktopBorderSize, 500, 400), 225 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), 226 &window_bounds); 227 EXPECT_EQ(gfx::Rect(kWindowTilePixels + WindowSizer::kDesktopBorderSize, 228 kWindowTilePixels + WindowSizer::kDesktopBorderSize, 229 500, 400).ToString(), 230 window_bounds.ToString()); 231 } 232 233 { // taskbar on top. 234 gfx::Rect window_bounds; 235 GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), 236 gfx::Rect(WindowSizer::kDesktopBorderSize, 237 WindowSizer::kDesktopBorderSize, 500, 400), 238 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), 239 &window_bounds); 240 EXPECT_EQ(gfx::Rect(kWindowTilePixels + WindowSizer::kDesktopBorderSize, 241 std::max(kWindowTilePixels + 242 WindowSizer::kDesktopBorderSize, 243 34 /* toolbar height */), 244 500, 400).ToString(), window_bounds.ToString()); 245 } 246 247 { // Too small to satisify the minimum visibility condition. 248 gfx::Rect window_bounds; 249 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 250 gfx::Rect(WindowSizer::kDesktopBorderSize, 251 WindowSizer::kDesktopBorderSize, 29, 29), 252 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), 253 &window_bounds); 254 EXPECT_EQ(gfx::Rect(kWindowTilePixels + WindowSizer::kDesktopBorderSize, 255 kWindowTilePixels + WindowSizer::kDesktopBorderSize, 256 30 /* not 29 */, 257 30 /* not 29 */).ToString(), 258 window_bounds.ToString()); 259 } 260 261 262 { // Normal. 263 gfx::Rect window_bounds; 264 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 265 gfx::Rect(WindowSizer::kDesktopBorderSize, 266 WindowSizer::kDesktopBorderSize, 500, 400), 267 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), 268 &window_bounds); 269 EXPECT_EQ(gfx::Rect(kWindowTilePixels + WindowSizer::kDesktopBorderSize, 270 kWindowTilePixels + WindowSizer::kDesktopBorderSize, 271 500, 400).ToString(), 272 window_bounds.ToString()); 273 } 274} 275 276// Test that the window opened is sized appropriately given persisted sizes. 277TEST_F(WindowSizerAshTest, PersistedBoundsCase) { 278 { // normal, in the middle of the screen somewhere. 279 gfx::Rect initial_bounds(WindowSizer::kDesktopBorderSize, 280 WindowSizer::kDesktopBorderSize, 500, 400); 281 282 gfx::Rect window_bounds; 283 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, 284 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); 285 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); 286 } 287 288 { // Normal. 289 gfx::Rect initial_bounds(0, 0, 1024, 768); 290 291 gfx::Rect window_bounds; 292 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, 293 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); 294 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); 295 } 296 297 { // normal, on non-primary monitor in negative coords. 298 gfx::Rect initial_bounds(-600, 10, 500, 400); 299 300 gfx::Rect window_bounds; 301 GetWindowBounds(p1024x768, p1024x768, left_s1024x768, 302 initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(), 303 &window_bounds); 304 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); 305 } 306 307 { // normal, on non-primary monitor in negative coords. 308 gfx::Rect initial_bounds(-1024, 0, 1024, 768); 309 310 gfx::Rect window_bounds; 311 GetWindowBounds(p1024x768, p1024x768, left_s1024x768, 312 initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(), 313 &window_bounds); 314 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); 315 } 316 317 { // Non-primary monitor resoultion has changed, but the monitor still 318 // completely contains the window. 319 320 gfx::Rect initial_bounds(1074, 50, 600, 500); 321 322 gfx::Rect window_bounds; 323 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), 324 initial_bounds, right_s1024x768, PERSISTED, NULL, 325 gfx::Rect(), &window_bounds); 326 EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); 327 } 328 329 { // Non-primary monitor resoultion has changed, and the window is partially 330 // off-screen. 331 332 gfx::Rect initial_bounds(1274, 50, 600, 500); 333 334 gfx::Rect window_bounds; 335 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), 336 initial_bounds, right_s1024x768, PERSISTED, 337 NULL, gfx::Rect(), &window_bounds); 338 EXPECT_EQ("1224,50 600x500", window_bounds.ToString()); 339 } 340 341 { // Non-primary monitor resoultion has changed, and the window is now too 342 // large for the monitor. 343 344 gfx::Rect initial_bounds(1274, 50, 900, 700); 345 346 gfx::Rect window_bounds; 347 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), 348 initial_bounds, right_s1024x768, PERSISTED, 349 NULL, gfx::Rect(), &window_bounds); 350 EXPECT_EQ("1024,0 800x600", window_bounds.ToString()); 351 } 352 353 { // width and height too small 354 gfx::Rect window_bounds; 355 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 356 gfx::Rect(WindowSizer::kDesktopBorderSize, 357 WindowSizer::kDesktopBorderSize, 29, 29), 358 gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); 359 EXPECT_EQ(gfx::Rect(WindowSizer::kDesktopBorderSize, 360 WindowSizer::kDesktopBorderSize, 361 30 /* not 29 */, 30 /* not 29 */).ToString(), 362 window_bounds.ToString()); 363 } 364} 365 366////////////////////////////////////////////////////////////////////////////// 367// The following unittests have different results on Mac/non-Mac because we 368// reposition windows aggressively on Mac. The *WithAggressiveReposition tests 369// are run on Mac, and the *WithNonAggressiveRepositioning tests are run on 370// other platforms. 371 372TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) { 373 { // taskbar on left. 374 gfx::Rect window_bounds; 375 GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), 376 gfx::Rect(WindowSizer::kDesktopBorderSize, 377 WindowSizer::kDesktopBorderSize, 500, 400), 378 gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), 379 &window_bounds); 380 EXPECT_EQ(gfx::Rect(kWindowTilePixels + WindowSizer::kDesktopBorderSize, 381 kWindowTilePixels + WindowSizer::kDesktopBorderSize, 382 500, 400).ToString(), 383 window_bounds.ToString()); 384 } 385 386 { // offset would put the new window offscreen at the bottom but the minimum 387 // visibility condition is barely satisfied without relocation. 388 gfx::Rect window_bounds; 389 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 390 gfx::Rect(10, 728, 500, 400), gfx::Rect(), LAST_ACTIVE, 391 NULL, gfx::Rect(), &window_bounds); 392 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400).ToString(), 393 window_bounds.ToString()); 394 } 395 396 { // offset would put the new window offscreen at the bottom and the minimum 397 // visibility condition is satisified by relocation. 398 gfx::Rect window_bounds; 399 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 400 gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, 401 NULL, gfx::Rect(), &window_bounds); 402 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 403 738 /* not 739 */, 404 500, 405 400).ToString(), 406 window_bounds.ToString()); 407 } 408 409 { // offset would put the new window offscreen at the right but the minimum 410 // visibility condition is barely satisfied without relocation. 411 gfx::Rect window_bounds; 412 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 413 gfx::Rect(984, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, 414 NULL, gfx::Rect(), &window_bounds); 415 EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400).ToString(), 416 window_bounds.ToString()); 417 } 418 419 { // offset would put the new window offscreen at the right and the minimum 420 // visibility condition is satisified by relocation. 421 gfx::Rect window_bounds; 422 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 423 gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, 424 NULL, gfx::Rect(), &window_bounds); 425 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 426 10 + kWindowTilePixels, 427 500, 428 400).ToString(), 429 window_bounds.ToString()); 430 } 431 432 { // offset would put the new window offscreen at the bottom right and the 433 // minimum visibility condition is satisified by relocation. 434 gfx::Rect window_bounds; 435 GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), 436 gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, 437 NULL, gfx::Rect(), &window_bounds); 438 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 439 738 /* not 739 */, 440 500, 441 400).ToString(), 442 window_bounds.ToString()); 443 } 444} 445 446// Test the placement of newly created windows. 447TEST_F(WindowSizerAshTest, PlaceNewWindows) { 448 // Create a browser which we can use to pass into the GetWindowBounds 449 // function. 450 scoped_ptr<TestingProfile> profile(new TestingProfile()); 451 // Creating a popup handler here to make sure it does not interfere with the 452 // existing windows. 453 Browser::CreateParams native_params(profile.get(), 454 chrome::HOST_DESKTOP_TYPE_ASH); 455 scoped_ptr<Browser> browser( 456 chrome::CreateBrowserWithTestWindowForParams(&native_params)); 457 458 // Creating a popup handler here to make sure it does not interfere with the 459 // existing windows. 460 scoped_ptr<BrowserWindow> browser_window(CreateTestBrowserWindow( 461 CreateTestWindowInShellWithId(0), 462 gfx::Rect(16, 32, 640, 320), 463 Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH))); 464 465 // Creating a popup to make sure it does not interfere with the positioning. 466 scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow( 467 CreateTestWindowInShellWithId(1), 468 gfx::Rect(16, 32, 128, 256), 469 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(), 470 chrome::HOST_DESKTOP_TYPE_ASH))); 471 472 // Creating a panel to make sure it does not interfere with the positioning. 473 scoped_ptr<BrowserWindow> browser_panel(CreateTestBrowserWindow( 474 CreateTestWindowInShellWithId(2), 475 gfx::Rect(32, 48, 256, 512), 476 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(), 477 chrome::HOST_DESKTOP_TYPE_ASH))); 478 browser_window->Show(); 479 { // Make sure that popups do not get changed. 480 gfx::Rect window_bounds; 481 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), 482 gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, 483 PERSISTED, browser_popup->browser(), 484 gfx::Rect(), &window_bounds); 485 EXPECT_EQ("50,100 300x150", window_bounds.ToString()); 486 } 487 488 browser_window->Hide(); 489 { // If a window is there but not shown the persisted default should be used. 490 gfx::Rect window_bounds; 491 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), 492 gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, 493 PERSISTED, browser.get(), gfx::Rect(), &window_bounds); 494 EXPECT_EQ("50,100 300x150", window_bounds.ToString()); 495 } 496 497 { // If a window is there but not shown the default should be returned. 498 gfx::Rect window_bounds; 499 GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), 500 gfx::Rect(), bottom_s1600x1200, 501 DEFAULT, browser.get(), gfx::Rect(), &window_bounds); 502 // Note: We need to also take the defaults maximum width into account here 503 // since that might get used if the resolution is too big. 504 EXPECT_EQ(gfx::Rect(std::max(WindowSizer::kDesktopBorderSize, 505 (1600 - WindowSizer::kMaximumWindowWidth) / 2), 506 WindowSizer::kDesktopBorderSize, 507 std::min(WindowSizer::kMaximumWindowWidth, 508 1600 - 2 * WindowSizer::kDesktopBorderSize), 509 1200 - WindowSizer::kDesktopBorderSize).ToString(), 510 window_bounds.ToString()); 511 } 512} 513 514// Test the placement of newly created windows on an empty desktop. 515// This test supplements "PlaceNewWindows" by testing the creation of a newly 516// created browser window on an empty desktop. 517TEST_F(WindowSizerAshTest, PlaceNewBrowserWindowOnEmptyDesktop) { 518 // Create a browser which we can use to pass into the GetWindowBounds 519 // function. 520 scoped_ptr<TestingProfile> profile(new TestingProfile()); 521 Browser::CreateParams native_params(profile.get(), 522 chrome::HOST_DESKTOP_TYPE_ASH); 523 scoped_ptr<Browser> browser( 524 chrome::CreateBrowserWithTestWindowForParams(&native_params)); 525 526 // A common screen size for Chrome OS devices where this behavior is 527 // desirable. 528 const gfx::Rect p1366x768(0, 0, 1366, 768); 529 530 // If there is no previous state the window should get maximized if the 531 // screen is less than or equal to our limit (1366 pixels width). 532 gfx::Rect window_bounds; 533 ui::WindowShowState out_show_state1 = ui::SHOW_STATE_DEFAULT; 534 GetWindowBoundsAndShowState( 535 p1366x768, // The screen resolution. 536 p1366x768, // The monitor work area. 537 gfx::Rect(), // The second monitor. 538 gfx::Rect(), // The (persisted) bounds. 539 p1366x768, // The overall work area. 540 ui::SHOW_STATE_NORMAL, // The persisted show state. 541 ui::SHOW_STATE_DEFAULT, // The last show state. 542 DEFAULT, // No persisted values. 543 browser.get(), // Use this browser. 544 gfx::Rect(), // Don't request valid bounds. 545 &window_bounds, 546 &out_show_state1); 547 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, out_show_state1); 548 549 // If there is a stored coordinate however, that should be taken instead. 550 ui::WindowShowState out_show_state2 = ui::SHOW_STATE_DEFAULT; 551 GetWindowBoundsAndShowState( 552 p1366x768, // The screen resolution. 553 p1366x768, // The monitor work area. 554 gfx::Rect(), // The second monitor. 555 gfx::Rect(50, 100, 300, 150), // The (persisted) bounds. 556 p1366x768, // The overall work area. 557 ui::SHOW_STATE_NORMAL, // The persisted show state. 558 ui::SHOW_STATE_DEFAULT, // The last show state. 559 PERSISTED, // Set the persisted values. 560 browser.get(), // Use this browser. 561 gfx::Rect(), // Don't request valid bounds. 562 &window_bounds, 563 &out_show_state2); 564 EXPECT_EQ(ui::SHOW_STATE_NORMAL, out_show_state2); 565 EXPECT_EQ("50,100 300x150", window_bounds.ToString()); 566 567 // A larger monitor should not trigger auto-maximize. 568 ui::WindowShowState out_show_state3 = ui::SHOW_STATE_DEFAULT; 569 GetWindowBoundsAndShowState( 570 p1600x1200, // The screen resolution. 571 p1600x1200, // The monitor work area. 572 gfx::Rect(), // The second monitor. 573 gfx::Rect(), // The (persisted) bounds. 574 p1600x1200, // The overall work area. 575 ui::SHOW_STATE_NORMAL, // The persisted show state. 576 ui::SHOW_STATE_DEFAULT, // The last show state. 577 DEFAULT, // No persisted values. 578 browser.get(), // Use this browser. 579 gfx::Rect(), // Don't request valid bounds. 580 &window_bounds, 581 &out_show_state3); 582 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, out_show_state3); 583} 584 585#if defined(OS_CHROMEOS) 586#define MAYBE_PlaceNewWindowsOnMultipleDisplays PlaceNewWindowsOnMultipleDisplays 587#else 588// No multiple displays on windows ash. 589#define MAYBE_PlaceNewWindowsOnMultipleDisplays DISABLED_PlaceNewWindowsOnMultipleDisplays 590#endif 591 592// Test the placement of newly created windows on multiple dislays. 593TEST_F(WindowSizerAshTest, MAYBE_PlaceNewWindowsOnMultipleDisplays) { 594 UpdateDisplay("1600x1200,1600x1200"); 595 gfx::Rect primary_bounds = ash::Shell::GetInstance()->GetScreen()-> 596 GetPrimaryDisplay().bounds(); 597 gfx::Rect secondary_bounds = ash::ScreenAsh::GetSecondaryDisplay().bounds(); 598 599 ash::Shell::GetInstance()->set_active_root_window( 600 ash::Shell::GetPrimaryRootWindow()); 601 602 scoped_ptr<TestingProfile> profile(new TestingProfile()); 603 604 // Create browser windows that are used as reference. 605 scoped_ptr<BrowserWindow> browser_window(CreateTestBrowserWindow( 606 CreateTestWindowInShellWithId(0), 607 gfx::Rect(10, 10, 200, 200), 608 Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH))); 609 browser_window->Show(); 610 EXPECT_EQ(browser_window->GetNativeWindow()->GetRootWindow(), 611 ash::Shell::GetActiveRootWindow()); 612 613 scoped_ptr<BrowserWindow> another_browser_window(CreateTestBrowserWindow( 614 CreateTestWindowInShellWithId(1), 615 gfx::Rect(400, 10, 300, 300), 616 Browser::CreateParams(profile.get(), chrome::HOST_DESKTOP_TYPE_ASH))); 617 another_browser_window->Show(); 618 619 // Creating a new window to verify the new placement. 620 scoped_ptr<TestBrowserWindowAura> new_browser_window(CreateTestBrowserWindow( 621 CreateTestWindowInShellWithId(0), 622 gfx::Rect(), 623 Browser::CreateParams(profile.get(), 624 chrome::HOST_DESKTOP_TYPE_ASH))); 625 626 // Make sure the primary root is active. 627 ASSERT_EQ(ash::Shell::GetPrimaryRootWindow(), 628 ash::Shell::GetActiveRootWindow()); 629 630 // First new window should be in the primary. 631 { 632 gfx::Rect window_bounds; 633 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, 634 gfx::Rect(), secondary_bounds, 635 PERSISTED, new_browser_window->browser(), 636 gfx::Rect(), &window_bounds); 637 // TODO(oshima): Use exact bounds when the window_sizer_ash is 638 // moved to ash and changed to include the result from 639 // RearrangeVisibleWindowOnShow. 640 EXPECT_TRUE(primary_bounds.Contains(window_bounds)); 641 } 642 643 // Move the window to the right side of the secondary display and create a new 644 // window. It should be opened then on the secondary display. 645 { 646 gfx::Display second_display = ash::Shell::GetScreen()-> 647 GetDisplayNearestPoint(gfx::Point(1600 + 100,10)); 648 browser_window->GetNativeWindow()->SetBoundsInScreen( 649 gfx::Rect(secondary_bounds.CenterPoint().x() - 100, 10, 200, 200), 650 second_display); 651 browser_window->Activate(); 652 EXPECT_NE(ash::Shell::GetPrimaryRootWindow(), 653 ash::Shell::GetActiveRootWindow()); 654 gfx::Rect window_bounds; 655 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, 656 gfx::Rect(), secondary_bounds, 657 PERSISTED, new_browser_window->browser(), 658 gfx::Rect(), &window_bounds); 659 // TODO(oshima): Use exact bounds when the window_sizer_ash is 660 // moved to ash and changed to include the result from 661 // RearrangeVisibleWindowOnShow. 662 EXPECT_TRUE(secondary_bounds.Contains(window_bounds)); 663 } 664 665 // Activate another window in the primary display and create a new window. 666 // It should be created in the primary display. 667 { 668 another_browser_window->Activate(); 669 EXPECT_EQ(ash::Shell::GetPrimaryRootWindow(), 670 ash::Shell::GetActiveRootWindow()); 671 672 gfx::Rect window_bounds; 673 GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, 674 gfx::Rect(), secondary_bounds, 675 PERSISTED, new_browser_window->browser(), 676 gfx::Rect(), &window_bounds); 677 // TODO(oshima): Use exact bounds when the window_sizer_ash is 678 // moved to ash and changed to include the result from 679 // RearrangeVisibleWindowOnShow. 680 EXPECT_TRUE(primary_bounds.Contains(window_bounds)); 681 } 682} 683 684// Test that the show state is properly returned for non default cases. 685TEST_F(WindowSizerAshTest, TestShowState) { 686 scoped_ptr<TestingProfile> profile(new TestingProfile()); 687 688 // Creating a browser & window to play with. 689 scoped_ptr<TestBrowserWindowAura> browser_window(CreateTestBrowserWindow( 690 CreateTestWindowInShellWithId(0), 691 gfx::Rect(16, 32, 640, 320), 692 Browser::CreateParams(Browser::TYPE_TABBED, profile.get(), 693 chrome::HOST_DESKTOP_TYPE_ASH))); 694 695 // Create also a popup browser since that behaves different. 696 scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow( 697 CreateTestWindowInShellWithId(1), 698 gfx::Rect(16, 32, 640, 320), 699 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(), 700 chrome::HOST_DESKTOP_TYPE_ASH))); 701 702 // Tabbed windows should retrieve the saved window state - since there is a 703 // top window. 704 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, 705 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 706 ui::SHOW_STATE_NORMAL, 707 BOTH, 708 browser_window->browser(), 709 p1600x1200)); 710 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, 711 GetWindowShowState(ui::SHOW_STATE_DEFAULT, 712 ui::SHOW_STATE_NORMAL, 713 BOTH, 714 browser_window->browser(), 715 p1600x1200)); 716 // Non tabbed windows should always follow the window saved visibility state. 717 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, 718 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 719 ui::SHOW_STATE_NORMAL, 720 BOTH, 721 browser_popup->browser(), 722 p1600x1200)); 723 // The non tabbed window will take the status of the last active of its kind. 724 EXPECT_EQ(ui::SHOW_STATE_NORMAL, 725 GetWindowShowState(ui::SHOW_STATE_DEFAULT, 726 ui::SHOW_STATE_NORMAL, 727 BOTH, 728 browser_popup->browser(), 729 p1600x1200)); 730 731 // Now create a top level window and check again for both. Only the tabbed 732 // window should follow the top level window's state. 733 // Creating a browser & window to play with. 734 scoped_ptr<TestBrowserWindowAura> browser_window2(CreateTestBrowserWindow( 735 CreateTestWindowInShellWithId(3), 736 gfx::Rect(16, 32, 640, 320), 737 Browser::CreateParams(Browser::TYPE_TABBED, profile.get(), 738 chrome::HOST_DESKTOP_TYPE_ASH))); 739 740 // A tabbed window should now take the top level window state. 741 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, 742 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 743 ui::SHOW_STATE_DEFAULT, 744 BOTH, 745 browser_window->browser(), 746 p1600x1200)); 747 // Non tabbed windows should always follow the window saved visibility state. 748 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, 749 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 750 ui::SHOW_STATE_MINIMIZED, 751 BOTH, 752 browser_popup->browser(), 753 p1600x1200)); 754 755 // In smaller screen resolutions we default to maximized if there is no other 756 // window visible. 757 int min_size = WindowSizer::GetForceMaximizedWidthLimit() / 2; 758 if (min_size > 0) { 759 const gfx::Rect tiny_screen(0, 0, min_size, min_size); 760 EXPECT_EQ(ui::SHOW_STATE_DEFAULT, 761 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 762 ui::SHOW_STATE_DEFAULT, 763 BOTH, 764 browser_window->browser(), 765 tiny_screen)); 766 browser_window->Hide(); 767 EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, 768 GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 769 ui::SHOW_STATE_DEFAULT, 770 BOTH, 771 browser_window2->browser(), 772 tiny_screen)); 773 774 } 775} 776 777// Test that the default show state override behavior is properly handled. 778TEST_F(WindowSizerAshTest, TestShowStateDefaults) { 779 // Creating a browser & window to play with. 780 scoped_ptr<TestingProfile> profile(new TestingProfile()); 781 782 scoped_ptr<TestBrowserWindowAura> browser_window(CreateTestBrowserWindow( 783 CreateTestWindowInShellWithId(0), 784 gfx::Rect(16, 32, 640, 320), 785 Browser::CreateParams(Browser::TYPE_TABBED, profile.get(), 786 chrome::HOST_DESKTOP_TYPE_ASH))); 787 788 // Create also a popup browser since that behaves slightly different for 789 // defaults. 790 scoped_ptr<TestBrowserWindowAura> browser_popup(CreateTestBrowserWindow( 791 CreateTestWindowInShellWithId(1), 792 gfx::Rect(16, 32, 128, 256), 793 Browser::CreateParams(Browser::TYPE_POPUP, profile.get(), 794 chrome::HOST_DESKTOP_TYPE_ASH))); 795 796 // Check that a browser creation state always get used if not given as 797 // SHOW_STATE_DEFAULT. 798 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 799 ui::SHOW_STATE_MAXIMIZED, 800 DEFAULT, 801 browser_window->browser(), 802 p1600x1200), ui::SHOW_STATE_DEFAULT); 803 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_MINIMIZED); 804 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 805 ui::SHOW_STATE_MAXIMIZED, 806 BOTH, 807 browser_window->browser(), 808 p1600x1200), ui::SHOW_STATE_MINIMIZED); 809 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_NORMAL); 810 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, 811 ui::SHOW_STATE_MAXIMIZED, 812 BOTH, 813 browser_window->browser(), 814 p1600x1200), ui::SHOW_STATE_NORMAL); 815 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_MAXIMIZED); 816 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, 817 ui::SHOW_STATE_NORMAL, 818 BOTH, 819 browser_window->browser(), 820 p1600x1200), ui::SHOW_STATE_MAXIMIZED); 821 822 // Check that setting the maximized command line option is forcing the 823 // maximized state. 824 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kStartMaximized); 825 826 browser_window->browser()->set_initial_show_state(ui::SHOW_STATE_NORMAL); 827 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, 828 ui::SHOW_STATE_NORMAL, 829 BOTH, 830 browser_window->browser(), 831 p1600x1200), ui::SHOW_STATE_MAXIMIZED); 832 833 // The popup should favor the initial show state over the command line. 834 EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, 835 ui::SHOW_STATE_NORMAL, 836 BOTH, 837 browser_popup->browser(), 838 p1600x1200), ui::SHOW_STATE_NORMAL); 839} 840