| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/accessibility_delegate.h" | 5 #include "ash/accessibility_delegate.h" |
| 6 #include "ash/drag_drop/drag_drop_controller.h" | 6 #include "ash/drag_drop/drag_drop_controller.h" |
| 7 #include "ash/root_window_controller.h" | 7 #include "ash/root_window_controller.h" |
| 8 #include "ash/screen_util.h" | 8 #include "ash/screen_util.h" |
| 9 #include "ash/shelf/shelf.h" | 9 #include "ash/shelf/shelf.h" |
| 10 #include "ash/shelf/shelf_widget.h" | 10 #include "ash/shelf/shelf_widget.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 namespace { | 47 namespace { |
| 48 | 48 |
| 49 class NonActivatableActivationDelegate | 49 class NonActivatableActivationDelegate |
| 50 : public aura::client::ActivationDelegate { | 50 : public aura::client::ActivationDelegate { |
| 51 public: | 51 public: |
| 52 virtual bool ShouldActivate() const OVERRIDE { | 52 virtual bool ShouldActivate() const OVERRIDE { |
| 53 return false; | 53 return false; |
| 54 } | 54 } |
| 55 }; | 55 }; |
| 56 | 56 |
| 57 bool IsWindowAbove(aura::Window* w1, aura::Window* w2) { | |
| 58 aura::Window* parent = w1->parent(); | |
| 59 DCHECK_EQ(parent, w2->parent()); | |
| 60 for (aura::Window::Windows::const_iterator iter = parent->children().begin(); | |
| 61 iter != parent->children().end(); ++iter) { | |
| 62 if (*iter == w1) | |
| 63 return false; | |
| 64 if (*iter == w2) | |
| 65 return true; | |
| 66 } | |
| 67 NOTREACHED(); | |
| 68 return false; | |
| 69 } | |
| 70 | |
| 71 aura::Window* GetWindowByName(aura::Window* container, | |
| 72 const std::string& name) { | |
| 73 aura::Window* window = NULL; | |
| 74 for (aura::Window::Windows::const_iterator iter = | |
| 75 container->children().begin(); iter != container->children().end(); | |
| 76 ++iter) { | |
| 77 if ((*iter)->name() == name) { | |
| 78 // The name should be unique. | |
| 79 DCHECK(!window); | |
| 80 window = *iter; | |
| 81 } | |
| 82 } | |
| 83 return window; | |
| 84 } | |
| 85 | |
| 86 // Returns the copy of |window| created for overview. It is found using the | |
| 87 // window name which should be the same as the source window's name with a | |
| 88 // special suffix, and in the same container as the source window. | |
| 89 aura::Window* GetCopyWindow(aura::Window* window) { | |
| 90 aura::Window* copy_window = NULL; | |
| 91 std::string copy_name = window->name() + " (Copy)"; | |
| 92 std::vector<aura::Window*> containers( | |
| 93 Shell::GetContainersFromAllRootWindows(window->parent()->id(), NULL)); | |
| 94 for (std::vector<aura::Window*>::iterator iter = containers.begin(); | |
| 95 iter != containers.end(); ++iter) { | |
| 96 aura::Window* found = GetWindowByName(*iter, copy_name); | |
| 97 if (found) { | |
| 98 // There should only be one copy window. | |
| 99 DCHECK(!copy_window); | |
| 100 copy_window = found; | |
| 101 } | |
| 102 } | |
| 103 return copy_window; | |
| 104 } | |
| 105 | |
| 106 void CancelDrag(DragDropController* controller, bool* canceled) { | 57 void CancelDrag(DragDropController* controller, bool* canceled) { |
| 107 if (controller->IsDragDropInProgress()) { | 58 if (controller->IsDragDropInProgress()) { |
| 108 *canceled = true; | 59 *canceled = true; |
| 109 controller->DragCancel(); | 60 controller->DragCancel(); |
| 110 } | 61 } |
| 111 } | 62 } |
| 112 | 63 |
| 113 } // namespace | 64 } // namespace |
| 114 | 65 |
| 115 class WindowSelectorTest : public test::AshTestBase { | 66 class WindowSelectorTest : public test::AshTestBase { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) { | 100 bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) { |
| 150 gfx::RectF window1_bounds = GetTransformedTargetBounds(window1); | 101 gfx::RectF window1_bounds = GetTransformedTargetBounds(window1); |
| 151 gfx::RectF window2_bounds = GetTransformedTargetBounds(window2); | 102 gfx::RectF window2_bounds = GetTransformedTargetBounds(window2); |
| 152 return window1_bounds.Intersects(window2_bounds); | 103 return window1_bounds.Intersects(window2_bounds); |
| 153 } | 104 } |
| 154 | 105 |
| 155 void ToggleOverview() { | 106 void ToggleOverview() { |
| 156 ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview(); | 107 ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview(); |
| 157 } | 108 } |
| 158 | 109 |
| 159 void Cycle(WindowSelector::Direction direction) { | |
| 160 ash::Shell::GetInstance()->window_selector_controller()-> | |
| 161 HandleCycleWindow(direction); | |
| 162 } | |
| 163 | |
| 164 void StopCycling() { | |
| 165 ash::Shell::GetInstance()->window_selector_controller()->window_selector_-> | |
| 166 SelectWindow(); | |
| 167 } | |
| 168 | |
| 169 void FireOverviewStartTimer() { | |
| 170 // Calls the method to start overview mode which is normally called by the | |
| 171 // timer. The timer will still fire and call this method triggering the | |
| 172 // DCHECK that overview mode was not already started, except that we call | |
| 173 // StopCycling before the timer has a chance to fire. | |
| 174 ash::Shell::GetInstance()->window_selector_controller()->window_selector_-> | |
| 175 StartOverview(); | |
| 176 } | |
| 177 | |
| 178 gfx::Transform GetTransformRelativeTo(gfx::PointF origin, | 110 gfx::Transform GetTransformRelativeTo(gfx::PointF origin, |
| 179 const gfx::Transform& transform) { | 111 const gfx::Transform& transform) { |
| 180 gfx::Transform t; | 112 gfx::Transform t; |
| 181 t.Translate(origin.x(), origin.y()); | 113 t.Translate(origin.x(), origin.y()); |
| 182 t.PreconcatTransform(transform); | 114 t.PreconcatTransform(transform); |
| 183 t.Translate(-origin.x(), -origin.y()); | 115 t.Translate(-origin.x(), -origin.y()); |
| 184 return t; | 116 return t; |
| 185 } | 117 } |
| 186 | 118 |
| 187 gfx::RectF GetTransformedBounds(aura::Window* window) { | 119 gfx::RectF GetTransformedBounds(aura::Window* window) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); | 267 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); |
| 336 EXPECT_FALSE(panel1->IsVisible()); | 268 EXPECT_FALSE(panel1->IsVisible()); |
| 337 | 269 |
| 338 // Entering overview and selecting another window, the previous window remains | 270 // Entering overview and selecting another window, the previous window remains |
| 339 // fullscreen. | 271 // fullscreen. |
| 340 // TODO(flackr): Currently the panel remains hidden, but should become visible | 272 // TODO(flackr): Currently the panel remains hidden, but should become visible |
| 341 // again. | 273 // again. |
| 342 ToggleOverview(); | 274 ToggleOverview(); |
| 343 ClickWindow(window2.get()); | 275 ClickWindow(window2.get()); |
| 344 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); | 276 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); |
| 345 | |
| 346 // Verify that selecting the panel will make it visible. | |
| 347 // TODO(flackr): Click on panel rather than cycle to it when | |
| 348 // clicking on panels is fixed, see http://crbug.com/339834. | |
| 349 Cycle(WindowSelector::FORWARD); | |
| 350 Cycle(WindowSelector::FORWARD); | |
| 351 StopCycling(); | |
| 352 EXPECT_TRUE(wm::GetWindowState(panel1.get())->IsActive()); | |
| 353 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen()); | |
| 354 EXPECT_TRUE(panel1->IsVisible()); | |
| 355 } | 277 } |
| 356 | 278 |
| 357 // Tests that the shelf dimming state is removed while in overview and restored | 279 // Tests that the shelf dimming state is removed while in overview and restored |
| 358 // on exiting overview. | 280 // on exiting overview. |
| 359 TEST_F(WindowSelectorTest, OverviewUndimsShelf) { | 281 TEST_F(WindowSelectorTest, OverviewUndimsShelf) { |
| 360 gfx::Rect bounds(0, 0, 400, 400); | 282 gfx::Rect bounds(0, 0, 400, 400); |
| 361 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | 283 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| 362 wm::WindowState* window_state = wm::GetWindowState(window1.get()); | 284 wm::WindowState* window_state = wm::GetWindowState(window1.get()); |
| 363 window_state->Maximize(); | 285 window_state->Maximize(); |
| 364 ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf(); | 286 ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf(); |
| 365 EXPECT_TRUE(shelf->GetDimsShelf()); | 287 EXPECT_TRUE(shelf->GetDimsShelf()); |
| 366 ToggleOverview(); | 288 ToggleOverview(); |
| 367 EXPECT_FALSE(shelf->GetDimsShelf()); | 289 EXPECT_FALSE(shelf->GetDimsShelf()); |
| 368 ToggleOverview(); | 290 ToggleOverview(); |
| 369 EXPECT_TRUE(shelf->GetDimsShelf()); | 291 EXPECT_TRUE(shelf->GetDimsShelf()); |
| 370 } | 292 } |
| 371 | 293 |
| 372 // Tests that beginning window selection hides the app list. | 294 // Tests that beginning window selection hides the app list. |
| 373 TEST_F(WindowSelectorTest, SelectingHidesAppList) { | 295 TEST_F(WindowSelectorTest, SelectingHidesAppList) { |
| 374 gfx::Rect bounds(0, 0, 400, 400); | 296 gfx::Rect bounds(0, 0, 400, 400); |
| 375 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | 297 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| 376 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | 298 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); |
| 377 Shell::GetInstance()->ToggleAppList(NULL); | 299 Shell::GetInstance()->ToggleAppList(NULL); |
| 378 EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility()); | 300 EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility()); |
| 379 ToggleOverview(); | 301 ToggleOverview(); |
| 380 EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility()); | 302 EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility()); |
| 381 ToggleOverview(); | 303 ToggleOverview(); |
| 382 | |
| 383 // The app list uses an animation to fade out. If it is toggled on immediately | |
| 384 // after being removed the old widget is re-used and it does not gain focus. | |
| 385 // When running under normal circumstances this shouldn't be possible, but | |
| 386 // it is in a test without letting the message loop run. | |
| 387 RunAllPendingInMessageLoop(); | |
| 388 | |
| 389 Shell::GetInstance()->ToggleAppList(NULL); | |
| 390 EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility()); | |
| 391 Cycle(WindowSelector::FORWARD); | |
| 392 EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility()); | |
| 393 StopCycling(); | |
| 394 } | 304 } |
| 395 | 305 |
| 396 // Tests that a minimized window's visibility and layer visibility is correctly | 306 // Tests that a minimized window's visibility and layer visibility is correctly |
| 397 // changed when entering overview and restored when leaving overview mode. | 307 // changed when entering overview and restored when leaving overview mode. |
| 398 TEST_F(WindowSelectorTest, MinimizedWindowVisibility) { | 308 TEST_F(WindowSelectorTest, MinimizedWindowVisibility) { |
| 399 gfx::Rect bounds(0, 0, 400, 400); | 309 gfx::Rect bounds(0, 0, 400, 400); |
| 400 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | 310 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| 401 wm::WindowState* window_state = wm::GetWindowState(window1.get()); | 311 wm::WindowState* window_state = wm::GetWindowState(window1.get()); |
| 402 window_state->Minimize(); | 312 window_state->Minimize(); |
| 403 EXPECT_FALSE(window1->IsVisible()); | 313 EXPECT_FALSE(window1->IsVisible()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 427 window->SetBounds(gfx::Rect(200, 0, 200, 200)); | 337 window->SetBounds(gfx::Rect(200, 0, 200, 200)); |
| 428 gfx::Rect new_overview_bounds = | 338 gfx::Rect new_overview_bounds = |
| 429 ToEnclosingRect(GetTransformedTargetBounds(window.get())); | 339 ToEnclosingRect(GetTransformedTargetBounds(window.get())); |
| 430 EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x()); | 340 EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x()); |
| 431 EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y()); | 341 EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y()); |
| 432 EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width()); | 342 EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width()); |
| 433 EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height()); | 343 EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height()); |
| 434 ToggleOverview(); | 344 ToggleOverview(); |
| 435 } | 345 } |
| 436 | 346 |
| 437 // Tests entering overview mode with three windows and cycling through them. | |
| 438 TEST_F(WindowSelectorTest, BasicCycle) { | |
| 439 gfx::Rect bounds(0, 0, 400, 400); | |
| 440 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 441 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 442 scoped_ptr<aura::Window> window3(CreateWindow(bounds)); | |
| 443 wm::ActivateWindow(window3.get()); | |
| 444 wm::ActivateWindow(window2.get()); | |
| 445 wm::ActivateWindow(window1.get()); | |
| 446 EXPECT_TRUE(wm::IsActiveWindow(window1.get())); | |
| 447 EXPECT_FALSE(wm::IsActiveWindow(window2.get())); | |
| 448 EXPECT_FALSE(wm::IsActiveWindow(window3.get())); | |
| 449 | |
| 450 Cycle(WindowSelector::FORWARD); | |
| 451 EXPECT_TRUE(IsSelecting()); | |
| 452 EXPECT_TRUE(wm::IsActiveWindow(window2.get())); | |
| 453 | |
| 454 Cycle(WindowSelector::FORWARD); | |
| 455 EXPECT_TRUE(wm::IsActiveWindow(window3.get())); | |
| 456 | |
| 457 StopCycling(); | |
| 458 EXPECT_FALSE(IsSelecting()); | |
| 459 EXPECT_FALSE(wm::IsActiveWindow(window1.get())); | |
| 460 EXPECT_FALSE(wm::IsActiveWindow(window2.get())); | |
| 461 EXPECT_TRUE(wm::IsActiveWindow(window3.get())); | |
| 462 } | |
| 463 | |
| 464 // Tests that cycling through windows preserves the window stacking order. | |
| 465 TEST_F(WindowSelectorTest, CyclePreservesStackingOrder) { | |
| 466 gfx::Rect bounds(0, 0, 400, 400); | |
| 467 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 468 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 469 scoped_ptr<aura::Window> window3(CreateWindow(bounds)); | |
| 470 wm::ActivateWindow(window3.get()); | |
| 471 wm::ActivateWindow(window2.get()); | |
| 472 wm::ActivateWindow(window1.get()); | |
| 473 // Window order from top to bottom is 1, 2, 3. | |
| 474 EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get())); | |
| 475 EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get())); | |
| 476 | |
| 477 // On window 2. | |
| 478 Cycle(WindowSelector::FORWARD); | |
| 479 EXPECT_TRUE(IsWindowAbove(window2.get(), window1.get())); | |
| 480 EXPECT_TRUE(IsWindowAbove(window1.get(), window3.get())); | |
| 481 | |
| 482 // On window 3. | |
| 483 Cycle(WindowSelector::FORWARD); | |
| 484 EXPECT_TRUE(IsWindowAbove(window3.get(), window1.get())); | |
| 485 EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get())); | |
| 486 | |
| 487 // Back on window 1. | |
| 488 Cycle(WindowSelector::FORWARD); | |
| 489 EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get())); | |
| 490 EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get())); | |
| 491 StopCycling(); | |
| 492 } | |
| 493 | |
| 494 // Tests that cycling through windows shows and minimizes windows as they | |
| 495 // are passed. | |
| 496 TEST_F(WindowSelectorTest, CyclePreservesMinimization) { | |
| 497 gfx::Rect bounds(0, 0, 400, 400); | |
| 498 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 499 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 500 wm::ActivateWindow(window2.get()); | |
| 501 wm::GetWindowState(window2.get())->Minimize(); | |
| 502 wm::ActivateWindow(window1.get()); | |
| 503 EXPECT_TRUE(wm::IsWindowMinimized(window2.get())); | |
| 504 | |
| 505 // On window 2. | |
| 506 Cycle(WindowSelector::FORWARD); | |
| 507 EXPECT_FALSE(wm::IsWindowMinimized(window2.get())); | |
| 508 | |
| 509 // Back on window 1. | |
| 510 Cycle(WindowSelector::FORWARD); | |
| 511 EXPECT_TRUE(wm::IsWindowMinimized(window2.get())); | |
| 512 | |
| 513 StopCycling(); | |
| 514 EXPECT_TRUE(wm::IsWindowMinimized(window2.get())); | |
| 515 } | |
| 516 | |
| 517 // Tests beginning cycling while in overview mode. | |
| 518 TEST_F(WindowSelectorTest, OverviewTransitionToCycle) { | |
| 519 gfx::Rect bounds(0, 0, 400, 400); | |
| 520 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 521 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 522 wm::ActivateWindow(window2.get()); | |
| 523 wm::ActivateWindow(window1.get()); | |
| 524 | |
| 525 ToggleOverview(); | |
| 526 Cycle(WindowSelector::FORWARD); | |
| 527 StopCycling(); | |
| 528 | |
| 529 EXPECT_TRUE(wm::IsActiveWindow(window2.get())); | |
| 530 EXPECT_FALSE(wm::IsActiveWindow(window1.get())); | |
| 531 EXPECT_EQ(window2.get(), GetFocusedWindow()); | |
| 532 } | |
| 533 | |
| 534 // Tests cycles between panel and normal windows. | |
| 535 TEST_F(WindowSelectorTest, CyclePanels) { | |
| 536 gfx::Rect bounds(0, 0, 400, 400); | |
| 537 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 538 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 539 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds)); | |
| 540 scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds)); | |
| 541 wm::ActivateWindow(window2.get()); | |
| 542 wm::ActivateWindow(window1.get()); | |
| 543 wm::ActivateWindow(panel2.get()); | |
| 544 wm::ActivateWindow(panel1.get()); | |
| 545 EXPECT_TRUE(wm::IsActiveWindow(panel1.get())); | |
| 546 | |
| 547 // Cycling once should select window1 since the panels are grouped into a | |
| 548 // single selectable item. | |
| 549 Cycle(WindowSelector::FORWARD); | |
| 550 StopCycling(); | |
| 551 EXPECT_TRUE(wm::IsActiveWindow(window1.get())); | |
| 552 | |
| 553 // Cycling again should select the most recently used panel. | |
| 554 Cycle(WindowSelector::FORWARD); | |
| 555 StopCycling(); | |
| 556 EXPECT_TRUE(wm::IsActiveWindow(panel1.get())); | |
| 557 } | |
| 558 | |
| 559 // Tests the visibility of panel windows during cycling. | |
| 560 TEST_F(WindowSelectorTest, CyclePanelVisibility) { | |
| 561 gfx::Rect bounds(0, 0, 400, 400); | |
| 562 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 563 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds)); | |
| 564 wm::ActivateWindow(panel1.get()); | |
| 565 wm::ActivateWindow(window1.get()); | |
| 566 | |
| 567 Cycle(WindowSelector::FORWARD); | |
| 568 FireOverviewStartTimer(); | |
| 569 EXPECT_EQ(1.0f, panel1->layer()->GetTargetOpacity()); | |
| 570 StopCycling(); | |
| 571 } | |
| 572 | |
| 573 // Tests cycles between panel and normal windows. | |
| 574 TEST_F(WindowSelectorTest, CyclePanelsDestroyed) { | |
| 575 gfx::Rect bounds(0, 0, 400, 400); | |
| 576 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 577 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 578 scoped_ptr<aura::Window> window3(CreateWindow(bounds)); | |
| 579 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds)); | |
| 580 scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds)); | |
| 581 wm::ActivateWindow(window3.get()); | |
| 582 wm::ActivateWindow(panel2.get()); | |
| 583 wm::ActivateWindow(panel1.get()); | |
| 584 wm::ActivateWindow(window2.get()); | |
| 585 wm::ActivateWindow(window1.get()); | |
| 586 EXPECT_TRUE(wm::IsActiveWindow(window1.get())); | |
| 587 | |
| 588 // Cycling once highlights window2. | |
| 589 Cycle(WindowSelector::FORWARD); | |
| 590 // All panels are destroyed. | |
| 591 panel1.reset(); | |
| 592 panel2.reset(); | |
| 593 // Cycling again should now select window3. | |
| 594 Cycle(WindowSelector::FORWARD); | |
| 595 StopCycling(); | |
| 596 EXPECT_TRUE(wm::IsActiveWindow(window3.get())); | |
| 597 } | |
| 598 | |
| 599 // Tests cycles between panel and normal windows. | |
| 600 TEST_F(WindowSelectorTest, CycleMruPanelDestroyed) { | |
| 601 gfx::Rect bounds(0, 0, 400, 400); | |
| 602 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 603 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 604 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds)); | |
| 605 scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds)); | |
| 606 wm::ActivateWindow(panel2.get()); | |
| 607 wm::ActivateWindow(panel1.get()); | |
| 608 wm::ActivateWindow(window2.get()); | |
| 609 wm::ActivateWindow(window1.get()); | |
| 610 EXPECT_TRUE(wm::IsActiveWindow(window1.get())); | |
| 611 | |
| 612 // Cycling once highlights window2. | |
| 613 Cycle(WindowSelector::FORWARD); | |
| 614 // Panel 1 is the next item as the MRU panel, removing it should make panel 2 | |
| 615 // the next window to be selected. | |
| 616 panel1.reset(); | |
| 617 // Cycling again should now select window3. | |
| 618 Cycle(WindowSelector::FORWARD); | |
| 619 StopCycling(); | |
| 620 EXPECT_TRUE(wm::IsActiveWindow(panel2.get())); | |
| 621 } | |
| 622 | |
| 623 // Tests that a newly created window aborts overview. | 347 // Tests that a newly created window aborts overview. |
| 624 TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) { | 348 TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) { |
| 625 gfx::Rect bounds(0, 0, 400, 400); | 349 gfx::Rect bounds(0, 0, 400, 400); |
| 626 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | 350 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); |
| 627 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | 351 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); |
| 628 ToggleOverview(); | 352 ToggleOverview(); |
| 629 EXPECT_TRUE(IsSelecting()); | 353 EXPECT_TRUE(IsSelecting()); |
| 630 | 354 |
| 631 // A window being created should exit overview mode. | 355 // A window being created should exit overview mode. |
| 632 scoped_ptr<aura::Window> window3(CreateWindow(bounds)); | 356 scoped_ptr<aura::Window> window3(CreateWindow(bounds)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 644 | 368 |
| 645 // A window being activated should exit overview mode. | 369 // A window being activated should exit overview mode. |
| 646 window1->Focus(); | 370 window1->Focus(); |
| 647 EXPECT_FALSE(IsSelecting()); | 371 EXPECT_FALSE(IsSelecting()); |
| 648 | 372 |
| 649 // window1 should be focused after exiting even though window2 was focused on | 373 // window1 should be focused after exiting even though window2 was focused on |
| 650 // entering overview because we exited due to an activation. | 374 // entering overview because we exited due to an activation. |
| 651 EXPECT_EQ(window1.get(), GetFocusedWindow()); | 375 EXPECT_EQ(window1.get(), GetFocusedWindow()); |
| 652 } | 376 } |
| 653 | 377 |
| 654 // Verifies that overview mode only begins after a delay when cycling. | |
| 655 TEST_F(WindowSelectorTest, CycleOverviewDelay) { | |
| 656 gfx::Rect bounds(0, 0, 400, 400); | |
| 657 scoped_ptr<aura::Window> window1(CreateWindow(bounds)); | |
| 658 scoped_ptr<aura::Window> window2(CreateWindow(bounds)); | |
| 659 EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get())); | |
| 660 | |
| 661 // When cycling first starts, the windows will still be overlapping. | |
| 662 Cycle(WindowSelector::FORWARD); | |
| 663 EXPECT_TRUE(IsSelecting()); | |
| 664 EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get())); | |
| 665 | |
| 666 // Once the overview timer fires, the windows should no longer overlap. | |
| 667 FireOverviewStartTimer(); | |
| 668 EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get())); | |
| 669 StopCycling(); | |
| 670 } | |
| 671 | |
| 672 // Tests that exiting overview mode without selecting a window restores focus | 378 // Tests that exiting overview mode without selecting a window restores focus |
| 673 // to the previously focused window. | 379 // to the previously focused window. |
| 674 TEST_F(WindowSelectorTest, CancelRestoresFocus) { | 380 TEST_F(WindowSelectorTest, CancelRestoresFocus) { |
| 675 gfx::Rect bounds(0, 0, 400, 400); | 381 gfx::Rect bounds(0, 0, 400, 400); |
| 676 scoped_ptr<aura::Window> window(CreateWindow(bounds)); | 382 scoped_ptr<aura::Window> window(CreateWindow(bounds)); |
| 677 wm::ActivateWindow(window.get()); | 383 wm::ActivateWindow(window.get()); |
| 678 EXPECT_EQ(window.get(), GetFocusedWindow()); | 384 EXPECT_EQ(window.get(), GetFocusedWindow()); |
| 679 | 385 |
| 680 // In overview mode, focus should be removed. | 386 // In overview mode, focus should be removed. |
| 681 ToggleOverview(); | 387 ToggleOverview(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 ToEnclosingRect(GetTransformedTargetBounds(panel2.get())))); | 544 ToEnclosingRect(GetTransformedTargetBounds(panel2.get())))); |
| 839 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | 545 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( |
| 840 ToEnclosingRect(GetTransformedTargetBounds(panel3.get())))); | 546 ToEnclosingRect(GetTransformedTargetBounds(panel3.get())))); |
| 841 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | 547 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( |
| 842 ToEnclosingRect(GetTransformedTargetBounds(panel4.get())))); | 548 ToEnclosingRect(GetTransformedTargetBounds(panel4.get())))); |
| 843 EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get())); | 549 EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get())); |
| 844 EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get())); | 550 EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get())); |
| 845 EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get())); | 551 EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get())); |
| 846 } | 552 } |
| 847 | 553 |
| 848 // Verifies that the single display overview used during alt tab cycling uses | |
| 849 // the display of the selected window by default. | |
| 850 TEST_F(WindowSelectorTest, CycleOverviewUsesCurrentDisplay) { | |
| 851 if (!SupportsMultipleDisplays()) | |
| 852 return; | |
| 853 | |
| 854 UpdateDisplay("400x400,400x400"); | |
| 855 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | |
| 856 | |
| 857 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100))); | |
| 858 scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100))); | |
| 859 EXPECT_EQ(root_windows[0], window1->GetRootWindow()); | |
| 860 EXPECT_EQ(root_windows[1], window2->GetRootWindow()); | |
| 861 wm::ActivateWindow(window2.get()); | |
| 862 wm::ActivateWindow(window1.get()); | |
| 863 EXPECT_EQ(root_windows[0], Shell::GetTargetRootWindow()); | |
| 864 | |
| 865 Cycle(WindowSelector::FORWARD); | |
| 866 FireOverviewStartTimer(); | |
| 867 | |
| 868 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 869 ToEnclosingRect(GetTransformedTargetBounds(window1.get())))); | |
| 870 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 871 ToEnclosingRect(GetTransformedTargetBounds(window2.get())))); | |
| 872 StopCycling(); | |
| 873 } | |
| 874 | |
| 875 // Verifies that the windows being shown on another display are copied. | |
| 876 TEST_F(WindowSelectorTest, CycleMultipleDisplaysCopiesWindows) { | |
| 877 if (!SupportsMultipleDisplays()) | |
| 878 return; | |
| 879 | |
| 880 UpdateDisplay("400x400,400x400"); | |
| 881 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | |
| 882 | |
| 883 gfx::Rect root1_rect(0, 0, 100, 100); | |
| 884 gfx::Rect root2_rect(450, 0, 100, 100); | |
| 885 scoped_ptr<aura::Window> unmoved1(CreateWindow(root2_rect)); | |
| 886 scoped_ptr<aura::Window> unmoved2(CreateWindow(root2_rect)); | |
| 887 scoped_ptr<aura::Window> moved1_trans_parent(CreateWindow(root1_rect)); | |
| 888 scoped_ptr<aura::Window> moved1(CreateWindow(root1_rect)); | |
| 889 unmoved1->SetName("unmoved1"); | |
| 890 unmoved2->SetName("unmoved2"); | |
| 891 moved1->SetName("moved1"); | |
| 892 moved1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW); | |
| 893 ::wm::AddTransientChild(moved1_trans_parent.get(), moved1.get()); | |
| 894 moved1_trans_parent->SetName("moved1_trans_parent"); | |
| 895 | |
| 896 EXPECT_EQ(root_windows[0], moved1->GetRootWindow()); | |
| 897 EXPECT_EQ(root_windows[0], moved1_trans_parent->GetRootWindow()); | |
| 898 EXPECT_EQ(root_windows[1], unmoved1->GetRootWindow()); | |
| 899 EXPECT_EQ(root_windows[1], unmoved2->GetRootWindow()); | |
| 900 wm::ActivateWindow(unmoved2.get()); | |
| 901 wm::ActivateWindow(unmoved1.get()); | |
| 902 | |
| 903 Cycle(WindowSelector::FORWARD); | |
| 904 FireOverviewStartTimer(); | |
| 905 | |
| 906 // All windows are moved to second root window. | |
| 907 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 908 ToEnclosingRect(GetTransformedTargetBounds(unmoved1.get())))); | |
| 909 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 910 ToEnclosingRect(GetTransformedTargetBounds(unmoved2.get())))); | |
| 911 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 912 ToEnclosingRect(GetTransformedTargetBounds(moved1.get())))); | |
| 913 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 914 ToEnclosingRect(GetTransformedTargetBounds(moved1_trans_parent.get())))); | |
| 915 | |
| 916 // unmoved1 and unmoved2 were already on the correct display and should not | |
| 917 // have been copied. | |
| 918 EXPECT_TRUE(!GetCopyWindow(unmoved1.get())); | |
| 919 EXPECT_TRUE(!GetCopyWindow(unmoved2.get())); | |
| 920 | |
| 921 // moved1 and its transient parent moved1_trans_parent should have also been | |
| 922 // copied for displaying on root_windows[1]. | |
| 923 aura::Window* copy1 = GetCopyWindow(moved1.get()); | |
| 924 aura::Window* copy1_trans_parent = GetCopyWindow(moved1_trans_parent.get()); | |
| 925 ASSERT_FALSE(!copy1); | |
| 926 ASSERT_FALSE(!copy1_trans_parent); | |
| 927 | |
| 928 // Verify that the bounds and transform of the copy match the original window | |
| 929 // but that it is on the other root window. | |
| 930 EXPECT_EQ(root_windows[1], copy1->GetRootWindow()); | |
| 931 EXPECT_EQ(moved1->GetBoundsInScreen().ToString(), | |
| 932 copy1->GetBoundsInScreen().ToString()); | |
| 933 EXPECT_EQ(moved1->layer()->GetTargetTransform().ToString(), | |
| 934 copy1->layer()->GetTargetTransform().ToString()); | |
| 935 StopCycling(); | |
| 936 | |
| 937 // After cycling the copy windows should have been destroyed. | |
| 938 RunAllPendingInMessageLoop(); | |
| 939 EXPECT_TRUE(!GetCopyWindow(moved1.get())); | |
| 940 EXPECT_TRUE(!GetCopyWindow(moved1_trans_parent.get())); | |
| 941 } | |
| 942 | |
| 943 // Tests that beginning to cycle from overview mode moves windows to the | |
| 944 // active display. | |
| 945 TEST_F(WindowSelectorTest, MultipleDisplaysOverviewTransitionToCycle) { | |
| 946 if (!SupportsMultipleDisplays()) | |
| 947 return; | |
| 948 | |
| 949 UpdateDisplay("400x400,400x400"); | |
| 950 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | |
| 951 | |
| 952 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100))); | |
| 953 scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100))); | |
| 954 EXPECT_EQ(root_windows[0], window1->GetRootWindow()); | |
| 955 EXPECT_EQ(root_windows[1], window2->GetRootWindow()); | |
| 956 wm::ActivateWindow(window2.get()); | |
| 957 wm::ActivateWindow(window1.get()); | |
| 958 | |
| 959 ToggleOverview(); | |
| 960 EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains( | |
| 961 ToEnclosingRect(GetTransformedTargetBounds(window1.get())))); | |
| 962 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains( | |
| 963 ToEnclosingRect(GetTransformedTargetBounds(window2.get())))); | |
| 964 | |
| 965 Cycle(WindowSelector::FORWARD); | |
| 966 EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains( | |
| 967 ToEnclosingRect(GetTransformedTargetBounds(window1.get())))); | |
| 968 EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains( | |
| 969 ToEnclosingRect(GetTransformedTargetBounds(window2.get())))); | |
| 970 StopCycling(); | |
| 971 } | |
| 972 | |
| 973 // Tests that a bounds change during overview is corrected for. | |
| 974 TEST_F(WindowSelectorTest, BoundsChangeDuringCycleOnOtherDisplay) { | |
| 975 if (!SupportsMultipleDisplays()) | |
| 976 return; | |
| 977 | |
| 978 UpdateDisplay("400x400,400x400"); | |
| 979 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | |
| 980 | |
| 981 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100))); | |
| 982 scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100))); | |
| 983 scoped_ptr<aura::Window> window3(CreateWindow(gfx::Rect(450, 0, 100, 100))); | |
| 984 EXPECT_EQ(root_windows[0], window1->GetRootWindow()); | |
| 985 EXPECT_EQ(root_windows[1], window2->GetRootWindow()); | |
| 986 EXPECT_EQ(root_windows[1], window3->GetRootWindow()); | |
| 987 wm::ActivateWindow(window1.get()); | |
| 988 wm::ActivateWindow(window2.get()); | |
| 989 wm::ActivateWindow(window3.get()); | |
| 990 | |
| 991 Cycle(WindowSelector::FORWARD); | |
| 992 FireOverviewStartTimer(); | |
| 993 | |
| 994 gfx::Rect overview_bounds( | |
| 995 ToEnclosingRect(GetTransformedTargetBounds(window1.get()))); | |
| 996 EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(overview_bounds)); | |
| 997 | |
| 998 // Change the position and size of window1 (being displayed on the second | |
| 999 // root window) and it should remain within the same bounds. | |
| 1000 window1->SetBounds(gfx::Rect(100, 0, 200, 200)); | |
| 1001 gfx::Rect new_overview_bounds = | |
| 1002 ToEnclosingRect(GetTransformedTargetBounds(window1.get())); | |
| 1003 EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x()); | |
| 1004 EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y()); | |
| 1005 EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width()); | |
| 1006 EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height()); | |
| 1007 StopCycling(); | |
| 1008 } | |
| 1009 | |
| 1010 // Tests shutting down during overview. | 554 // Tests shutting down during overview. |
| 1011 TEST_F(WindowSelectorTest, Shutdown) { | 555 TEST_F(WindowSelectorTest, Shutdown) { |
| 1012 gfx::Rect bounds(0, 0, 400, 400); | 556 gfx::Rect bounds(0, 0, 400, 400); |
| 1013 // These windows will be deleted when the test exits and the Shell instance | 557 // These windows will be deleted when the test exits and the Shell instance |
| 1014 // is shut down. | 558 // is shut down. |
| 1015 aura::Window* window1(CreateWindow(bounds)); | 559 aura::Window* window1(CreateWindow(bounds)); |
| 1016 aura::Window* window2(CreateWindow(bounds)); | 560 aura::Window* window2(CreateWindow(bounds)); |
| 1017 aura::Window* window3(CreatePanelWindow(bounds)); | 561 aura::Window* window3(CreatePanelWindow(bounds)); |
| 1018 aura::Window* window4(CreatePanelWindow(bounds)); | 562 aura::Window* window4(CreatePanelWindow(bounds)); |
| 1019 | 563 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1185 UpdateDisplay("600x200/r"); | 729 UpdateDisplay("600x200/r"); |
| 1186 EXPECT_EQ("0,0 200x600", root_window->bounds().ToString()); | 730 EXPECT_EQ("0,0 200x600", root_window->bounds().ToString()); |
| 1187 for (ScopedVector<aura::Window>::iterator iter = windows.begin(); | 731 for (ScopedVector<aura::Window>::iterator iter = windows.begin(); |
| 1188 iter != windows.end(); ++iter) { | 732 iter != windows.end(); ++iter) { |
| 1189 EXPECT_TRUE(root_window->bounds().Contains( | 733 EXPECT_TRUE(root_window->bounds().Contains( |
| 1190 ToEnclosingRect(GetTransformedTargetBounds(*iter)))); | 734 ToEnclosingRect(GetTransformedTargetBounds(*iter)))); |
| 1191 } | 735 } |
| 1192 } | 736 } |
| 1193 | 737 |
| 1194 } // namespace ash | 738 } // namespace ash |
| OLD | NEW |