Home | History | Annotate | Download | only in overview
      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
      3 // found in the LICENSE file.
      4 
      5 #include "ash/launcher/launcher.h"
      6 #include "ash/root_window_controller.h"
      7 #include "ash/screen_ash.h"
      8 #include "ash/shelf/shelf_widget.h"
      9 #include "ash/shell.h"
     10 #include "ash/test/ash_test_base.h"
     11 #include "ash/test/launcher_test_api.h"
     12 #include "ash/test/shelf_view_test_api.h"
     13 #include "ash/test/shell_test_api.h"
     14 #include "ash/test/test_shelf_delegate.h"
     15 #include "ash/wm/mru_window_tracker.h"
     16 #include "ash/wm/overview/window_selector.h"
     17 #include "ash/wm/overview/window_selector_controller.h"
     18 #include "ash/wm/window_state.h"
     19 #include "ash/wm/window_util.h"
     20 #include "base/basictypes.h"
     21 #include "base/compiler_specific.h"
     22 #include "base/memory/scoped_vector.h"
     23 #include "base/run_loop.h"
     24 #include "ui/aura/client/activation_delegate.h"
     25 #include "ui/aura/client/aura_constants.h"
     26 #include "ui/aura/client/cursor_client.h"
     27 #include "ui/aura/client/focus_client.h"
     28 #include "ui/aura/root_window.h"
     29 #include "ui/aura/test/event_generator.h"
     30 #include "ui/aura/test/test_window_delegate.h"
     31 #include "ui/aura/test/test_windows.h"
     32 #include "ui/aura/window.h"
     33 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
     34 #include "ui/gfx/rect_conversions.h"
     35 #include "ui/gfx/transform.h"
     36 
     37 namespace ash {
     38 namespace internal {
     39 
     40 namespace {
     41 
     42 class NonActivatableActivationDelegate
     43     : public aura::client::ActivationDelegate {
     44  public:
     45   virtual bool ShouldActivate() const OVERRIDE {
     46     return false;
     47   }
     48 };
     49 
     50 bool IsWindowAbove(aura::Window* w1, aura::Window* w2) {
     51   aura::Window* parent = w1->parent();
     52   DCHECK_EQ(parent, w2->parent());
     53   for (aura::Window::Windows::const_iterator iter = parent->children().begin();
     54        iter != parent->children().end(); ++iter) {
     55     if (*iter == w1)
     56       return false;
     57     if (*iter == w2)
     58       return true;
     59   }
     60   NOTREACHED();
     61   return false;
     62 }
     63 
     64 aura::Window* GetWindowByName(aura::Window* container,
     65                               const std::string& name) {
     66   aura::Window* window = NULL;
     67   for (aura::Window::Windows::const_iterator iter =
     68        container->children().begin(); iter != container->children().end();
     69        ++iter) {
     70     if ((*iter)->name() == name) {
     71       // The name should be unique.
     72       DCHECK(!window);
     73       window = *iter;
     74     }
     75   }
     76   return window;
     77 }
     78 
     79 // Returns the copy of |window| created for overview. It is found using the
     80 // window name which should be the same as the source window's name with a
     81 // special suffix, and in the same container as the source window.
     82 aura::Window* GetCopyWindow(aura::Window* window) {
     83   aura::Window* copy_window = NULL;
     84   std::string copy_name = window->name() + " (Copy)";
     85   std::vector<aura::Window*> containers(
     86       Shell::GetContainersFromAllRootWindows(window->parent()->id(), NULL));
     87   for (std::vector<aura::Window*>::iterator iter = containers.begin();
     88        iter != containers.end(); ++iter) {
     89     aura::Window* found = GetWindowByName(*iter, copy_name);
     90     if (found) {
     91       // There should only be one copy window.
     92       DCHECK(!copy_window);
     93       copy_window = found;
     94     }
     95   }
     96   return copy_window;
     97 }
     98 
     99 }  // namespace
    100 
    101 class WindowSelectorTest : public test::AshTestBase {
    102  public:
    103   WindowSelectorTest() {}
    104   virtual ~WindowSelectorTest() {}
    105 
    106   virtual void SetUp() OVERRIDE {
    107     test::AshTestBase::SetUp();
    108     ASSERT_TRUE(test::TestShelfDelegate::instance());
    109 
    110     shelf_view_test_.reset(new test::ShelfViewTestAPI(
    111         test::LauncherTestAPI(Launcher::ForPrimaryDisplay()).shelf_view()));
    112     shelf_view_test_->SetAnimationDuration(1);
    113   }
    114 
    115   aura::Window* CreateWindow(const gfx::Rect& bounds) {
    116     return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds);
    117   }
    118 
    119   aura::Window* CreateNonActivatableWindow(const gfx::Rect& bounds) {
    120     aura::Window* window = CreateWindow(bounds);
    121     aura::client::SetActivationDelegate(window,
    122                                         &non_activatable_activation_delegate_);
    123     EXPECT_FALSE(ash::wm::CanActivateWindow(window));
    124     return window;
    125   }
    126 
    127   aura::Window* CreatePanelWindow(const gfx::Rect& bounds) {
    128     aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
    129         NULL, aura::client::WINDOW_TYPE_PANEL, 0, bounds);
    130     test::TestShelfDelegate::instance()->AddLauncherItem(window);
    131     shelf_view_test()->RunMessageLoopUntilAnimationsDone();
    132     return window;
    133   }
    134 
    135   bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) {
    136     gfx::RectF window1_bounds = GetTransformedTargetBounds(window1);
    137     gfx::RectF window2_bounds = GetTransformedTargetBounds(window2);
    138     return window1_bounds.Intersects(window2_bounds);
    139   }
    140 
    141   void ToggleOverview() {
    142     ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview();
    143   }
    144 
    145   void Cycle(WindowSelector::Direction direction) {
    146     ash::Shell::GetInstance()->window_selector_controller()->
    147         HandleCycleWindow(direction);
    148   }
    149 
    150   void StopCycling() {
    151     ash::Shell::GetInstance()->window_selector_controller()->window_selector_->
    152         SelectWindow();
    153   }
    154 
    155   void FireOverviewStartTimer() {
    156     // Calls the method to start overview mode which is normally called by the
    157     // timer. The timer will still fire and call this method triggering the
    158     // DCHECK that overview mode was not already started, except that we call
    159     // StopCycling before the timer has a chance to fire.
    160     ash::Shell::GetInstance()->window_selector_controller()->window_selector_->
    161         StartOverview();
    162   }
    163 
    164   gfx::Transform GetTransformRelativeTo(gfx::PointF origin,
    165                                         const gfx::Transform& transform) {
    166     gfx::Transform t;
    167     t.Translate(origin.x(), origin.y());
    168     t.PreconcatTransform(transform);
    169     t.Translate(-origin.x(), -origin.y());
    170     return t;
    171   }
    172 
    173   gfx::RectF GetTransformedBounds(aura::Window* window) {
    174     gfx::RectF bounds(ash::ScreenAsh::ConvertRectToScreen(
    175         window->parent(), window->layer()->bounds()));
    176     gfx::Transform transform(GetTransformRelativeTo(bounds.origin(),
    177         window->layer()->transform()));
    178     transform.TransformRect(&bounds);
    179     return bounds;
    180   }
    181 
    182   gfx::RectF GetTransformedTargetBounds(aura::Window* window) {
    183     gfx::RectF bounds(ash::ScreenAsh::ConvertRectToScreen(
    184         window->parent(), window->layer()->GetTargetBounds()));
    185     gfx::Transform transform(GetTransformRelativeTo(bounds.origin(),
    186         window->layer()->GetTargetTransform()));
    187     transform.TransformRect(&bounds);
    188     return bounds;
    189   }
    190 
    191   void ClickWindow(aura::Window* window) {
    192     aura::test::EventGenerator event_generator(window->GetRootWindow(), window);
    193     gfx::RectF target = GetTransformedBounds(window);
    194     event_generator.ClickLeftButton();
    195   }
    196 
    197   bool IsSelecting() {
    198     return ash::Shell::GetInstance()->window_selector_controller()->
    199         IsSelecting();
    200   }
    201 
    202   aura::Window* GetFocusedWindow() {
    203     return aura::client::GetFocusClient(
    204         Shell::GetPrimaryRootWindow())->GetFocusedWindow();
    205   }
    206 
    207   test::ShelfViewTestAPI* shelf_view_test() {
    208     return shelf_view_test_.get();
    209   }
    210 
    211  private:
    212   aura::test::TestWindowDelegate delegate_;
    213   NonActivatableActivationDelegate non_activatable_activation_delegate_;
    214   scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_;
    215 
    216   DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest);
    217 };
    218 
    219 // Tests entering overview mode with two windows and selecting one.
    220 TEST_F(WindowSelectorTest, Basic) {
    221   gfx::Rect bounds(0, 0, 400, 400);
    222   aura::Window* root_window = Shell::GetPrimaryRootWindow();
    223   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    224   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    225   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    226   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
    227   EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
    228   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
    229   wm::ActivateWindow(window2.get());
    230   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
    231   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    232   EXPECT_EQ(window2.get(), GetFocusedWindow());
    233   // Hide the cursor before entering overview to test that it will be shown.
    234   aura::client::GetCursorClient(root_window)->HideCursor();
    235 
    236   // In overview mode the windows should no longer overlap and focus should
    237   // be removed from the window.
    238   ToggleOverview();
    239   EXPECT_EQ(NULL, GetFocusedWindow());
    240   EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
    241   EXPECT_FALSE(WindowsOverlapping(window1.get(), panel1.get()));
    242   // Panels 1 and 2 should still be overlapping being in a single selector
    243   // item.
    244   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
    245 
    246   // The cursor should be visible and locked as a pointer
    247   EXPECT_EQ(ui::kCursorPointer,
    248             root_window->GetDispatcher()->last_cursor().native_type());
    249   EXPECT_TRUE(aura::client::GetCursorClient(root_window)->IsCursorLocked());
    250   EXPECT_TRUE(aura::client::GetCursorClient(root_window)->IsCursorVisible());
    251 
    252   // Clicking window 1 should activate it.
    253   ClickWindow(window1.get());
    254   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    255   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
    256   EXPECT_EQ(window1.get(), GetFocusedWindow());
    257 
    258   // Cursor should have been unlocked.
    259   EXPECT_FALSE(aura::client::GetCursorClient(root_window)->IsCursorLocked());
    260 }
    261 
    262 // Tests entering overview mode with two windows and selecting one.
    263 TEST_F(WindowSelectorTest, FullscreenWindow) {
    264   gfx::Rect bounds(0, 0, 400, 400);
    265   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    266   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    267   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    268   wm::ActivateWindow(window1.get());
    269 
    270   wm::GetWindowState(window1.get())->ToggleFullscreen();
    271   // The panel is hidden in fullscreen mode.
    272   EXPECT_FALSE(panel1->IsVisible());
    273   EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
    274 
    275   // Enter overview and select the fullscreen window.
    276   ToggleOverview();
    277 
    278   // The panel becomes temporarily visible for the overview.
    279   EXPECT_TRUE(panel1->IsVisible());
    280   ClickWindow(window1.get());
    281 
    282   // The window is still fullscreen as it was selected. The panel should again
    283   // be hidden.
    284   EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
    285   EXPECT_FALSE(panel1->IsVisible());
    286 
    287   // Entering overview and selecting another window, the previous window remains
    288   // fullscreen.
    289   // TODO(flackr): Currently the panel remains hidden, but should become visible
    290   // again.
    291   ToggleOverview();
    292   ClickWindow(window2.get());
    293   EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
    294 }
    295 
    296 // Tests that the shelf dimming state is removed while in overview and restored
    297 // on exiting overview.
    298 TEST_F(WindowSelectorTest, OverviewUndimsShelf) {
    299   gfx::Rect bounds(0, 0, 400, 400);
    300   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    301   wm::WindowState* window_state = wm::GetWindowState(window1.get());
    302   window_state->Maximize();
    303   ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf();
    304   EXPECT_TRUE(shelf->GetDimsShelf());
    305   ToggleOverview();
    306   EXPECT_FALSE(shelf->GetDimsShelf());
    307   ToggleOverview();
    308   EXPECT_TRUE(shelf->GetDimsShelf());
    309 }
    310 
    311 // Tests that beginning window selection hides the app list.
    312 TEST_F(WindowSelectorTest, SelectingHidesAppList) {
    313   gfx::Rect bounds(0, 0, 400, 400);
    314   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    315   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    316   Shell::GetInstance()->ToggleAppList(NULL);
    317   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
    318   ToggleOverview();
    319   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
    320   ToggleOverview();
    321 
    322   // The app list uses an animation to fade out. If it is toggled on immediately
    323   // after being removed the old widget is re-used and it does not gain focus.
    324   // When running under normal circumstances this shouldn't be possible, but
    325   // it is in a test without letting the message loop run.
    326   RunAllPendingInMessageLoop();
    327 
    328   Shell::GetInstance()->ToggleAppList(NULL);
    329   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
    330   Cycle(WindowSelector::FORWARD);
    331   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
    332   StopCycling();
    333 }
    334 
    335 // Tests that a minimized window's visibility and layer visibility is correctly
    336 // changed when entering overview and restored when leaving overview mode.
    337 TEST_F(WindowSelectorTest, MinimizedWindowVisibility) {
    338   gfx::Rect bounds(0, 0, 400, 400);
    339   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    340   wm::WindowState* window_state = wm::GetWindowState(window1.get());
    341   window_state->Minimize();
    342   EXPECT_FALSE(window1->IsVisible());
    343   EXPECT_FALSE(window1->layer()->GetTargetVisibility());
    344   {
    345     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    346         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    347     ToggleOverview();
    348     EXPECT_TRUE(window1->IsVisible());
    349     EXPECT_TRUE(window1->layer()->GetTargetVisibility());
    350   }
    351   {
    352     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    353         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    354     ToggleOverview();
    355     EXPECT_FALSE(window1->IsVisible());
    356     EXPECT_FALSE(window1->layer()->GetTargetVisibility());
    357   }
    358 }
    359 
    360 // Tests that a bounds change during overview is corrected for.
    361 TEST_F(WindowSelectorTest, BoundsChangeDuringOverview) {
    362   scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400)));
    363   ToggleOverview();
    364   gfx::Rect overview_bounds =
    365       ToEnclosingRect(GetTransformedTargetBounds(window.get()));
    366   window->SetBounds(gfx::Rect(200, 0, 200, 200));
    367   gfx::Rect new_overview_bounds =
    368       ToEnclosingRect(GetTransformedTargetBounds(window.get()));
    369   EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
    370   EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
    371   EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
    372   EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
    373   ToggleOverview();
    374 }
    375 
    376 // Tests entering overview mode with three windows and cycling through them.
    377 TEST_F(WindowSelectorTest, BasicCycle) {
    378   gfx::Rect bounds(0, 0, 400, 400);
    379   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    380   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    381   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
    382   wm::ActivateWindow(window3.get());
    383   wm::ActivateWindow(window2.get());
    384   wm::ActivateWindow(window1.get());
    385   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    386   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
    387   EXPECT_FALSE(wm::IsActiveWindow(window3.get()));
    388 
    389   Cycle(WindowSelector::FORWARD);
    390   EXPECT_TRUE(IsSelecting());
    391   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    392 
    393   Cycle(WindowSelector::FORWARD);
    394   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    395 
    396   StopCycling();
    397   EXPECT_FALSE(IsSelecting());
    398   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
    399   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
    400   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    401 }
    402 
    403 // Tests that cycling through windows preserves the window stacking order.
    404 TEST_F(WindowSelectorTest, CyclePreservesStackingOrder) {
    405   gfx::Rect bounds(0, 0, 400, 400);
    406   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    407   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    408   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
    409   wm::ActivateWindow(window3.get());
    410   wm::ActivateWindow(window2.get());
    411   wm::ActivateWindow(window1.get());
    412   // Window order from top to bottom is 1, 2, 3.
    413   EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
    414   EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get()));
    415 
    416   // On window 2.
    417   Cycle(WindowSelector::FORWARD);
    418   EXPECT_TRUE(IsWindowAbove(window2.get(), window1.get()));
    419   EXPECT_TRUE(IsWindowAbove(window1.get(), window3.get()));
    420 
    421   // On window 3.
    422   Cycle(WindowSelector::FORWARD);
    423   EXPECT_TRUE(IsWindowAbove(window3.get(), window1.get()));
    424   EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
    425 
    426   // Back on window 1.
    427   Cycle(WindowSelector::FORWARD);
    428   EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
    429   EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get()));
    430   StopCycling();
    431 }
    432 
    433 // Tests that cycling through windows shows and minimizes windows as they
    434 // are passed.
    435 TEST_F(WindowSelectorTest, CyclePreservesMinimization) {
    436   gfx::Rect bounds(0, 0, 400, 400);
    437   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    438   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    439   wm::ActivateWindow(window2.get());
    440   wm::GetWindowState(window2.get())->Minimize();
    441   wm::ActivateWindow(window1.get());
    442   EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
    443 
    444   // On window 2.
    445   Cycle(WindowSelector::FORWARD);
    446   EXPECT_FALSE(wm::IsWindowMinimized(window2.get()));
    447 
    448   // Back on window 1.
    449   Cycle(WindowSelector::FORWARD);
    450   EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
    451 
    452   StopCycling();
    453   EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
    454 }
    455 
    456 // Tests beginning cycling while in overview mode.
    457 TEST_F(WindowSelectorTest, OverviewTransitionToCycle) {
    458   gfx::Rect bounds(0, 0, 400, 400);
    459   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    460   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    461   wm::ActivateWindow(window2.get());
    462   wm::ActivateWindow(window1.get());
    463 
    464   ToggleOverview();
    465   Cycle(WindowSelector::FORWARD);
    466   StopCycling();
    467 
    468   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    469   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
    470   EXPECT_EQ(window2.get(), GetFocusedWindow());
    471 }
    472 
    473 // Tests cycles between panel and normal windows.
    474 TEST_F(WindowSelectorTest, CyclePanels) {
    475   gfx::Rect bounds(0, 0, 400, 400);
    476   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    477   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    478   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    479   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
    480   wm::ActivateWindow(window2.get());
    481   wm::ActivateWindow(window1.get());
    482   wm::ActivateWindow(panel2.get());
    483   wm::ActivateWindow(panel1.get());
    484   EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
    485 
    486   // Cycling once should select window1 since the panels are grouped into a
    487   // single selectable item.
    488   Cycle(WindowSelector::FORWARD);
    489   StopCycling();
    490   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    491 
    492   // Cycling again should select the most recently used panel.
    493   Cycle(WindowSelector::FORWARD);
    494   StopCycling();
    495   EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
    496 }
    497 
    498 // Tests the visibility of panel windows during cycling.
    499 TEST_F(WindowSelectorTest, CyclePanelVisibility) {
    500   gfx::Rect bounds(0, 0, 400, 400);
    501   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    502   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    503   wm::ActivateWindow(panel1.get());
    504   wm::ActivateWindow(window1.get());
    505 
    506   Cycle(WindowSelector::FORWARD);
    507   FireOverviewStartTimer();
    508   EXPECT_EQ(1.0f, panel1->layer()->GetTargetOpacity());
    509   StopCycling();
    510 }
    511 
    512 // Tests cycles between panel and normal windows.
    513 TEST_F(WindowSelectorTest, CyclePanelsDestroyed) {
    514   gfx::Rect bounds(0, 0, 400, 400);
    515   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    516   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    517   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
    518   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    519   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
    520   wm::ActivateWindow(window3.get());
    521   wm::ActivateWindow(panel2.get());
    522   wm::ActivateWindow(panel1.get());
    523   wm::ActivateWindow(window2.get());
    524   wm::ActivateWindow(window1.get());
    525   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    526 
    527   // Cycling once highlights window2.
    528   Cycle(WindowSelector::FORWARD);
    529   // All panels are destroyed.
    530   panel1.reset();
    531   panel2.reset();
    532   // Cycling again should now select window3.
    533   Cycle(WindowSelector::FORWARD);
    534   StopCycling();
    535   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    536 }
    537 
    538 // Tests cycles between panel and normal windows.
    539 TEST_F(WindowSelectorTest, CycleMruPanelDestroyed) {
    540   gfx::Rect bounds(0, 0, 400, 400);
    541   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    542   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    543   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    544   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
    545   wm::ActivateWindow(panel2.get());
    546   wm::ActivateWindow(panel1.get());
    547   wm::ActivateWindow(window2.get());
    548   wm::ActivateWindow(window1.get());
    549   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    550 
    551   // Cycling once highlights window2.
    552   Cycle(WindowSelector::FORWARD);
    553   // Panel 1 is the next item as the MRU panel, removing it should make panel 2
    554   // the next window to be selected.
    555   panel1.reset();
    556   // Cycling again should now select window3.
    557   Cycle(WindowSelector::FORWARD);
    558   StopCycling();
    559   EXPECT_TRUE(wm::IsActiveWindow(panel2.get()));
    560 }
    561 
    562 // Tests that a newly created window aborts overview.
    563 TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) {
    564   gfx::Rect bounds(0, 0, 400, 400);
    565   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    566   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    567   ToggleOverview();
    568   EXPECT_TRUE(IsSelecting());
    569 
    570   // A window being created should exit overview mode.
    571   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
    572   EXPECT_FALSE(IsSelecting());
    573 }
    574 
    575 // Tests that a window activation exits overview mode.
    576 TEST_F(WindowSelectorTest, ActivationCancelsOveriew) {
    577   gfx::Rect bounds(0, 0, 400, 400);
    578   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    579   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    580   window2->Focus();
    581   ToggleOverview();
    582   EXPECT_TRUE(IsSelecting());
    583 
    584   // A window being activated should exit overview mode.
    585   window1->Focus();
    586   EXPECT_FALSE(IsSelecting());
    587 
    588   // window1 should be focused after exiting even though window2 was focused on
    589   // entering overview because we exited due to an activation.
    590   EXPECT_EQ(window1.get(), GetFocusedWindow());
    591 }
    592 
    593 // Verifies that overview mode only begins after a delay when cycling.
    594 TEST_F(WindowSelectorTest, CycleOverviewDelay) {
    595   gfx::Rect bounds(0, 0, 400, 400);
    596   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    597   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    598   EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
    599 
    600   // When cycling first starts, the windows will still be overlapping.
    601   Cycle(WindowSelector::FORWARD);
    602   EXPECT_TRUE(IsSelecting());
    603   EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
    604 
    605   // Once the overview timer fires, the windows should no longer overlap.
    606   FireOverviewStartTimer();
    607   EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
    608   StopCycling();
    609 }
    610 
    611 // Tests that exiting overview mode without selecting a window restores focus
    612 // to the previously focused window.
    613 TEST_F(WindowSelectorTest, CancelRestoresFocus) {
    614   gfx::Rect bounds(0, 0, 400, 400);
    615   scoped_ptr<aura::Window> window(CreateWindow(bounds));
    616   wm::ActivateWindow(window.get());
    617   EXPECT_EQ(window.get(), GetFocusedWindow());
    618 
    619   // In overview mode, focus should be removed.
    620   ToggleOverview();
    621   EXPECT_EQ(NULL, GetFocusedWindow());
    622 
    623   // If canceling overview mode, focus should be restored.
    624   ToggleOverview();
    625   EXPECT_EQ(window.get(), GetFocusedWindow());
    626 }
    627 
    628 // Tests that overview mode is exited if the last remaining window is destroyed.
    629 TEST_F(WindowSelectorTest, LastWindowDestroyed) {
    630   gfx::Rect bounds(0, 0, 400, 400);
    631   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    632   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    633   ToggleOverview();
    634 
    635   window1.reset();
    636   window2.reset();
    637   EXPECT_FALSE(IsSelecting());
    638 }
    639 
    640 // Tests that entering overview mode restores a window to its original
    641 // target location.
    642 TEST_F(WindowSelectorTest, QuickReentryRestoresInitialTransform) {
    643   gfx::Rect bounds(0, 0, 400, 400);
    644   scoped_ptr<aura::Window> window(CreateWindow(bounds));
    645   gfx::Rect initial_bounds = ToEnclosingRect(
    646       GetTransformedBounds(window.get()));
    647   ToggleOverview();
    648   // Quickly exit and reenter overview mode. The window should still be
    649   // animating when we reenter. We cannot short circuit animations for this but
    650   // we also don't have to wait for them to complete.
    651   {
    652     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    653         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    654     ToggleOverview();
    655     ToggleOverview();
    656   }
    657   EXPECT_NE(initial_bounds, ToEnclosingRect(
    658       GetTransformedTargetBounds(window.get())));
    659   ToggleOverview();
    660   EXPECT_FALSE(IsSelecting());
    661   EXPECT_EQ(initial_bounds, ToEnclosingRect(
    662       GetTransformedTargetBounds(window.get())));
    663 }
    664 
    665 // Tests that non-activatable windows are hidden when entering overview mode.
    666 TEST_F(WindowSelectorTest, NonActivatableWindowsHidden) {
    667   gfx::Rect bounds(0, 0, 400, 400);
    668   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    669   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    670   scoped_ptr<aura::Window> non_activatable_window(
    671       CreateNonActivatableWindow(Shell::GetPrimaryRootWindow()->bounds()));
    672   EXPECT_TRUE(non_activatable_window->IsVisible());
    673   ToggleOverview();
    674   EXPECT_FALSE(non_activatable_window->IsVisible());
    675   ToggleOverview();
    676   EXPECT_TRUE(non_activatable_window->IsVisible());
    677 
    678   // Test that a window behind the fullscreen non-activatable window can be
    679   // clicked.
    680   non_activatable_window->parent()->StackChildAtTop(
    681       non_activatable_window.get());
    682   ToggleOverview();
    683   ClickWindow(window1.get());
    684   EXPECT_FALSE(IsSelecting());
    685   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    686 }
    687 
    688 // Tests that windows with modal child windows are transformed with the modal
    689 // child even though not activatable themselves.
    690 TEST_F(WindowSelectorTest, ModalChild) {
    691   gfx::Rect bounds(0, 0, 400, 400);
    692   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    693   scoped_ptr<aura::Window> child1(CreateWindow(bounds));
    694   child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
    695   window1->AddTransientChild(child1.get());
    696   EXPECT_EQ(window1->parent(), child1->parent());
    697   ToggleOverview();
    698   EXPECT_TRUE(window1->IsVisible());
    699   EXPECT_TRUE(child1->IsVisible());
    700   EXPECT_EQ(ToEnclosingRect(GetTransformedTargetBounds(child1.get())),
    701       ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
    702   ToggleOverview();
    703 }
    704 
    705 // Tests that clicking a modal window's parent activates the modal window in
    706 // overview.
    707 TEST_F(WindowSelectorTest, ClickModalWindowParent) {
    708   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 180, 180)));
    709   scoped_ptr<aura::Window> child1(CreateWindow(gfx::Rect(200, 0, 180, 180)));
    710   child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
    711   window1->AddTransientChild(child1.get());
    712   EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
    713   EXPECT_EQ(window1->parent(), child1->parent());
    714   ToggleOverview();
    715   // Given that their relative positions are preserved, the windows should still
    716   // not overlap.
    717   EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
    718   ClickWindow(window1.get());
    719   EXPECT_FALSE(IsSelecting());
    720 
    721   // Clicking on window1 should activate child1.
    722   EXPECT_TRUE(wm::IsActiveWindow(child1.get()));
    723 }
    724 
    725 // Tests that windows remain on the display they are currently on in overview
    726 // mode.
    727 TEST_F(WindowSelectorTest, MultipleDisplays) {
    728   if (!SupportsMultipleDisplays())
    729     return;
    730 
    731   UpdateDisplay("600x400,600x400");
    732   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    733   gfx::Rect bounds1(0, 0, 400, 400);
    734   gfx::Rect bounds2(650, 0, 400, 400);
    735 
    736   scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
    737   scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
    738   scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
    739   scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
    740   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1));
    741   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds1));
    742   scoped_ptr<aura::Window> panel3(CreatePanelWindow(bounds2));
    743   scoped_ptr<aura::Window> panel4(CreatePanelWindow(bounds2));
    744   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    745   EXPECT_EQ(root_windows[0], window2->GetRootWindow());
    746   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    747   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
    748 
    749   EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
    750   EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
    751   EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
    752   EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
    753 
    754   // In overview mode, each window remains in the same root window.
    755   ToggleOverview();
    756   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    757   EXPECT_EQ(root_windows[0], window2->GetRootWindow());
    758   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    759   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
    760   EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
    761   EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
    762   EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
    763   EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
    764 
    765   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    766       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
    767   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    768       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
    769   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    770       ToEnclosingRect(GetTransformedTargetBounds(window3.get()))));
    771   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    772       ToEnclosingRect(GetTransformedTargetBounds(window4.get()))));
    773 
    774   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    775       ToEnclosingRect(GetTransformedTargetBounds(panel1.get()))));
    776   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    777       ToEnclosingRect(GetTransformedTargetBounds(panel2.get()))));
    778   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    779       ToEnclosingRect(GetTransformedTargetBounds(panel3.get()))));
    780   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    781       ToEnclosingRect(GetTransformedTargetBounds(panel4.get()))));
    782   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
    783   EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get()));
    784   EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get()));
    785 }
    786 
    787 // Verifies that the single display overview used during alt tab cycling uses
    788 // the display of the selected window by default.
    789 TEST_F(WindowSelectorTest, CycleOverviewUsesCurrentDisplay) {
    790   if (!SupportsMultipleDisplays())
    791     return;
    792 
    793   UpdateDisplay("400x400,400x400");
    794   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    795 
    796   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
    797   scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
    798   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    799   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    800   wm::ActivateWindow(window2.get());
    801   wm::ActivateWindow(window1.get());
    802   EXPECT_EQ(root_windows[0], Shell::GetTargetRootWindow());
    803 
    804   Cycle(WindowSelector::FORWARD);
    805   FireOverviewStartTimer();
    806 
    807   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    808       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
    809   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    810       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
    811   StopCycling();
    812 }
    813 
    814 // Verifies that the windows being shown on another display are copied.
    815 TEST_F(WindowSelectorTest, CycleMultipleDisplaysCopiesWindows) {
    816   if (!SupportsMultipleDisplays())
    817     return;
    818 
    819   UpdateDisplay("400x400,400x400");
    820   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    821 
    822   gfx::Rect root1_rect(0, 0, 100, 100);
    823   gfx::Rect root2_rect(450, 0, 100, 100);
    824   scoped_ptr<aura::Window> unmoved1(CreateWindow(root2_rect));
    825   scoped_ptr<aura::Window> unmoved2(CreateWindow(root2_rect));
    826   scoped_ptr<aura::Window> moved1_trans_parent(CreateWindow(root1_rect));
    827   scoped_ptr<aura::Window> moved1(CreateWindow(root1_rect));
    828   unmoved1->SetName("unmoved1");
    829   unmoved2->SetName("unmoved2");
    830   moved1->SetName("moved1");
    831   moved1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
    832   moved1_trans_parent->AddTransientChild(moved1.get());
    833   moved1_trans_parent->SetName("moved1_trans_parent");
    834 
    835   EXPECT_EQ(root_windows[0], moved1->GetRootWindow());
    836   EXPECT_EQ(root_windows[0], moved1_trans_parent->GetRootWindow());
    837   EXPECT_EQ(root_windows[1], unmoved1->GetRootWindow());
    838   EXPECT_EQ(root_windows[1], unmoved2->GetRootWindow());
    839   wm::ActivateWindow(unmoved2.get());
    840   wm::ActivateWindow(unmoved1.get());
    841 
    842   Cycle(WindowSelector::FORWARD);
    843   FireOverviewStartTimer();
    844 
    845   // All windows are moved to second root window.
    846   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    847       ToEnclosingRect(GetTransformedTargetBounds(unmoved1.get()))));
    848   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    849       ToEnclosingRect(GetTransformedTargetBounds(unmoved2.get()))));
    850   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    851       ToEnclosingRect(GetTransformedTargetBounds(moved1.get()))));
    852   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    853       ToEnclosingRect(GetTransformedTargetBounds(moved1_trans_parent.get()))));
    854 
    855   // unmoved1 and unmoved2 were already on the correct display and should not
    856   // have been copied.
    857   EXPECT_TRUE(!GetCopyWindow(unmoved1.get()));
    858   EXPECT_TRUE(!GetCopyWindow(unmoved2.get()));
    859 
    860   // moved1 and its transient parent moved1_trans_parent should have also been
    861   // copied for displaying on root_windows[1].
    862   aura::Window* copy1 = GetCopyWindow(moved1.get());
    863   aura::Window* copy1_trans_parent = GetCopyWindow(moved1_trans_parent.get());
    864   ASSERT_FALSE(!copy1);
    865   ASSERT_FALSE(!copy1_trans_parent);
    866 
    867   // Verify that the bounds and transform of the copy match the original window
    868   // but that it is on the other root window.
    869   EXPECT_EQ(root_windows[1], copy1->GetRootWindow());
    870   EXPECT_EQ(moved1->GetBoundsInScreen().ToString(),
    871             copy1->GetBoundsInScreen().ToString());
    872   EXPECT_EQ(moved1->layer()->GetTargetTransform().ToString(),
    873             copy1->layer()->GetTargetTransform().ToString());
    874   StopCycling();
    875 
    876   // After cycling the copy windows should have been destroyed.
    877   RunAllPendingInMessageLoop();
    878   EXPECT_TRUE(!GetCopyWindow(moved1.get()));
    879   EXPECT_TRUE(!GetCopyWindow(moved1_trans_parent.get()));
    880 }
    881 
    882 // Tests that beginning to cycle from overview mode moves windows to the
    883 // active display.
    884 TEST_F(WindowSelectorTest, MultipleDisplaysOverviewTransitionToCycle) {
    885   if (!SupportsMultipleDisplays())
    886     return;
    887 
    888   UpdateDisplay("400x400,400x400");
    889   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    890 
    891   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
    892   scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
    893   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    894   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    895   wm::ActivateWindow(window2.get());
    896   wm::ActivateWindow(window1.get());
    897 
    898   ToggleOverview();
    899   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    900       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
    901   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
    902       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
    903 
    904   Cycle(WindowSelector::FORWARD);
    905   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    906       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
    907   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
    908       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
    909   StopCycling();
    910 }
    911 
    912 // Tests that a bounds change during overview is corrected for.
    913 TEST_F(WindowSelectorTest, BoundsChangeDuringCycleOnOtherDisplay) {
    914   if (!SupportsMultipleDisplays())
    915     return;
    916 
    917   UpdateDisplay("400x400,400x400");
    918   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    919 
    920   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
    921   scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
    922   scoped_ptr<aura::Window> window3(CreateWindow(gfx::Rect(450, 0, 100, 100)));
    923   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    924   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    925   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    926   wm::ActivateWindow(window1.get());
    927   wm::ActivateWindow(window2.get());
    928   wm::ActivateWindow(window3.get());
    929 
    930   Cycle(WindowSelector::FORWARD);
    931   FireOverviewStartTimer();
    932 
    933   gfx::Rect overview_bounds(
    934       ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
    935   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(overview_bounds));
    936 
    937   // Change the position and size of window1 (being displayed on the second
    938   // root window) and it should remain within the same bounds.
    939   window1->SetBounds(gfx::Rect(100, 0, 200, 200));
    940   gfx::Rect new_overview_bounds =
    941       ToEnclosingRect(GetTransformedTargetBounds(window1.get()));
    942   EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
    943   EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
    944   EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
    945   EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
    946   StopCycling();
    947 }
    948 
    949 // Tests shutting down during overview.
    950 TEST_F(WindowSelectorTest, Shutdown) {
    951   gfx::Rect bounds(0, 0, 400, 400);
    952   // These windows will be deleted when the test exits and the Shell instance
    953   // is shut down.
    954   aura::Window* window1(CreateWindow(bounds));
    955   aura::Window* window2(CreateWindow(bounds));
    956   aura::Window* window3(CreatePanelWindow(bounds));
    957   aura::Window* window4(CreatePanelWindow(bounds));
    958 
    959   wm::ActivateWindow(window4);
    960   wm::ActivateWindow(window3);
    961   wm::ActivateWindow(window2);
    962   wm::ActivateWindow(window1);
    963 
    964   ToggleOverview();
    965 }
    966 
    967 // Tests removing a display during overview.
    968 TEST_F(WindowSelectorTest, RemoveDisplay) {
    969   if (!SupportsMultipleDisplays())
    970     return;
    971 
    972   UpdateDisplay("400x400,400x400");
    973   gfx::Rect bounds1(0, 0, 100, 100);
    974   gfx::Rect bounds2(450, 0, 100, 100);
    975   scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
    976   scoped_ptr<aura::Window> window2(CreateWindow(bounds2));
    977   scoped_ptr<aura::Window> window3(CreatePanelWindow(bounds1));
    978   scoped_ptr<aura::Window> window4(CreatePanelWindow(bounds2));
    979 
    980   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    981   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    982   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    983   EXPECT_EQ(root_windows[0], window3->GetRootWindow());
    984   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
    985 
    986   wm::ActivateWindow(window4.get());
    987   wm::ActivateWindow(window3.get());
    988   wm::ActivateWindow(window2.get());
    989   wm::ActivateWindow(window1.get());
    990 
    991   ToggleOverview();
    992   EXPECT_TRUE(IsSelecting());
    993   UpdateDisplay("400x400");
    994   EXPECT_FALSE(IsSelecting());
    995 }
    996 
    997 }  // namespace internal
    998 }  // namespace ash
    999