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