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 <algorithm>
      6 
      7 #include "ash/accessibility_delegate.h"
      8 #include "ash/drag_drop/drag_drop_controller.h"
      9 #include "ash/root_window_controller.h"
     10 #include "ash/screen_util.h"
     11 #include "ash/shelf/shelf.h"
     12 #include "ash/shelf/shelf_widget.h"
     13 #include "ash/shell.h"
     14 #include "ash/shell_window_ids.h"
     15 #include "ash/test/ash_test_base.h"
     16 #include "ash/test/shelf_test_api.h"
     17 #include "ash/test/shelf_view_test_api.h"
     18 #include "ash/test/shell_test_api.h"
     19 #include "ash/test/test_shelf_delegate.h"
     20 #include "ash/wm/mru_window_tracker.h"
     21 #include "ash/wm/overview/window_grid.h"
     22 #include "ash/wm/overview/window_selector.h"
     23 #include "ash/wm/overview/window_selector_controller.h"
     24 #include "ash/wm/overview/window_selector_item.h"
     25 #include "ash/wm/panels/panel_layout_manager.h"
     26 #include "ash/wm/window_state.h"
     27 #include "ash/wm/window_util.h"
     28 #include "ash/wm/wm_event.h"
     29 #include "base/basictypes.h"
     30 #include "base/compiler_specific.h"
     31 #include "base/memory/scoped_vector.h"
     32 #include "base/run_loop.h"
     33 #include "base/strings/utf_string_conversions.h"
     34 #include "ui/aura/client/aura_constants.h"
     35 #include "ui/aura/client/cursor_client.h"
     36 #include "ui/aura/client/focus_client.h"
     37 #include "ui/aura/test/event_generator.h"
     38 #include "ui/aura/test/test_window_delegate.h"
     39 #include "ui/aura/test/test_windows.h"
     40 #include "ui/aura/window.h"
     41 #include "ui/aura/window_event_dispatcher.h"
     42 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
     43 #include "ui/gfx/rect_conversions.h"
     44 #include "ui/gfx/transform.h"
     45 #include "ui/views/controls/label.h"
     46 #include "ui/views/widget/native_widget_aura.h"
     47 #include "ui/views/widget/widget_delegate.h"
     48 #include "ui/wm/core/window_util.h"
     49 #include "ui/wm/public/activation_delegate.h"
     50 
     51 namespace ash {
     52 namespace {
     53 
     54 class NonActivatableActivationDelegate
     55     : public aura::client::ActivationDelegate {
     56  public:
     57   virtual bool ShouldActivate() const OVERRIDE {
     58     return false;
     59   }
     60 };
     61 
     62 void CancelDrag(DragDropController* controller, bool* canceled) {
     63   if (controller->IsDragDropInProgress()) {
     64     *canceled = true;
     65     controller->DragCancel();
     66   }
     67 }
     68 
     69 }  // namespace
     70 
     71 class WindowSelectorTest : public test::AshTestBase {
     72  public:
     73   WindowSelectorTest() {}
     74   virtual ~WindowSelectorTest() {}
     75 
     76   virtual void SetUp() OVERRIDE {
     77     test::AshTestBase::SetUp();
     78     ASSERT_TRUE(test::TestShelfDelegate::instance());
     79 
     80     shelf_view_test_.reset(new test::ShelfViewTestAPI(
     81         test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view()));
     82     shelf_view_test_->SetAnimationDuration(1);
     83   }
     84 
     85   aura::Window* CreateWindow(const gfx::Rect& bounds) {
     86     return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds);
     87   }
     88 
     89   aura::Window* CreateWindowWithId(const gfx::Rect& bounds, int id) {
     90     return CreateTestWindowInShellWithDelegate(&delegate_, id, bounds);
     91   }
     92   aura::Window* CreateNonActivatableWindow(const gfx::Rect& bounds) {
     93     aura::Window* window = CreateWindow(bounds);
     94     aura::client::SetActivationDelegate(window,
     95                                         &non_activatable_activation_delegate_);
     96     EXPECT_FALSE(ash::wm::CanActivateWindow(window));
     97     return window;
     98   }
     99 
    100   aura::Window* CreatePanelWindow(const gfx::Rect& bounds) {
    101     aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
    102         NULL, ui::wm::WINDOW_TYPE_PANEL, 0, bounds);
    103     test::TestShelfDelegate::instance()->AddShelfItem(window);
    104     shelf_view_test()->RunMessageLoopUntilAnimationsDone();
    105     return window;
    106   }
    107 
    108   views::Widget* CreatePanelWindowWidget(const gfx::Rect& bounds) {
    109     views::Widget* widget = new views::Widget;
    110     views::Widget::InitParams params;
    111     params.bounds = bounds;
    112     params.type = views::Widget::InitParams::TYPE_PANEL;
    113     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    114     widget->Init(params);
    115     widget->Show();
    116     ParentWindowInPrimaryRootWindow(widget->GetNativeWindow());
    117     return widget;
    118   }
    119 
    120   bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) {
    121     gfx::RectF window1_bounds = GetTransformedTargetBounds(window1);
    122     gfx::RectF window2_bounds = GetTransformedTargetBounds(window2);
    123     return window1_bounds.Intersects(window2_bounds);
    124   }
    125 
    126   void ToggleOverview() {
    127     ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview();
    128   }
    129 
    130   gfx::Transform GetTransformRelativeTo(gfx::PointF origin,
    131                                         const gfx::Transform& transform) {
    132     gfx::Transform t;
    133     t.Translate(origin.x(), origin.y());
    134     t.PreconcatTransform(transform);
    135     t.Translate(-origin.x(), -origin.y());
    136     return t;
    137   }
    138 
    139   gfx::RectF GetTransformedBounds(aura::Window* window) {
    140     gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
    141         window->parent(), window->layer()->bounds()));
    142     gfx::Transform transform(GetTransformRelativeTo(bounds.origin(),
    143         window->layer()->transform()));
    144     transform.TransformRect(&bounds);
    145     return bounds;
    146   }
    147 
    148   gfx::RectF GetTransformedTargetBounds(aura::Window* window) {
    149     gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
    150         window->parent(), window->layer()->GetTargetBounds()));
    151     gfx::Transform transform(GetTransformRelativeTo(bounds.origin(),
    152         window->layer()->GetTargetTransform()));
    153     transform.TransformRect(&bounds);
    154     return bounds;
    155   }
    156 
    157   gfx::RectF GetTransformedBoundsInRootWindow(aura::Window* window) {
    158     gfx::RectF bounds = gfx::Rect(window->bounds().size());
    159     aura::Window* root = window->GetRootWindow();
    160     CHECK(window->layer());
    161     CHECK(root->layer());
    162     gfx::Transform transform;
    163     if (!window->layer()->GetTargetTransformRelativeTo(root->layer(),
    164                                                        &transform)) {
    165       return gfx::RectF();
    166     }
    167     transform.TransformRect(&bounds);
    168     return bounds;
    169   }
    170 
    171   void ClickWindow(aura::Window* window) {
    172     aura::test::EventGenerator event_generator(window->GetRootWindow(), window);
    173     gfx::RectF target = GetTransformedBounds(window);
    174     event_generator.ClickLeftButton();
    175   }
    176 
    177   void SendKey(ui::KeyboardCode key) {
    178       aura::test::EventGenerator event_generator(Shell::GetPrimaryRootWindow());
    179       event_generator.PressKey(key, 0);
    180       event_generator.ReleaseKey(key, 0);
    181   }
    182 
    183   bool IsSelecting() {
    184     return ash::Shell::GetInstance()->window_selector_controller()->
    185         IsSelecting();
    186   }
    187 
    188   aura::Window* GetFocusedWindow() {
    189     return aura::client::GetFocusClient(
    190         Shell::GetPrimaryRootWindow())->GetFocusedWindow();
    191     }
    192 
    193   const std::vector<WindowSelectorItem*>& GetWindowItemsForRoot(int index) {
    194     return ash::Shell::GetInstance()->window_selector_controller()->
    195         window_selector_->grid_list_[index]->window_list_.get();
    196     }
    197 
    198   const aura::Window* GetSelectedWindow() {
    199     WindowSelector* ws = ash::Shell::GetInstance()->
    200         window_selector_controller()->window_selector_.get();
    201     return ws->grid_list_[ws->selected_grid_index_]->
    202         SelectedWindow()->SelectionWindow();
    203   }
    204 
    205   views::Widget* GetCloseButton(ash::WindowSelectorItem* window) {
    206     return window->close_button_.get();
    207   }
    208 
    209   views::Widget* GetLabelWidget(ash::WindowSelectorItem* window) {
    210     return window->window_label_.get();
    211   }
    212 
    213   // Tests that a window is contained within a given WindowSelectorItem, and
    214   // that both the window and its matching close button are within the same
    215   // screen.
    216   void IsWindowAndCloseButtonInScreen(aura::Window* window,
    217                                       WindowSelectorItem* window_item) {
    218     aura::Window* root_window = window_item->GetRootWindow();
    219     EXPECT_TRUE(window_item->Contains(window));
    220     EXPECT_TRUE(root_window->GetBoundsInScreen().Contains(
    221         ToEnclosingRect(GetTransformedTargetBounds(window))));
    222     EXPECT_TRUE(root_window->GetBoundsInScreen().Contains(
    223         ToEnclosingRect(GetTransformedTargetBounds(
    224             GetCloseButton(window_item)->GetNativeView()))));
    225   }
    226 
    227   test::ShelfViewTestAPI* shelf_view_test() {
    228     return shelf_view_test_.get();
    229   }
    230 
    231  private:
    232   aura::test::TestWindowDelegate delegate_;
    233   NonActivatableActivationDelegate non_activatable_activation_delegate_;
    234   scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_;
    235 
    236   DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest);
    237 };
    238 
    239 // Tests that an a11y alert is sent on entering overview mode.
    240 TEST_F(WindowSelectorTest, A11yAlertOnOverviewMode) {
    241   gfx::Rect bounds(0, 0, 400, 400);
    242   AccessibilityDelegate* delegate =
    243       ash::Shell::GetInstance()->accessibility_delegate();
    244   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    245   EXPECT_NE(delegate->GetLastAccessibilityAlert(),
    246             A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
    247   ToggleOverview();
    248   EXPECT_EQ(delegate->GetLastAccessibilityAlert(),
    249             A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
    250 }
    251 
    252 // Tests entering overview mode with two windows and selecting one by clicking.
    253 TEST_F(WindowSelectorTest, Basic) {
    254   gfx::Rect bounds(0, 0, 400, 400);
    255   aura::Window* root_window = Shell::GetPrimaryRootWindow();
    256   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    257   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    258   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    259   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
    260   EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
    261   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
    262   wm::ActivateWindow(window2.get());
    263   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
    264   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    265   EXPECT_EQ(window2.get(), GetFocusedWindow());
    266   // Hide the cursor before entering overview to test that it will be shown.
    267   aura::client::GetCursorClient(root_window)->HideCursor();
    268 
    269   // In overview mode the windows should no longer overlap and focus should
    270   // be removed from the window.
    271   ToggleOverview();
    272   EXPECT_EQ(NULL, GetFocusedWindow());
    273   EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
    274   EXPECT_FALSE(WindowsOverlapping(window1.get(), panel1.get()));
    275   // Panels 1 and 2 should still be overlapping being in a single selector
    276   // item.
    277   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
    278 
    279   // Clicking window 1 should activate it.
    280   ClickWindow(window1.get());
    281   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    282   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
    283   EXPECT_EQ(window1.get(), GetFocusedWindow());
    284 
    285   // Cursor should have been unlocked.
    286   EXPECT_FALSE(aura::client::GetCursorClient(root_window)->IsCursorLocked());
    287 }
    288 
    289 // Tests selecting a window by tapping on it.
    290 TEST_F(WindowSelectorTest, BasicGesture) {
    291   gfx::Rect bounds(0, 0, 400, 400);
    292   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    293   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    294   wm::ActivateWindow(window1.get());
    295   EXPECT_EQ(window1.get(), GetFocusedWindow());
    296   ToggleOverview();
    297   EXPECT_EQ(NULL, GetFocusedWindow());
    298   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    299                                        window2.get());
    300   generator.GestureTapAt(gfx::ToEnclosingRect(
    301       GetTransformedTargetBounds(window2.get())).CenterPoint());
    302   EXPECT_EQ(window2.get(), GetFocusedWindow());
    303 }
    304 
    305 // Tests that a window does not receive located events when in overview mode.
    306 TEST_F(WindowSelectorTest, WindowDoesNotReceiveEvents) {
    307   gfx::Rect window_bounds(20, 10, 200, 300);
    308   aura::Window* root_window = Shell::GetPrimaryRootWindow();
    309   scoped_ptr<aura::Window> window(CreateWindow(window_bounds));
    310 
    311   gfx::Point point1(window_bounds.x() + 10, window_bounds.y() + 10);
    312 
    313   ui::MouseEvent event1(ui::ET_MOUSE_PRESSED, point1, point1,
    314                         ui::EF_NONE, ui::EF_NONE);
    315 
    316   ui::EventTarget* root_target = root_window;
    317   ui::EventTargeter* targeter = root_target->GetEventTargeter();
    318 
    319   // The event should target the window because we are still not in overview
    320   // mode.
    321   EXPECT_EQ(window, static_cast<aura::Window*>(
    322       targeter->FindTargetForEvent(root_target, &event1)));
    323 
    324   ToggleOverview();
    325 
    326   // The bounds have changed, take that into account.
    327   gfx::RectF bounds = GetTransformedBoundsInRootWindow(window.get());
    328   gfx::Point point2(bounds.x() + 10, bounds.y() + 10);
    329   ui::MouseEvent event2(ui::ET_MOUSE_PRESSED, point2, point2,
    330                         ui::EF_NONE, ui::EF_NONE);
    331 
    332   // Now the transparent window should be intercepting this event.
    333   EXPECT_NE(window, static_cast<aura::Window*>(
    334         targeter->FindTargetForEvent(root_target, &event2)));
    335 }
    336 
    337 // Tests that clicking on the close button effectively closes the window.
    338 TEST_F(WindowSelectorTest, CloseButton) {
    339   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(200, 300, 250, 450)));
    340 
    341   // We need a widget for the close button the work, a bare window will crash.
    342   scoped_ptr<views::Widget> widget(new views::Widget);
    343   views::Widget::InitParams params;
    344   params.bounds = gfx::Rect(0, 0, 400, 400);
    345   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    346   params.parent = window1->parent();
    347   widget->Init(params);
    348   widget->Show();
    349   ToggleOverview();
    350 
    351   aura::Window* window2 = widget->GetNativeWindow();
    352   gfx::RectF bounds = GetTransformedBoundsInRootWindow(window2);
    353   gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1);
    354   aura::test::EventGenerator event_generator(window2->GetRootWindow(), point);
    355 
    356   EXPECT_FALSE(widget->IsClosed());
    357   event_generator.ClickLeftButton();
    358   EXPECT_TRUE(widget->IsClosed());
    359 }
    360 
    361 // Tests entering overview mode with two windows and selecting one.
    362 TEST_F(WindowSelectorTest, FullscreenWindow) {
    363   gfx::Rect bounds(0, 0, 400, 400);
    364   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    365   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    366   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
    367   wm::ActivateWindow(window1.get());
    368 
    369   const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
    370   wm::GetWindowState(window1.get())->OnWMEvent(&toggle_fullscreen_event);
    371   // The panel is hidden in fullscreen mode.
    372   EXPECT_FALSE(panel1->IsVisible());
    373   EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
    374 
    375   // Enter overview and select the fullscreen window.
    376   ToggleOverview();
    377 
    378   // The panel becomes temporarily visible for the overview.
    379   EXPECT_TRUE(panel1->IsVisible());
    380   ClickWindow(window1.get());
    381 
    382   // The window is still fullscreen as it was selected. The panel should again
    383   // be hidden.
    384   EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
    385   EXPECT_FALSE(panel1->IsVisible());
    386 
    387   // Entering overview and selecting another window, the previous window remains
    388   // fullscreen.
    389   // TODO(flackr): Currently the panel remains hidden, but should become visible
    390   // again.
    391   ToggleOverview();
    392   ClickWindow(window2.get());
    393   EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
    394 }
    395 
    396 // Tests that the shelf dimming state is removed while in overview and restored
    397 // on exiting overview.
    398 TEST_F(WindowSelectorTest, OverviewUndimsShelf) {
    399   gfx::Rect bounds(0, 0, 400, 400);
    400   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    401   wm::WindowState* window_state = wm::GetWindowState(window1.get());
    402   window_state->Maximize();
    403   ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf();
    404   EXPECT_TRUE(shelf->GetDimsShelf());
    405   ToggleOverview();
    406   EXPECT_FALSE(shelf->GetDimsShelf());
    407   ToggleOverview();
    408   EXPECT_TRUE(shelf->GetDimsShelf());
    409 }
    410 
    411 // Tests that beginning window selection hides the app list.
    412 TEST_F(WindowSelectorTest, SelectingHidesAppList) {
    413   gfx::Rect bounds(0, 0, 400, 400);
    414   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    415   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    416   Shell::GetInstance()->ToggleAppList(NULL);
    417   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
    418   ToggleOverview();
    419   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
    420   ToggleOverview();
    421 }
    422 
    423 // Tests that a minimized window's visibility and layer visibility is correctly
    424 // changed when entering overview and restored when leaving overview mode.
    425 // Crashes after the skia roll in http://crrev.com/274114.
    426 // http://crbug.com/379570
    427 TEST_F(WindowSelectorTest, DISABLED_MinimizedWindowVisibility) {
    428   gfx::Rect bounds(0, 0, 400, 400);
    429   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    430   wm::WindowState* window_state = wm::GetWindowState(window1.get());
    431   window_state->Minimize();
    432   EXPECT_FALSE(window1->IsVisible());
    433   EXPECT_FALSE(window1->layer()->GetTargetVisibility());
    434   {
    435     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    436         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    437     ToggleOverview();
    438     EXPECT_TRUE(window1->IsVisible());
    439     EXPECT_TRUE(window1->layer()->GetTargetVisibility());
    440   }
    441   {
    442     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    443         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    444     ToggleOverview();
    445     EXPECT_FALSE(window1->IsVisible());
    446     EXPECT_FALSE(window1->layer()->GetTargetVisibility());
    447   }
    448 }
    449 
    450 // Tests that a bounds change during overview is corrected for.
    451 TEST_F(WindowSelectorTest, BoundsChangeDuringOverview) {
    452   scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400)));
    453   ToggleOverview();
    454   gfx::Rect overview_bounds =
    455       ToEnclosingRect(GetTransformedTargetBounds(window.get()));
    456   window->SetBounds(gfx::Rect(200, 0, 200, 200));
    457   gfx::Rect new_overview_bounds =
    458       ToEnclosingRect(GetTransformedTargetBounds(window.get()));
    459   EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
    460   EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
    461   EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
    462   EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
    463   ToggleOverview();
    464 }
    465 
    466 // Tests that a newly created window aborts overview.
    467 TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) {
    468   gfx::Rect bounds(0, 0, 400, 400);
    469   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    470   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    471   ToggleOverview();
    472   EXPECT_TRUE(IsSelecting());
    473 
    474   // A window being created should exit overview mode.
    475   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
    476   EXPECT_FALSE(IsSelecting());
    477 }
    478 
    479 // Tests that a window activation exits overview mode.
    480 TEST_F(WindowSelectorTest, ActivationCancelsOveriew) {
    481   gfx::Rect bounds(0, 0, 400, 400);
    482   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    483   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    484   window2->Focus();
    485   ToggleOverview();
    486   EXPECT_TRUE(IsSelecting());
    487 
    488   // A window being activated should exit overview mode.
    489   window1->Focus();
    490   EXPECT_FALSE(IsSelecting());
    491 
    492   // window1 should be focused after exiting even though window2 was focused on
    493   // entering overview because we exited due to an activation.
    494   EXPECT_EQ(window1.get(), GetFocusedWindow());
    495 }
    496 
    497 // Tests that exiting overview mode without selecting a window restores focus
    498 // to the previously focused window.
    499 TEST_F(WindowSelectorTest, CancelRestoresFocus) {
    500   gfx::Rect bounds(0, 0, 400, 400);
    501   scoped_ptr<aura::Window> window(CreateWindow(bounds));
    502   wm::ActivateWindow(window.get());
    503   EXPECT_EQ(window.get(), GetFocusedWindow());
    504 
    505   // In overview mode, focus should be removed.
    506   ToggleOverview();
    507   EXPECT_EQ(NULL, GetFocusedWindow());
    508 
    509   // If canceling overview mode, focus should be restored.
    510   ToggleOverview();
    511   EXPECT_EQ(window.get(), GetFocusedWindow());
    512 }
    513 
    514 // Tests that overview mode is exited if the last remaining window is destroyed.
    515 TEST_F(WindowSelectorTest, LastWindowDestroyed) {
    516   gfx::Rect bounds(0, 0, 400, 400);
    517   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    518   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    519   ToggleOverview();
    520 
    521   window1.reset();
    522   window2.reset();
    523   EXPECT_FALSE(IsSelecting());
    524 }
    525 
    526 // Tests that entering overview mode restores a window to its original
    527 // target location.
    528 TEST_F(WindowSelectorTest, QuickReentryRestoresInitialTransform) {
    529   gfx::Rect bounds(0, 0, 400, 400);
    530   scoped_ptr<aura::Window> window(CreateWindow(bounds));
    531   gfx::Rect initial_bounds = ToEnclosingRect(
    532       GetTransformedBounds(window.get()));
    533   ToggleOverview();
    534   // Quickly exit and reenter overview mode. The window should still be
    535   // animating when we reenter. We cannot short circuit animations for this but
    536   // we also don't have to wait for them to complete.
    537   {
    538     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
    539         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
    540     ToggleOverview();
    541     ToggleOverview();
    542   }
    543   EXPECT_NE(initial_bounds, ToEnclosingRect(
    544       GetTransformedTargetBounds(window.get())));
    545   ToggleOverview();
    546   EXPECT_FALSE(IsSelecting());
    547   EXPECT_EQ(initial_bounds, ToEnclosingRect(
    548       GetTransformedTargetBounds(window.get())));
    549 }
    550 
    551 // Tests that non-activatable windows are hidden when entering overview mode.
    552 TEST_F(WindowSelectorTest, NonActivatableWindowsHidden) {
    553   gfx::Rect bounds(0, 0, 400, 400);
    554   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    555   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    556   scoped_ptr<aura::Window> non_activatable_window(
    557       CreateNonActivatableWindow(Shell::GetPrimaryRootWindow()->bounds()));
    558   EXPECT_TRUE(non_activatable_window->IsVisible());
    559   ToggleOverview();
    560   EXPECT_FALSE(non_activatable_window->IsVisible());
    561   ToggleOverview();
    562   EXPECT_TRUE(non_activatable_window->IsVisible());
    563 
    564   // Test that a window behind the fullscreen non-activatable window can be
    565   // clicked.
    566   non_activatable_window->parent()->StackChildAtTop(
    567       non_activatable_window.get());
    568   ToggleOverview();
    569   ClickWindow(window1.get());
    570   EXPECT_FALSE(IsSelecting());
    571   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    572 }
    573 
    574 // Tests that windows with modal child windows are transformed with the modal
    575 // child even though not activatable themselves.
    576 TEST_F(WindowSelectorTest, ModalChild) {
    577   gfx::Rect bounds(0, 0, 400, 400);
    578   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    579   scoped_ptr<aura::Window> child1(CreateWindow(bounds));
    580   child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
    581   ::wm::AddTransientChild(window1.get(), child1.get());
    582   EXPECT_EQ(window1->parent(), child1->parent());
    583   ToggleOverview();
    584   EXPECT_TRUE(window1->IsVisible());
    585   EXPECT_TRUE(child1->IsVisible());
    586   EXPECT_EQ(ToEnclosingRect(GetTransformedTargetBounds(child1.get())),
    587       ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
    588   ToggleOverview();
    589 }
    590 
    591 // Tests that clicking a modal window's parent activates the modal window in
    592 // overview.
    593 TEST_F(WindowSelectorTest, ClickModalWindowParent) {
    594   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 180, 180)));
    595   scoped_ptr<aura::Window> child1(CreateWindow(gfx::Rect(200, 0, 180, 180)));
    596   child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
    597   ::wm::AddTransientChild(window1.get(), child1.get());
    598   EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
    599   EXPECT_EQ(window1->parent(), child1->parent());
    600   ToggleOverview();
    601   // Given that their relative positions are preserved, the windows should still
    602   // not overlap.
    603   EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
    604   ClickWindow(window1.get());
    605   EXPECT_FALSE(IsSelecting());
    606 
    607   // Clicking on window1 should activate child1.
    608   EXPECT_TRUE(wm::IsActiveWindow(child1.get()));
    609 }
    610 
    611 // Tests that windows remain on the display they are currently on in overview
    612 // mode, and that the close buttons are on matching displays.
    613 TEST_F(WindowSelectorTest, MultipleDisplays) {
    614   if (!SupportsMultipleDisplays())
    615     return;
    616 
    617   UpdateDisplay("600x400,600x400");
    618   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    619   gfx::Rect bounds1(0, 0, 400, 400);
    620   gfx::Rect bounds2(650, 0, 400, 400);
    621 
    622   scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
    623   scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
    624   scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
    625   scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
    626   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1));
    627   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds1));
    628   scoped_ptr<aura::Window> panel3(CreatePanelWindow(bounds2));
    629   scoped_ptr<aura::Window> panel4(CreatePanelWindow(bounds2));
    630   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    631   EXPECT_EQ(root_windows[0], window2->GetRootWindow());
    632   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    633   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
    634 
    635   EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
    636   EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
    637   EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
    638   EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
    639 
    640   // In overview mode, each window remains in the same root window.
    641   ToggleOverview();
    642   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    643   EXPECT_EQ(root_windows[0], window2->GetRootWindow());
    644   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    645   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
    646   EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
    647   EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
    648   EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
    649   EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
    650 
    651   const std::vector<WindowSelectorItem*>& primary_window_items =
    652       GetWindowItemsForRoot(0);
    653   const std::vector<WindowSelectorItem*>& secondary_window_items =
    654       GetWindowItemsForRoot(1);
    655 
    656   // Window indices are based on top-down order. The reverse of our creation.
    657   IsWindowAndCloseButtonInScreen(window1.get(), primary_window_items[2]);
    658   IsWindowAndCloseButtonInScreen(window2.get(), primary_window_items[1]);
    659   IsWindowAndCloseButtonInScreen(window3.get(), secondary_window_items[2]);
    660   IsWindowAndCloseButtonInScreen(window4.get(), secondary_window_items[1]);
    661 
    662   IsWindowAndCloseButtonInScreen(panel1.get(), primary_window_items[0]);
    663   IsWindowAndCloseButtonInScreen(panel2.get(), primary_window_items[0]);
    664   IsWindowAndCloseButtonInScreen(panel3.get(), secondary_window_items[0]);
    665   IsWindowAndCloseButtonInScreen(panel4.get(), secondary_window_items[0]);
    666 
    667   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
    668   EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get()));
    669   EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get()));
    670 }
    671 
    672 // Tests shutting down during overview.
    673 TEST_F(WindowSelectorTest, Shutdown) {
    674   gfx::Rect bounds(0, 0, 400, 400);
    675   // These windows will be deleted when the test exits and the Shell instance
    676   // is shut down.
    677   aura::Window* window1(CreateWindow(bounds));
    678   aura::Window* window2(CreateWindow(bounds));
    679   aura::Window* window3(CreatePanelWindow(bounds));
    680   aura::Window* window4(CreatePanelWindow(bounds));
    681 
    682   wm::ActivateWindow(window4);
    683   wm::ActivateWindow(window3);
    684   wm::ActivateWindow(window2);
    685   wm::ActivateWindow(window1);
    686 
    687   ToggleOverview();
    688 }
    689 
    690 // Tests removing a display during overview.
    691 TEST_F(WindowSelectorTest, RemoveDisplay) {
    692   if (!SupportsMultipleDisplays())
    693     return;
    694 
    695   UpdateDisplay("400x400,400x400");
    696   gfx::Rect bounds1(0, 0, 100, 100);
    697   gfx::Rect bounds2(450, 0, 100, 100);
    698   scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
    699   scoped_ptr<aura::Window> window2(CreateWindow(bounds2));
    700   scoped_ptr<aura::Window> window3(CreatePanelWindow(bounds1));
    701   scoped_ptr<aura::Window> window4(CreatePanelWindow(bounds2));
    702 
    703   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    704   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    705   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    706   EXPECT_EQ(root_windows[0], window3->GetRootWindow());
    707   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
    708 
    709   wm::ActivateWindow(window4.get());
    710   wm::ActivateWindow(window3.get());
    711   wm::ActivateWindow(window2.get());
    712   wm::ActivateWindow(window1.get());
    713 
    714   ToggleOverview();
    715   EXPECT_TRUE(IsSelecting());
    716   UpdateDisplay("400x400");
    717   EXPECT_FALSE(IsSelecting());
    718 }
    719 
    720 // Tests starting overview during a drag and drop tracking operation.
    721 // TODO(flackr): Fix memory corruption crash when running locally (not failing
    722 // on bots). See http://crbug.com/342528.
    723 TEST_F(WindowSelectorTest, DISABLED_DragDropInProgress) {
    724   bool drag_canceled_by_test = false;
    725   gfx::Rect bounds(0, 0, 400, 400);
    726   scoped_ptr<aura::Window> window(CreateWindow(bounds));
    727   test::ShellTestApi shell_test_api(Shell::GetInstance());
    728   ash::DragDropController* drag_drop_controller =
    729       shell_test_api.drag_drop_controller();
    730   ui::OSExchangeData data;
    731   base::MessageLoopForUI::current()->PostTask(FROM_HERE,
    732       base::Bind(&WindowSelectorTest::ToggleOverview,
    733                  base::Unretained(this)));
    734   base::MessageLoopForUI::current()->PostTask(FROM_HERE,
    735       base::Bind(&CancelDrag, drag_drop_controller, &drag_canceled_by_test));
    736   data.SetString(base::UTF8ToUTF16("I am being dragged"));
    737   drag_drop_controller->StartDragAndDrop(data, window->GetRootWindow(),
    738       window.get(), gfx::Point(5, 5), ui::DragDropTypes::DRAG_MOVE,
    739       ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
    740   RunAllPendingInMessageLoop();
    741   EXPECT_FALSE(drag_canceled_by_test);
    742   ASSERT_TRUE(IsSelecting());
    743   RunAllPendingInMessageLoop();
    744 }
    745 
    746 // Test that a label is created under the window on entering overview mode.
    747 TEST_F(WindowSelectorTest, CreateLabelUnderWindow) {
    748   scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 100, 100)));
    749   base::string16 window_title = base::UTF8ToUTF16("My window");
    750   window->set_title(window_title);
    751   ToggleOverview();
    752   WindowSelectorItem* window_item = GetWindowItemsForRoot(0).back();
    753   views::Widget* widget = GetLabelWidget(window_item);
    754   // Has the label widget been created?
    755   ASSERT_TRUE(widget);
    756   views::Label* label = static_cast<views::Label*>(widget->GetContentsView());
    757   // Verify the label matches the window title.
    758   EXPECT_EQ(label->text(), window_title);
    759   // Labels are located based on target_bounds, not the actual window item
    760   // bounds.
    761   gfx::Rect target_bounds(window_item->target_bounds());
    762   gfx::Rect expected_label_bounds(target_bounds.x(),
    763                                   target_bounds.bottom(),
    764                                   target_bounds.width(),
    765                                   label->GetPreferredSize().height());
    766   gfx::Rect real_label_bounds = widget->GetNativeWindow()->bounds();
    767   EXPECT_EQ(widget->GetNativeWindow()->bounds(), real_label_bounds);
    768 }
    769 
    770 // Tests that a label is created for the active panel in a group of panels in
    771 // overview mode.
    772 TEST_F(WindowSelectorTest, CreateLabelUnderPanel) {
    773   scoped_ptr<aura::Window> panel1(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
    774   scoped_ptr<aura::Window> panel2(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
    775   base::string16 panel1_title = base::UTF8ToUTF16("My panel");
    776   base::string16 panel2_title = base::UTF8ToUTF16("Another panel");
    777   panel1->set_title(panel1_title);
    778   panel2->set_title(panel2_title);
    779   wm::ActivateWindow(panel1.get());
    780   ToggleOverview();
    781   WindowSelectorItem* window_item = GetWindowItemsForRoot(0).back();
    782   views::Widget* widget = GetLabelWidget(window_item);
    783   // Has the label widget been created?
    784   ASSERT_TRUE(widget);
    785   views::Label* label = static_cast<views::Label*>(widget->GetContentsView());
    786   // Verify the label matches the active window title.
    787   EXPECT_EQ(label->text(), panel1_title);
    788 }
    789 
    790 // Tests that overview updates the window positions if the display orientation
    791 // changes.
    792 TEST_F(WindowSelectorTest, DisplayOrientationChanged) {
    793   if (!SupportsHostWindowResize())
    794     return;
    795 
    796   aura::Window* root_window = Shell::GetInstance()->GetPrimaryRootWindow();
    797   UpdateDisplay("600x200");
    798   EXPECT_EQ("0,0 600x200", root_window->bounds().ToString());
    799   gfx::Rect window_bounds(0, 0, 150, 150);
    800   ScopedVector<aura::Window> windows;
    801   for (int i = 0; i < 3; i++) {
    802     windows.push_back(CreateWindow(window_bounds));
    803   }
    804 
    805   ToggleOverview();
    806   for (ScopedVector<aura::Window>::iterator iter = windows.begin();
    807        iter != windows.end(); ++iter) {
    808     EXPECT_TRUE(root_window->bounds().Contains(
    809         ToEnclosingRect(GetTransformedTargetBounds(*iter))));
    810   }
    811 
    812   // Rotate the display, windows should be repositioned to be within the screen
    813   // bounds.
    814   UpdateDisplay("600x200/r");
    815   EXPECT_EQ("0,0 200x600", root_window->bounds().ToString());
    816   for (ScopedVector<aura::Window>::iterator iter = windows.begin();
    817        iter != windows.end(); ++iter) {
    818     EXPECT_TRUE(root_window->bounds().Contains(
    819         ToEnclosingRect(GetTransformedTargetBounds(*iter))));
    820   }
    821 }
    822 
    823 // Tests traversing some windows in overview mode with the arrow keys in every
    824 // possible direction.
    825 TEST_F(WindowSelectorTest, BasicArrowKeyNavigation) {
    826   if (!SupportsHostWindowResize())
    827     return;
    828   const size_t test_windows = 7;
    829   UpdateDisplay("400x300");
    830   ScopedVector<aura::Window> windows;
    831   for (size_t i = test_windows; i > 0; i--)
    832     windows.push_back(CreateWindowWithId(gfx::Rect(0, 0, 100, 100), i));
    833 
    834   ui::KeyboardCode arrow_keys[] = {
    835       ui::VKEY_RIGHT,
    836       ui::VKEY_DOWN,
    837       ui::VKEY_LEFT,
    838       ui::VKEY_UP
    839   };
    840   // Expected window layout:
    841   // +-------+  +-------+  +-------+
    842   // |   1   |  |   2   |  |   3   |
    843   // +-------+  +-------+  +-------+
    844   // +-------+  +-------+  +-------+
    845   // |   4   |  |   5   |  |   6   |
    846   // +-------+  +-------+  +-------+
    847   // +-------+
    848   // |   7   |
    849   // +-------+
    850   // Index for each window during a full loop plus wrapping around.
    851   int index_path_for_direction[][test_windows + 1] = {
    852       {1, 2, 3, 4, 5, 6, 7, 1},  // Right
    853       {1, 4, 7, 2, 5, 3, 6, 1},  // Down
    854       {7, 6, 5, 4, 3, 2, 1, 7},  // Left
    855       {6, 3, 5, 2, 7, 4, 1, 6}   // Up
    856   };
    857 
    858   for (size_t key_index = 0; key_index < arraysize(arrow_keys); key_index++) {
    859     ToggleOverview();
    860     for (size_t i = 0; i < test_windows + 1; i++) {
    861       SendKey(arrow_keys[key_index]);
    862       // TODO(nsatragno): Add a more readable error message by constructing a
    863       // string from the window IDs.
    864       EXPECT_EQ(GetSelectedWindow()->id(),
    865                 index_path_for_direction[key_index][i]);
    866     }
    867     ToggleOverview();
    868   }
    869 }
    870 
    871 // Tests basic selection across multiple monitors.
    872 TEST_F(WindowSelectorTest, BasicMultiMonitorArrowKeyNavigation) {
    873   if (!SupportsMultipleDisplays())
    874     return;
    875 
    876   UpdateDisplay("400x400,400x400");
    877   gfx::Rect bounds1(0, 0, 100, 100);
    878   gfx::Rect bounds2(450, 0, 100, 100);
    879   scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
    880   scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
    881   scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
    882   scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
    883 
    884 
    885   ToggleOverview();
    886 
    887   SendKey(ui::VKEY_RIGHT);
    888   EXPECT_EQ(GetSelectedWindow(), window1.get());
    889   SendKey(ui::VKEY_RIGHT);
    890   EXPECT_EQ(GetSelectedWindow(), window2.get());
    891   SendKey(ui::VKEY_RIGHT);
    892   EXPECT_EQ(GetSelectedWindow(), window3.get());
    893   SendKey(ui::VKEY_RIGHT);
    894   EXPECT_EQ(GetSelectedWindow(), window4.get());
    895 }
    896 
    897 // Tests selecting a window in overview mode with the return key.
    898 TEST_F(WindowSelectorTest, SelectWindowWithReturnKey) {
    899   gfx::Rect bounds(0, 0, 100, 100);
    900   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
    901   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
    902   ToggleOverview();
    903 
    904   // Pressing the return key without a selection widget should not do anything.
    905   SendKey(ui::VKEY_RETURN);
    906   EXPECT_TRUE(IsSelecting());
    907 
    908   // Select the first window.
    909   SendKey(ui::VKEY_RIGHT);
    910   SendKey(ui::VKEY_RETURN);
    911   ASSERT_FALSE(IsSelecting());
    912   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    913 
    914   // Select the second window.
    915   ToggleOverview();
    916   SendKey(ui::VKEY_RIGHT);
    917   SendKey(ui::VKEY_RIGHT);
    918   SendKey(ui::VKEY_RETURN);
    919   EXPECT_FALSE(IsSelecting());
    920   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    921 }
    922 
    923 // Tests that overview mode hides the callout widget.
    924 TEST_F(WindowSelectorTest, WindowOverviewHidesCalloutWidgets) {
    925   scoped_ptr<aura::Window> panel1(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
    926   scoped_ptr<aura::Window> panel2(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
    927   PanelLayoutManager* panel_manager =
    928         static_cast<PanelLayoutManager*>(panel1->parent()->layout_manager());
    929 
    930   // By default, panel callout widgets are visible.
    931   EXPECT_TRUE(
    932       panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
    933   EXPECT_TRUE(
    934       panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
    935 
    936   // Toggling the overview should hide the callout widgets.
    937   ToggleOverview();
    938   EXPECT_FALSE(
    939       panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
    940   EXPECT_FALSE(
    941       panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
    942 
    943   // Ending the overview should show them again.
    944   ToggleOverview();
    945   EXPECT_TRUE(
    946       panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
    947   EXPECT_TRUE(
    948       panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
    949 }
    950 
    951 // Tests that when panels are grouped that the close button only closes the
    952 // currently active panel. After the removal window selection should still be
    953 // active, and the label should have changed. Removing the last panel should
    954 // cause selection to end.
    955 TEST_F(WindowSelectorTest, CloseButtonOnPanels) {
    956   scoped_ptr<views::Widget> widget1(CreatePanelWindowWidget(
    957       gfx::Rect(0, 0, 300, 100)));
    958   scoped_ptr<views::Widget> widget2(CreatePanelWindowWidget(
    959       gfx::Rect(100, 0, 100, 100)));
    960   aura::Window* window1 = widget1->GetNativeWindow();
    961   aura::Window* window2 = widget2->GetNativeWindow();
    962   base::string16 panel1_title = base::UTF8ToUTF16("Panel 1");
    963   base::string16 panel2_title = base::UTF8ToUTF16("Panel 2");
    964   window1->set_title(panel1_title);
    965   window2->set_title(panel2_title);
    966   wm::ActivateWindow(window1);
    967   ToggleOverview();
    968 
    969   gfx::RectF bounds1 = GetTransformedBoundsInRootWindow(window1);
    970   gfx::Point point1(bounds1.top_right().x() - 1, bounds1.top_right().y() - 1);
    971   aura::test::EventGenerator event_generator1(window1->GetRootWindow(), point1);
    972 
    973   EXPECT_FALSE(widget1->IsClosed());
    974   event_generator1.ClickLeftButton();
    975   EXPECT_TRUE(widget1->IsClosed());
    976   RunAllPendingInMessageLoop();
    977   EXPECT_TRUE(IsSelecting());
    978   WindowSelectorItem* window_item = GetWindowItemsForRoot(0).front();
    979   EXPECT_FALSE(window_item->empty());
    980   EXPECT_TRUE(window_item->Contains(window2));
    981   EXPECT_TRUE(GetCloseButton(window_item)->IsVisible());
    982 
    983   views::Widget* widget = GetLabelWidget(window_item);
    984   views::Label* label = static_cast<views::Label*>(widget->GetContentsView());
    985   EXPECT_EQ(label->text(), panel2_title);
    986 
    987   gfx::RectF bounds2 = GetTransformedBoundsInRootWindow(window2);
    988   gfx::Point point2(bounds2.top_right().x() - 1, bounds2.top_right().y() - 1);
    989   aura::test::EventGenerator event_generator2(window2->GetRootWindow(), point2);
    990 
    991   EXPECT_FALSE(widget2->IsClosed());
    992   event_generator2.ClickLeftButton();
    993   EXPECT_TRUE(widget2->IsClosed());
    994   RunAllPendingInMessageLoop();
    995   EXPECT_FALSE(IsSelecting());
    996 }
    997 
    998 }  // namespace ash
    999