1 // Copyright (c) 2006-2008 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 <vector> 6 7 #include "chrome/browser/ui/window_sizer.h" 8 #include "base/logging.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 // Some standard monitor sizes (no task bar). 12 static const gfx::Rect tentwentyfour(0, 0, 1024, 768); 13 static const gfx::Rect twelveeighty(0, 0, 1280, 1024); 14 static const gfx::Rect sixteenhundred(0, 0, 1600, 1200); 15 static const gfx::Rect sixteeneighty(0, 0, 1680, 1050); 16 static const gfx::Rect nineteentwenty(0, 0, 1920, 1200); 17 18 // Represents a 1024x768 monitor that is not the primary monitor, arranged to 19 // the immediate left of the primary 1024x768 monitor. 20 static const gfx::Rect left_nonprimary(-1024, 0, 1024, 768); 21 22 // Represents a 1024x768 monitor that is not the primary monitor, arranged to 23 // the immediate right of the primary 1024x768 monitor. 24 static const gfx::Rect right_nonprimary(1024, 0, 1024, 768); 25 26 // Represents a 1024x768 monitor that is not the primary monitor, arranged to 27 // the immediate top of the primary 1024x768 monitor. 28 static const gfx::Rect top_nonprimary(0, -768, 1024, 768); 29 30 // Represents a 1024x768 monitor that is not the primary monitor, arranged to 31 // the immediate bottom of the primary 1024x768 monitor. 32 static const gfx::Rect bottom_nonprimary(0, 768, 1024, 768); 33 34 // The work area for 1024x768 monitors with different taskbar orientations. 35 static const gfx::Rect taskbar_bottom_work_area(0, 0, 1024, 734); 36 static const gfx::Rect taskbar_top_work_area(0, 34, 1024, 734); 37 static const gfx::Rect taskbar_left_work_area(107, 0, 917, 768); 38 static const gfx::Rect taskbar_right_work_area(0, 0, 917, 768); 39 40 static int kWindowTilePixels = WindowSizer::kWindowTilePixels; 41 42 // Testing implementation of WindowSizer::MonitorInfoProvider that we can use 43 // to fake various monitor layouts and sizes. 44 class TestMonitorInfoProvider : public WindowSizer::MonitorInfoProvider { 45 public: 46 TestMonitorInfoProvider() {} 47 virtual ~TestMonitorInfoProvider() {} 48 49 void AddMonitor(const gfx::Rect& bounds, const gfx::Rect& work_area) { 50 DCHECK(bounds.Contains(work_area)); 51 monitor_bounds_.push_back(bounds); 52 work_areas_.push_back(work_area); 53 } 54 55 // Overridden from WindowSizer::MonitorInfoProvider: 56 virtual gfx::Rect GetPrimaryMonitorWorkArea() const { 57 return work_areas_[0]; 58 } 59 60 virtual gfx::Rect GetPrimaryMonitorBounds() const { 61 return monitor_bounds_[0]; 62 } 63 64 virtual gfx::Rect GetMonitorWorkAreaMatching( 65 const gfx::Rect& match_rect) const { 66 return work_areas_[GetMonitorIndexMatchingBounds(match_rect)]; 67 } 68 69 virtual gfx::Point GetBoundsOffsetMatching( 70 const gfx::Rect& match_rect) const { 71 int monitor_index = GetMonitorIndexMatchingBounds(match_rect); 72 gfx::Rect bounds = monitor_bounds_[monitor_index]; 73 const gfx::Rect& work_area = work_areas_[monitor_index]; 74 return gfx::Point(work_area.x() - bounds.x(), work_area.y() - bounds.y()); 75 } 76 77 virtual void UpdateWorkAreas() { } 78 79 private: 80 size_t GetMonitorIndexMatchingBounds(const gfx::Rect& match_rect) const { 81 int max_area = 0; 82 size_t max_area_index = 0; 83 // Loop through all the monitors, finding the one that intersects the 84 // largest area of the supplied match rect. 85 for (size_t i = 0; i < work_areas_.size(); ++i) { 86 gfx::Rect overlap(match_rect.Intersect(work_areas_[i])); 87 int area = overlap.width() * overlap.height(); 88 if (area > max_area) { 89 max_area = area; 90 max_area_index = i; 91 } 92 } 93 return max_area_index; 94 } 95 96 std::vector<gfx::Rect> monitor_bounds_; 97 98 DISALLOW_COPY_AND_ASSIGN(TestMonitorInfoProvider); 99 }; 100 101 // Testing implementation of WindowSizer::StateProvider that we use to fake 102 // persistent storage and existing windows. 103 class TestStateProvider : public WindowSizer::StateProvider { 104 public: 105 TestStateProvider() 106 : persistent_maximized_(false), 107 has_persistent_data_(false), 108 has_last_active_data_(false) { 109 } 110 virtual ~TestStateProvider() {} 111 112 void SetPersistentState(const gfx::Rect& bounds, 113 bool maximized, 114 const gfx::Rect& work_area, 115 bool has_persistent_data) { 116 persistent_bounds_ = bounds; 117 persistent_maximized_ = maximized; 118 persistent_work_area_ = work_area; 119 has_persistent_data_ = has_persistent_data; 120 } 121 122 void SetLastActiveState(const gfx::Rect& bounds, bool has_last_active_data) { 123 last_active_bounds_ = bounds; 124 has_last_active_data_ = has_last_active_data; 125 } 126 127 // Overridden from WindowSizer::StateProvider: 128 virtual bool GetPersistentState(gfx::Rect* bounds, 129 bool* maximized, 130 gfx::Rect* saved_work_area) const { 131 *bounds = persistent_bounds_; 132 *maximized = persistent_maximized_; 133 *saved_work_area = persistent_work_area_; 134 return has_persistent_data_; 135 } 136 137 virtual bool GetLastActiveWindowState(gfx::Rect* bounds) const { 138 *bounds = last_active_bounds_; 139 return has_last_active_data_; 140 } 141 142 private: 143 gfx::Rect persistent_bounds_; 144 bool persistent_maximized_; 145 gfx::Rect persistent_work_area_; 146 bool has_persistent_data_; 147 148 gfx::Rect last_active_bounds_; 149 bool has_last_active_data_; 150 151 DISALLOW_COPY_AND_ASSIGN(TestStateProvider); 152 }; 153 154 // A convenience function to read the window bounds from the window sizer 155 // according to the specified configuration. 156 enum Source { DEFAULT, LAST_ACTIVE, PERSISTED }; 157 static void GetWindowBounds(const gfx::Rect& monitor1_bounds, 158 const gfx::Rect& monitor1_work_area, 159 const gfx::Rect& monitor2_bounds, 160 const gfx::Rect& state, 161 bool maximized, 162 const gfx::Rect& work_area, 163 Source source, 164 gfx::Rect* out_bounds, 165 bool* out_maximized) { 166 TestMonitorInfoProvider* mip = new TestMonitorInfoProvider; 167 mip->AddMonitor(monitor1_bounds, monitor1_work_area); 168 if (!monitor2_bounds.IsEmpty()) 169 mip->AddMonitor(monitor2_bounds, monitor2_bounds); 170 TestStateProvider* sp = new TestStateProvider; 171 if (source == PERSISTED) 172 sp->SetPersistentState(state, maximized, work_area, true); 173 else if (source == LAST_ACTIVE) 174 sp->SetLastActiveState(state, true); 175 WindowSizer sizer(sp, mip); 176 sizer.DetermineWindowBounds(gfx::Rect(), out_bounds, out_maximized); 177 } 178 179 // Test that the window is sized appropriately for the first run experience 180 // where the default window bounds calculation is invoked. 181 TEST(WindowSizerTest, DefaultSizeCase) { 182 { // 4:3 monitor case, 1024x768, no taskbar 183 gfx::Rect window_bounds; 184 bool maximized; 185 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), gfx::Rect(), 186 false, gfx::Rect(), DEFAULT, &window_bounds, &maximized); 187 EXPECT_FALSE(maximized); 188 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 189 1024 - kWindowTilePixels * 2, 190 768 - kWindowTilePixels * 2), 191 window_bounds); 192 } 193 194 { // 4:3 monitor case, 1024x768, taskbar on bottom 195 gfx::Rect window_bounds; 196 bool maximized; 197 GetWindowBounds(tentwentyfour, taskbar_bottom_work_area, gfx::Rect(), 198 gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds, 199 &maximized); 200 EXPECT_FALSE(maximized); 201 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 202 1024 - kWindowTilePixels * 2, 203 (taskbar_bottom_work_area.height() - 204 kWindowTilePixels * 2)), 205 window_bounds); 206 } 207 208 { // 4:3 monitor case, 1024x768, taskbar on right 209 gfx::Rect window_bounds; 210 bool maximized; 211 GetWindowBounds(tentwentyfour, taskbar_right_work_area, gfx::Rect(), 212 gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds, 213 &maximized); 214 EXPECT_FALSE(maximized); 215 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 216 taskbar_right_work_area.width() - kWindowTilePixels*2, 217 768 - kWindowTilePixels * 2), 218 window_bounds); 219 } 220 221 { // 4:3 monitor case, 1024x768, taskbar on left 222 gfx::Rect window_bounds; 223 bool maximized; 224 GetWindowBounds(tentwentyfour, taskbar_left_work_area, gfx::Rect(), 225 gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds, 226 &maximized); 227 EXPECT_FALSE(maximized); 228 EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kWindowTilePixels, 229 kWindowTilePixels, 230 taskbar_left_work_area.width() - kWindowTilePixels * 2, 231 (taskbar_left_work_area.height() - 232 kWindowTilePixels * 2)), 233 window_bounds); 234 } 235 236 { // 4:3 monitor case, 1024x768, taskbar on top 237 gfx::Rect window_bounds; 238 bool maximized; 239 GetWindowBounds(tentwentyfour, taskbar_top_work_area, gfx::Rect(), 240 gfx::Rect(), false, gfx::Rect(), DEFAULT, &window_bounds, 241 &maximized); 242 EXPECT_FALSE(maximized); 243 EXPECT_EQ(gfx::Rect(kWindowTilePixels, 244 taskbar_top_work_area.y() + kWindowTilePixels, 245 1024 - kWindowTilePixels * 2, 246 taskbar_top_work_area.height() - kWindowTilePixels * 2), 247 window_bounds); 248 } 249 250 { // 4:3 monitor case, 1280x1024 251 gfx::Rect window_bounds; 252 bool maximized; 253 GetWindowBounds(twelveeighty, twelveeighty, gfx::Rect(), gfx::Rect(), 254 false, gfx::Rect(), DEFAULT, &window_bounds, &maximized); 255 EXPECT_FALSE(maximized); 256 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 257 1050, 258 1024 - kWindowTilePixels * 2), 259 window_bounds); 260 } 261 262 { // 4:3 monitor case, 1600x1200 263 gfx::Rect window_bounds; 264 bool maximized; 265 GetWindowBounds(sixteenhundred, sixteenhundred, gfx::Rect(), gfx::Rect(), 266 false, gfx::Rect(), DEFAULT, &window_bounds, &maximized); 267 EXPECT_FALSE(maximized); 268 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 269 1050, 270 1200 - kWindowTilePixels * 2), 271 window_bounds); 272 } 273 274 { // 16:10 monitor case, 1680x1050 275 gfx::Rect window_bounds; 276 bool maximized; 277 GetWindowBounds(sixteeneighty, sixteeneighty, gfx::Rect(), gfx::Rect(), 278 false, gfx::Rect(), DEFAULT, &window_bounds, &maximized); 279 EXPECT_FALSE(maximized); 280 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 281 840 - static_cast<int>(kWindowTilePixels * 1.5), 282 1050 - kWindowTilePixels * 2), 283 window_bounds); 284 } 285 286 { // 16:10 monitor case, 1920x1200 287 gfx::Rect window_bounds; 288 bool maximized; 289 GetWindowBounds(nineteentwenty, nineteentwenty, gfx::Rect(), gfx::Rect(), 290 false, gfx::Rect(), DEFAULT, &window_bounds, &maximized); 291 EXPECT_FALSE(maximized); 292 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 293 960 - static_cast<int>(kWindowTilePixels * 1.5), 294 1200 - kWindowTilePixels * 2), 295 window_bounds); 296 } 297 } 298 299 // Test that the next opened window is positioned appropriately given the 300 // bounds of an existing window of the same type. 301 TEST(WindowSizerTest, LastWindowBoundsCase) { 302 { // normal, in the middle of the screen somewhere. 303 gfx::Rect window_bounds; 304 bool maximized = false; 305 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 306 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), 307 false, gfx::Rect(), LAST_ACTIVE, 308 &window_bounds, &maximized); 309 EXPECT_FALSE(maximized); 310 EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, 311 kWindowTilePixels * 2, 500, 400), window_bounds); 312 } 313 314 { // taskbar on top. 315 gfx::Rect window_bounds; 316 bool maximized = false; 317 GetWindowBounds(tentwentyfour, taskbar_top_work_area, gfx::Rect(), 318 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), 319 false, gfx::Rect(), LAST_ACTIVE, 320 &window_bounds, &maximized); 321 EXPECT_FALSE(maximized); 322 EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, 323 std::max(kWindowTilePixels * 2, 324 34 /* toolbar height */), 325 500, 400), window_bounds); 326 } 327 328 { // too small to satisify the minimum visibility condition. 329 gfx::Rect window_bounds; 330 bool maximized = false; 331 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 332 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), 333 false, gfx::Rect(), LAST_ACTIVE, 334 &window_bounds, &maximized); 335 EXPECT_FALSE(maximized); 336 EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, 337 kWindowTilePixels * 2, 338 30 /* not 29 */, 339 30 /* not 29 */), 340 window_bounds); 341 } 342 343 344 { // normal, but maximized 345 gfx::Rect window_bounds; 346 bool maximized = false; 347 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 348 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), 349 true, gfx::Rect(), LAST_ACTIVE, 350 &window_bounds, &maximized); 351 EXPECT_FALSE(maximized); 352 EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, 353 kWindowTilePixels * 2, 500, 400), window_bounds); 354 } 355 } 356 357 // Test that the window opened is sized appropriately given persisted sizes. 358 TEST(WindowSizerTest, PersistedBoundsCase) { 359 { // normal, in the middle of the screen somewhere. 360 gfx::Rect initial_bounds(kWindowTilePixels, kWindowTilePixels, 500, 400); 361 362 gfx::Rect window_bounds; 363 bool maximized; 364 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), initial_bounds, 365 false, gfx::Rect(), PERSISTED, &window_bounds, &maximized); 366 EXPECT_FALSE(maximized); 367 EXPECT_EQ(initial_bounds, window_bounds); 368 } 369 370 { // normal, maximized. 371 gfx::Rect initial_bounds(0, 0, 1024, 768); 372 373 gfx::Rect window_bounds; 374 bool maximized; 375 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), initial_bounds, 376 true, gfx::Rect(), PERSISTED, &window_bounds, &maximized); 377 EXPECT_TRUE(maximized); 378 EXPECT_EQ(initial_bounds, window_bounds); 379 } 380 381 { // normal, on non-primary monitor in negative coords. 382 gfx::Rect initial_bounds(-600, 10, 500, 400); 383 384 gfx::Rect window_bounds; 385 bool maximized; 386 GetWindowBounds(tentwentyfour, tentwentyfour, left_nonprimary, 387 initial_bounds, false, gfx::Rect(), PERSISTED, 388 &window_bounds, &maximized); 389 EXPECT_FALSE(maximized); 390 EXPECT_EQ(initial_bounds, window_bounds); 391 } 392 393 { // normal, on non-primary monitor in negative coords, maximized. 394 gfx::Rect initial_bounds(-1024, 0, 1024, 768); 395 396 gfx::Rect window_bounds; 397 bool maximized; 398 GetWindowBounds(tentwentyfour, tentwentyfour, left_nonprimary, 399 initial_bounds, true, gfx::Rect(), PERSISTED, 400 &window_bounds, &maximized); 401 EXPECT_TRUE(maximized); 402 EXPECT_EQ(initial_bounds, window_bounds); 403 } 404 405 { // Non-primary monitor resoultion has changed, but the monitor still 406 // completely contains the window. 407 408 gfx::Rect initial_bounds(1074, 50, 600, 500); 409 410 gfx::Rect window_bounds; 411 bool maximized; 412 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(1024, 0, 800, 600), 413 initial_bounds, false, right_nonprimary, 414 PERSISTED, &window_bounds, &maximized); 415 EXPECT_FALSE(maximized); 416 EXPECT_EQ(initial_bounds, window_bounds); 417 } 418 419 { // Non-primary monitor resoultion has changed, and the window is partially 420 // off-screen. 421 422 gfx::Rect initial_bounds(1274, 50, 600, 500); 423 424 gfx::Rect window_bounds; 425 bool maximized; 426 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(1024, 0, 800, 600), 427 initial_bounds, false, right_nonprimary, 428 PERSISTED, &window_bounds, &maximized); 429 EXPECT_FALSE(maximized); 430 EXPECT_EQ(gfx::Rect(1224, 50, 600, 500), window_bounds); 431 } 432 433 { // Non-primary monitor resoultion has changed, and the window is now too 434 // large for the monitor. 435 436 gfx::Rect initial_bounds(1274, 50, 900, 700); 437 438 gfx::Rect window_bounds; 439 bool maximized; 440 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(1024, 0, 800, 600), 441 initial_bounds, false, right_nonprimary, 442 PERSISTED, &window_bounds, &maximized); 443 EXPECT_FALSE(maximized); 444 EXPECT_EQ(gfx::Rect(1024, 0, 800, 600), window_bounds); 445 } 446 447 { // width and height too small 448 gfx::Rect window_bounds; 449 bool maximized; 450 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 451 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), 452 false, gfx::Rect(), PERSISTED, 453 &window_bounds, &maximized); 454 EXPECT_FALSE(maximized); 455 EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 456 30 /* not 29 */, 30 /* not 29 */), 457 window_bounds); 458 } 459 460 #if defined(OS_MACOSX) 461 { // Saved state is too tall to possibly be resized. Mac resizers 462 // are at the bottom of the window, and no piece of a window can 463 // be moved higher than the menubar. (Perhaps the user changed 464 // resolution to something smaller before relaunching Chrome?) 465 gfx::Rect window_bounds; 466 bool maximized; 467 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 468 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 30, 5000), 469 false, gfx::Rect(), PERSISTED, 470 &window_bounds, &maximized); 471 EXPECT_FALSE(maximized); 472 EXPECT_EQ(tentwentyfour.height(), window_bounds.height()); 473 } 474 #endif // defined(OS_MACOSX) 475 } 476 477 ////////////////////////////////////////////////////////////////////////////// 478 // The following unittests have different results on Mac/non-Mac because we 479 // reposition windows aggressively on Mac. The *WithAggressiveReposition tests 480 // are run on Mac, and the *WithNonAggressiveRepositioning tests are run on 481 // other platforms. 482 483 #if defined(OS_MACOSX) 484 TEST(WindowSizerTest, LastWindowOffscreenWithAggressiveRepositioning) { 485 { // taskbar on left. The new window overlaps slightly with the taskbar, so 486 // it is moved to be flush with the left edge of the work area. 487 gfx::Rect window_bounds; 488 bool maximized = false; 489 GetWindowBounds(tentwentyfour, taskbar_left_work_area, gfx::Rect(), 490 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), 491 false, gfx::Rect(), LAST_ACTIVE, 492 &window_bounds, &maximized); 493 EXPECT_FALSE(maximized); 494 EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x(), 495 kWindowTilePixels * 2, 500, 400), window_bounds); 496 } 497 498 { // offset would put the new window offscreen at the bottom 499 gfx::Rect window_bounds; 500 bool maximized = false; 501 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 502 gfx::Rect(10, 729, 500, 400), false, gfx::Rect(), 503 LAST_ACTIVE, &window_bounds, &maximized); 504 EXPECT_FALSE(maximized); 505 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 506 0 /* not 729 + kWindowTilePixels */, 507 500, 400), 508 window_bounds); 509 } 510 511 { // offset would put the new window offscreen at the right 512 gfx::Rect window_bounds; 513 bool maximized = false; 514 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 515 gfx::Rect(985, 10, 500, 400), false, gfx::Rect(), 516 LAST_ACTIVE, &window_bounds, &maximized); 517 EXPECT_FALSE(maximized); 518 EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/, 519 10 + kWindowTilePixels, 520 500, 400), 521 window_bounds); 522 } 523 524 { // offset would put the new window offscreen at the bottom right 525 gfx::Rect window_bounds; 526 bool maximized = false; 527 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 528 gfx::Rect(985, 729, 500, 400), false, gfx::Rect(), 529 LAST_ACTIVE, &window_bounds, &maximized); 530 EXPECT_FALSE(maximized); 531 EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/, 532 0 /* not 729 + kWindowTilePixels*/, 533 500, 400), 534 window_bounds); 535 } 536 } 537 538 TEST(WindowSizerTest, PersistedWindowOffscreenWithAggressiveRepositioning) { 539 { // off the left 540 gfx::Rect window_bounds; 541 bool maximized; 542 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 543 gfx::Rect(-471, 50, 500, 400), false, gfx::Rect(), 544 PERSISTED, &window_bounds, &maximized); 545 EXPECT_FALSE(maximized); 546 EXPECT_EQ(gfx::Rect(0 /* not -471 */, 50, 500, 400), window_bounds); 547 } 548 549 { // off the top 550 gfx::Rect window_bounds; 551 bool maximized; 552 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 553 gfx::Rect(50, -370, 500, 400), false, gfx::Rect(), 554 PERSISTED, &window_bounds, &maximized); 555 EXPECT_FALSE(maximized); 556 EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); 557 } 558 559 { // off the right 560 gfx::Rect window_bounds; 561 bool maximized; 562 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 563 gfx::Rect(995, 50, 500, 400), false, gfx::Rect(), 564 PERSISTED, &window_bounds, &maximized); 565 EXPECT_FALSE(maximized); 566 EXPECT_EQ(gfx::Rect(0 /* not 995 */, 50, 500, 400), window_bounds); 567 } 568 569 { // off the bottom 570 gfx::Rect window_bounds; 571 bool maximized; 572 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 573 gfx::Rect(50, 739, 500, 400), false, gfx::Rect(), PERSISTED, 574 &window_bounds, &maximized); 575 EXPECT_FALSE(maximized); 576 EXPECT_EQ(gfx::Rect(50, 0 /* not 739 */, 500, 400), window_bounds); 577 } 578 579 { // off the topleft 580 gfx::Rect window_bounds; 581 bool maximized; 582 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 583 gfx::Rect(-471, -371, 500, 400), false, gfx::Rect(), 584 PERSISTED, &window_bounds, &maximized); 585 EXPECT_FALSE(maximized); 586 EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not -371 */, 500, 400), 587 window_bounds); 588 } 589 590 { // off the topright 591 gfx::Rect window_bounds; 592 bool maximized; 593 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 594 gfx::Rect(995, -371, 500, 400), false, gfx::Rect(), 595 PERSISTED, &window_bounds, &maximized); 596 EXPECT_FALSE(maximized); 597 EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not -371 */, 500, 400), 598 window_bounds); 599 } 600 601 { // off the bottomleft 602 gfx::Rect window_bounds; 603 bool maximized; 604 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 605 gfx::Rect(-471, 739, 500, 400), false, gfx::Rect(), 606 PERSISTED, &window_bounds, &maximized); 607 EXPECT_FALSE(maximized); 608 EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not 739 */, 500, 400), 609 window_bounds); 610 } 611 612 { // off the bottomright 613 gfx::Rect window_bounds; 614 bool maximized; 615 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 616 gfx::Rect(995, 739, 500, 400), false, gfx::Rect(), 617 PERSISTED, &window_bounds, &maximized); 618 EXPECT_FALSE(maximized); 619 EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not 739 */, 500, 400), 620 window_bounds); 621 } 622 623 { // entirely off left 624 gfx::Rect window_bounds; 625 bool maximized; 626 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 627 gfx::Rect(-700, 50, 500, 400), false, gfx::Rect(), 628 PERSISTED, &window_bounds, &maximized); 629 EXPECT_FALSE(maximized); 630 EXPECT_EQ(gfx::Rect(0 /* not -700 */, 50, 500, 400), window_bounds); 631 } 632 633 { // entirely off left (monitor was detached since last run) 634 gfx::Rect window_bounds; 635 bool maximized; 636 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 637 gfx::Rect(-700, 50, 500, 400), false, left_nonprimary, 638 PERSISTED, &window_bounds, &maximized); 639 EXPECT_FALSE(maximized); 640 EXPECT_EQ(gfx::Rect(0, 50, 500, 400), window_bounds); 641 } 642 643 { // entirely off top 644 gfx::Rect window_bounds; 645 bool maximized; 646 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 647 gfx::Rect(50, -500, 500, 400), false, gfx::Rect(), 648 PERSISTED, &window_bounds, &maximized); 649 EXPECT_FALSE(maximized); 650 EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); 651 } 652 653 { // entirely off top (monitor was detached since last run) 654 gfx::Rect window_bounds; 655 bool maximized; 656 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 657 gfx::Rect(50, -500, 500, 400), false, top_nonprimary, 658 PERSISTED, &window_bounds, &maximized); 659 EXPECT_FALSE(maximized); 660 EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); 661 } 662 663 { // entirely off right 664 gfx::Rect window_bounds; 665 bool maximized; 666 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 667 gfx::Rect(1200, 50, 500, 400), false, gfx::Rect(), 668 PERSISTED, &window_bounds, &maximized); 669 EXPECT_FALSE(maximized); 670 EXPECT_EQ(gfx::Rect(0 /* not 1200 */, 50, 500, 400), window_bounds); 671 } 672 673 { // entirely off right (monitor was detached since last run) 674 gfx::Rect window_bounds; 675 bool maximized; 676 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 677 gfx::Rect(1200, 50, 500, 400), false, right_nonprimary, 678 PERSISTED, &window_bounds, &maximized); 679 EXPECT_FALSE(maximized); 680 EXPECT_EQ(gfx::Rect(524 /* not 1200 */, 50, 500, 400), window_bounds); 681 } 682 683 { // entirely off bottom 684 gfx::Rect window_bounds; 685 bool maximized; 686 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 687 gfx::Rect(50, 800, 500, 400), false, gfx::Rect(), PERSISTED, 688 &window_bounds, &maximized); 689 EXPECT_FALSE(maximized); 690 EXPECT_EQ(gfx::Rect(50, 0 /* not 800 */, 500, 400), window_bounds); 691 } 692 693 { // entirely off bottom (monitor was detached since last run) 694 gfx::Rect window_bounds; 695 bool maximized; 696 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 697 gfx::Rect(50, 800, 500, 400), false, bottom_nonprimary, 698 PERSISTED, &window_bounds, &maximized); 699 EXPECT_FALSE(maximized); 700 EXPECT_EQ(gfx::Rect(50, 368 /* not 800 */, 500, 400), window_bounds); 701 } 702 703 { // wider than the screen. off both the left and right 704 gfx::Rect window_bounds; 705 bool maximized; 706 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 707 gfx::Rect(-100, 50, 2000, 400), false, gfx::Rect(), 708 PERSISTED, &window_bounds, &maximized); 709 EXPECT_FALSE(maximized); 710 EXPECT_EQ(gfx::Rect(0 /* not -100 */, 50, 2000, 400), window_bounds); 711 } 712 } 713 #else 714 TEST(WindowSizerTest, LastWindowOffscreenWithNonAggressiveRepositioning) { 715 { // taskbar on left. 716 gfx::Rect window_bounds; 717 bool maximized = false; 718 GetWindowBounds(tentwentyfour, taskbar_left_work_area, gfx::Rect(), 719 gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), 720 false, gfx::Rect(), LAST_ACTIVE, 721 &window_bounds, &maximized); 722 EXPECT_FALSE(maximized); 723 EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, 724 kWindowTilePixels * 2, 500, 400), window_bounds); 725 } 726 727 // Linux does not tile windows, so tile adjustment tests don't make sense. 728 #if !defined(OS_LINUX) 729 { // offset would put the new window offscreen at the bottom but the minimum 730 // visibility condition is barely satisfied without relocation. 731 gfx::Rect window_bounds; 732 bool maximized = false; 733 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 734 gfx::Rect(10, 728, 500, 400), false, gfx::Rect(), 735 LAST_ACTIVE, &window_bounds, &maximized); 736 EXPECT_FALSE(maximized); 737 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 738 500, 400), window_bounds); 739 } 740 741 { // offset would put the new window offscreen at the bottom and the minimum 742 // visibility condition is satisified by relocation. 743 gfx::Rect window_bounds; 744 bool maximized = false; 745 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 746 gfx::Rect(10, 729, 500, 400), false, gfx::Rect(), 747 LAST_ACTIVE, &window_bounds, &maximized); 748 EXPECT_FALSE(maximized); 749 EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738 /* not 739 */, 500, 400), 750 window_bounds); 751 } 752 753 { // offset would put the new window offscreen at the right but the minimum 754 // visibility condition is barely satisfied without relocation. 755 gfx::Rect window_bounds; 756 bool maximized = false; 757 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 758 gfx::Rect(984, 10, 500, 400), false, gfx::Rect(), 759 LAST_ACTIVE, &window_bounds, &maximized); 760 EXPECT_FALSE(maximized); 761 EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400), window_bounds); 762 } 763 764 { // offset would put the new window offscreen at the right and the minimum 765 // visibility condition is satisified by relocation. 766 gfx::Rect window_bounds; 767 bool maximized = false; 768 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 769 gfx::Rect(985, 10, 500, 400), false, gfx::Rect(), 770 LAST_ACTIVE, &window_bounds, &maximized); 771 EXPECT_FALSE(maximized); 772 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 10 + kWindowTilePixels, 773 500, 400), window_bounds); 774 } 775 776 { // offset would put the new window offscreen at the bottom right and the 777 // minimum visibility condition is satisified by relocation. 778 gfx::Rect window_bounds; 779 bool maximized = false; 780 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 781 gfx::Rect(985, 729, 500, 400), false, gfx::Rect(), 782 LAST_ACTIVE, &window_bounds, &maximized); 783 EXPECT_FALSE(maximized); 784 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400), 785 window_bounds); 786 } 787 #endif // !defined(OS_LINUX) 788 } 789 790 TEST(WindowSizerTest, PersistedWindowOffscreenWithNonAggressiveRepositioning) { 791 { // off the left but the minimum visibility condition is barely satisfied 792 // without relocaiton. 793 gfx::Rect initial_bounds(-470, 50, 500, 400); 794 795 gfx::Rect window_bounds; 796 bool maximized; 797 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 798 initial_bounds, false, gfx::Rect(), PERSISTED, 799 &window_bounds, &maximized); 800 EXPECT_FALSE(maximized); 801 EXPECT_EQ(initial_bounds, window_bounds); 802 } 803 804 { // off the left and the minimum visibility condition is satisfied by 805 // relocation. 806 gfx::Rect window_bounds; 807 bool maximized; 808 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 809 gfx::Rect(-471, 50, 500, 400), false, gfx::Rect(), 810 PERSISTED, &window_bounds, &maximized); 811 EXPECT_FALSE(maximized); 812 EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 50, 500, 400), window_bounds); 813 } 814 815 { // off the top 816 gfx::Rect initial_bounds(50, -370, 500, 400); 817 818 gfx::Rect window_bounds; 819 bool maximized; 820 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 821 gfx::Rect(50, -370, 500, 400), false, gfx::Rect(), 822 PERSISTED, &window_bounds, &maximized); 823 EXPECT_FALSE(maximized); 824 EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); 825 } 826 827 { // off the right but the minimum visibility condition is barely satisified 828 // without relocation. 829 gfx::Rect initial_bounds(994, 50, 500, 400); 830 831 gfx::Rect window_bounds; 832 bool maximized; 833 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 834 initial_bounds, false, gfx::Rect(), PERSISTED, 835 &window_bounds, &maximized); 836 EXPECT_FALSE(maximized); 837 EXPECT_EQ(initial_bounds, window_bounds); 838 } 839 840 { // off the right and the minimum visibility condition is satisified by 841 // relocation. 842 gfx::Rect window_bounds; 843 bool maximized; 844 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 845 gfx::Rect(995, 50, 500, 400), false, gfx::Rect(), 846 PERSISTED, &window_bounds, &maximized); 847 EXPECT_FALSE(maximized); 848 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 50, 500, 400), window_bounds); 849 } 850 851 { // off the bottom but the minimum visibility condition is barely satisified 852 // without relocation. 853 gfx::Rect initial_bounds(50, 738, 500, 400); 854 855 gfx::Rect window_bounds; 856 bool maximized; 857 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 858 initial_bounds, false, gfx::Rect(), PERSISTED, 859 &window_bounds, &maximized); 860 EXPECT_FALSE(maximized); 861 EXPECT_EQ(initial_bounds, window_bounds); 862 } 863 864 { // off the bottom and the minimum visibility condition is satisified by 865 // relocation. 866 gfx::Rect window_bounds; 867 bool maximized; 868 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 869 gfx::Rect(50, 739, 500, 400), false, gfx::Rect(), PERSISTED, 870 &window_bounds, &maximized); 871 EXPECT_FALSE(maximized); 872 EXPECT_EQ(gfx::Rect(50, 738 /* not 739 */, 500, 400), window_bounds); 873 } 874 875 { // off the topleft 876 gfx::Rect window_bounds; 877 bool maximized; 878 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 879 gfx::Rect(-471, -371, 500, 400), false, gfx::Rect(), 880 PERSISTED, &window_bounds, &maximized); 881 EXPECT_FALSE(maximized); 882 EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 0, 500, 400), 883 window_bounds); 884 } 885 886 { // off the topright and the minimum visibility condition is satisified by 887 // relocation. 888 gfx::Rect window_bounds; 889 bool maximized; 890 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 891 gfx::Rect(995, -371, 500, 400), false, gfx::Rect(), 892 PERSISTED, &window_bounds, &maximized); 893 EXPECT_FALSE(maximized); 894 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 0, 500, 400), 895 window_bounds); 896 } 897 898 { // off the bottomleft and the minimum visibility condition is satisified by 899 // relocation. 900 gfx::Rect window_bounds; 901 bool maximized; 902 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 903 gfx::Rect(-471, 739, 500, 400), false, gfx::Rect(), 904 PERSISTED, &window_bounds, &maximized); 905 EXPECT_FALSE(maximized); 906 EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 738 /* not 739 */, 500, 400), 907 window_bounds); 908 } 909 910 { // off the bottomright and the minimum visibility condition is satisified by 911 // relocation. 912 gfx::Rect window_bounds; 913 bool maximized; 914 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 915 gfx::Rect(995, 739, 500, 400), false, gfx::Rect(), 916 PERSISTED, &window_bounds, &maximized); 917 EXPECT_FALSE(maximized); 918 EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400), 919 window_bounds); 920 } 921 922 { // entirely off left 923 gfx::Rect window_bounds; 924 bool maximized; 925 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 926 gfx::Rect(-700, 50, 500, 400), false, gfx::Rect(), 927 PERSISTED, &window_bounds, &maximized); 928 EXPECT_FALSE(maximized); 929 EXPECT_EQ(gfx::Rect(-470 /* not -700 */, 50, 500, 400), window_bounds); 930 } 931 932 { // entirely off left (monitor was detached since last run) 933 gfx::Rect window_bounds; 934 bool maximized; 935 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 936 gfx::Rect(-700, 50, 500, 400), false, left_nonprimary, 937 PERSISTED, &window_bounds, &maximized); 938 EXPECT_FALSE(maximized); 939 EXPECT_EQ(gfx::Rect(0, 50, 500, 400), window_bounds); 940 } 941 942 { // entirely off top 943 gfx::Rect window_bounds; 944 bool maximized; 945 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 946 gfx::Rect(50, -500, 500, 400), false, gfx::Rect(), 947 PERSISTED, &window_bounds, &maximized); 948 EXPECT_FALSE(maximized); 949 EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); 950 } 951 952 { // entirely off top (monitor was detached since last run) 953 gfx::Rect window_bounds; 954 bool maximized; 955 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 956 gfx::Rect(50, -500, 500, 400), false, top_nonprimary, 957 PERSISTED, &window_bounds, &maximized); 958 EXPECT_FALSE(maximized); 959 EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); 960 } 961 962 { // entirely off right 963 gfx::Rect window_bounds; 964 bool maximized; 965 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 966 gfx::Rect(1200, 50, 500, 400), false, gfx::Rect(), 967 PERSISTED, &window_bounds, &maximized); 968 EXPECT_FALSE(maximized); 969 EXPECT_EQ(gfx::Rect(994 /* not 1200 */, 50, 500, 400), window_bounds); 970 } 971 972 { // entirely off right (monitor was detached since last run) 973 gfx::Rect window_bounds; 974 bool maximized; 975 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 976 gfx::Rect(1200, 50, 500, 400), false, right_nonprimary, 977 PERSISTED, &window_bounds, &maximized); 978 EXPECT_FALSE(maximized); 979 EXPECT_EQ(gfx::Rect(524, 50, 500, 400), window_bounds); 980 } 981 982 { // entirely off bottom 983 gfx::Rect window_bounds; 984 bool maximized; 985 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 986 gfx::Rect(50, 800, 500, 400), false, gfx::Rect(), PERSISTED, 987 &window_bounds, &maximized); 988 EXPECT_FALSE(maximized); 989 EXPECT_EQ(gfx::Rect(50, 738 /* not 800 */, 500, 400), window_bounds); 990 } 991 992 { // entirely off bottom (monitor was detached since last run) 993 gfx::Rect window_bounds; 994 bool maximized; 995 GetWindowBounds(tentwentyfour, tentwentyfour, gfx::Rect(), 996 gfx::Rect(50, 800, 500, 400), false, bottom_nonprimary, 997 PERSISTED, &window_bounds, &maximized); 998 EXPECT_FALSE(maximized); 999 EXPECT_EQ(gfx::Rect(50, 368, 500, 400), window_bounds); 1000 } 1001 } 1002 #endif //defined(OS_MACOSX) 1003