Home | History | Annotate | Download | only in wm
      1 // Copyright 2014 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/wm/window_cycle_controller.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "ash/session/session_state_delegate.h"
     10 #include "ash/shelf/shelf.h"
     11 #include "ash/shelf/shelf_widget.h"
     12 #include "ash/shell.h"
     13 #include "ash/shell_window_ids.h"
     14 #include "ash/test/ash_test_base.h"
     15 #include "ash/test/shelf_test_api.h"
     16 #include "ash/test/shelf_view_test_api.h"
     17 #include "ash/test/test_shelf_delegate.h"
     18 #include "ash/test/test_shell_delegate.h"
     19 #include "ash/wm/window_cycle_list.h"
     20 #include "ash/wm/window_state.h"
     21 #include "ash/wm/window_util.h"
     22 #include "base/memory/scoped_ptr.h"
     23 #include "ui/aura/client/aura_constants.h"
     24 #include "ui/aura/client/screen_position_client.h"
     25 #include "ui/aura/env.h"
     26 #include "ui/aura/test/test_windows.h"
     27 #include "ui/aura/window.h"
     28 #include "ui/aura/window_event_dispatcher.h"
     29 #include "ui/gfx/rect.h"
     30 #include "ui/gfx/screen.h"
     31 
     32 namespace ash {
     33 
     34 using aura::test::CreateTestWindowWithId;
     35 using aura::test::TestWindowDelegate;
     36 using aura::Window;
     37 
     38 class WindowCycleControllerTest : public test::AshTestBase {
     39  public:
     40   WindowCycleControllerTest() {}
     41   virtual ~WindowCycleControllerTest() {}
     42 
     43   virtual void SetUp() OVERRIDE {
     44     test::AshTestBase::SetUp();
     45     ASSERT_TRUE(test::TestShelfDelegate::instance());
     46 
     47     shelf_view_test_.reset(new test::ShelfViewTestAPI(
     48         test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view()));
     49     shelf_view_test_->SetAnimationDuration(1);
     50   }
     51 
     52   aura::Window* CreatePanelWindow() {
     53     gfx::Rect rect(100, 100);
     54     aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
     55         NULL, ui::wm::WINDOW_TYPE_PANEL, 0, rect);
     56     test::TestShelfDelegate::instance()->AddShelfItem(window);
     57     shelf_view_test_->RunMessageLoopUntilAnimationsDone();
     58     return window;
     59   }
     60 
     61  private:
     62   scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_;
     63 
     64   DISALLOW_COPY_AND_ASSIGN(WindowCycleControllerTest);
     65 };
     66 
     67 TEST_F(WindowCycleControllerTest, HandleCycleWindowBaseCases) {
     68   WindowCycleController* controller =
     69       Shell::GetInstance()->window_cycle_controller();
     70 
     71   // Cycling doesn't crash if there are no windows.
     72   controller->HandleCycleWindow(WindowCycleController::FORWARD);
     73 
     74   // Create a single test window.
     75   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
     76   wm::ActivateWindow(window0.get());
     77   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
     78 
     79   // Cycling works for a single window, even though nothing changes.
     80   controller->HandleCycleWindow(WindowCycleController::FORWARD);
     81   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
     82 }
     83 
     84 // Verifies if there is only one window and it isn't active that cycling
     85 // activates it.
     86 TEST_F(WindowCycleControllerTest, SingleWindowNotActive) {
     87   WindowCycleController* controller =
     88       Shell::GetInstance()->window_cycle_controller();
     89 
     90   // Create a single test window.
     91   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
     92   wm::ActivateWindow(window0.get());
     93   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
     94 
     95   // Rotate focus, this should move focus to another window that isn't part of
     96   // the default container.
     97   Shell::GetInstance()->RotateFocus(Shell::FORWARD);
     98   EXPECT_FALSE(wm::IsActiveWindow(window0.get()));
     99 
    100   // Cycling should activate the window.
    101   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    102   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    103 }
    104 
    105 TEST_F(WindowCycleControllerTest, HandleCycleWindow) {
    106   WindowCycleController* controller =
    107       Shell::GetInstance()->window_cycle_controller();
    108 
    109   // Set up several windows to use to test cycling.  Create them in reverse
    110   // order so they are stacked 0 over 1 over 2.
    111   scoped_ptr<Window> window2(CreateTestWindowInShellWithId(2));
    112   scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
    113   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    114   wm::ActivateWindow(window0.get());
    115 
    116   // Simulate pressing and releasing Alt-tab.
    117   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    118   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    119 
    120   // Window lists should return the topmost window in front.
    121   ASSERT_TRUE(controller->window_cycle_list());
    122   ASSERT_EQ(3u, controller->window_cycle_list()->windows().size());
    123   ASSERT_EQ(window0.get(), controller->window_cycle_list()->windows()[0]);
    124   ASSERT_EQ(window1.get(), controller->window_cycle_list()->windows()[1]);
    125   ASSERT_EQ(window2.get(), controller->window_cycle_list()->windows()[2]);
    126 
    127   controller->StopCycling();
    128   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    129 
    130   // Pressing and releasing Alt-tab again should cycle back to the most-
    131   // recently-used window in the current child order.
    132   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    133   controller->StopCycling();
    134   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    135 
    136   // Pressing Alt-tab multiple times without releasing Alt should cycle through
    137   // all the windows and wrap around.
    138   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    139   EXPECT_TRUE(controller->IsCycling());
    140   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    141 
    142   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    143   EXPECT_TRUE(controller->IsCycling());
    144   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    145 
    146   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    147   EXPECT_TRUE(controller->IsCycling());
    148   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    149 
    150   controller->StopCycling();
    151   EXPECT_FALSE(controller->IsCycling());
    152   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    153 
    154   // Reset our stacking order.
    155   wm::ActivateWindow(window2.get());
    156   wm::ActivateWindow(window1.get());
    157   wm::ActivateWindow(window0.get());
    158 
    159   // Likewise we can cycle backwards through all the windows.
    160   controller->HandleCycleWindow(WindowCycleController::BACKWARD);
    161   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    162   controller->HandleCycleWindow(WindowCycleController::BACKWARD);
    163   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    164   controller->HandleCycleWindow(WindowCycleController::BACKWARD);
    165   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    166   controller->StopCycling();
    167   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    168 
    169   // When the screen is locked, cycling window does not take effect.
    170   Shell::GetInstance()->session_state_delegate()->LockScreen();
    171   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    172   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    173   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    174   controller->HandleCycleWindow(WindowCycleController::BACKWARD);
    175   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    176 
    177   Shell::GetInstance()->session_state_delegate()->UnlockScreen();
    178   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    179   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    180   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    181   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    182   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    183 
    184   // When a modal window is active, cycling window does not take effect.
    185   aura::Window* modal_container =
    186       ash::Shell::GetContainer(
    187           Shell::GetPrimaryRootWindow(),
    188           kShellWindowId_SystemModalContainer);
    189   scoped_ptr<Window> modal_window(
    190       CreateTestWindowWithId(-2, modal_container));
    191   modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM);
    192   wm::ActivateWindow(modal_window.get());
    193   EXPECT_TRUE(wm::IsActiveWindow(modal_window.get()));
    194   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    195   EXPECT_TRUE(wm::IsActiveWindow(modal_window.get()));
    196   EXPECT_FALSE(wm::IsActiveWindow(window0.get()));
    197   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
    198   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
    199   controller->HandleCycleWindow(WindowCycleController::BACKWARD);
    200   EXPECT_TRUE(wm::IsActiveWindow(modal_window.get()));
    201   EXPECT_FALSE(wm::IsActiveWindow(window0.get()));
    202   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
    203   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
    204 }
    205 
    206 // Cycles between a maximized and normal window.
    207 TEST_F(WindowCycleControllerTest, MaximizedWindow) {
    208   // Create a couple of test windows.
    209   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    210   scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
    211   wm::WindowState* window1_state = wm::GetWindowState(window1.get());
    212   window1_state->Maximize();
    213   window1_state->Activate();
    214   EXPECT_TRUE(window1_state->IsActive());
    215 
    216   // Rotate focus, this should move focus to window0.
    217   WindowCycleController* controller =
    218       Shell::GetInstance()->window_cycle_controller();
    219   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    220   EXPECT_TRUE(wm::GetWindowState(window0.get())->IsActive());
    221 
    222   // One more time.
    223   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    224   EXPECT_TRUE(window1_state->IsActive());
    225 }
    226 
    227 // Cycles to a minimized window.
    228 TEST_F(WindowCycleControllerTest, Minimized) {
    229   // Create a couple of test windows.
    230   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    231   scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
    232   wm::WindowState* window0_state = wm::GetWindowState(window0.get());
    233   wm::WindowState* window1_state = wm::GetWindowState(window1.get());
    234 
    235   window1_state->Minimize();
    236   window0_state->Activate();
    237   EXPECT_TRUE(window0_state->IsActive());
    238 
    239   // Rotate focus, this should move focus to window1 and unminimize it.
    240   WindowCycleController* controller =
    241       Shell::GetInstance()->window_cycle_controller();
    242   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    243   EXPECT_FALSE(window1_state->IsMinimized());
    244   EXPECT_TRUE(window1_state->IsActive());
    245 
    246   // One more time back to w0.
    247   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    248   EXPECT_TRUE(window0_state->IsActive());
    249 }
    250 
    251 TEST_F(WindowCycleControllerTest, AlwaysOnTopWindow) {
    252   WindowCycleController* controller =
    253       Shell::GetInstance()->window_cycle_controller();
    254 
    255   // Set up several windows to use to test cycling.
    256   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    257   scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
    258 
    259   Window* top_container =
    260       Shell::GetContainer(
    261           Shell::GetPrimaryRootWindow(),
    262           kShellWindowId_AlwaysOnTopContainer);
    263   scoped_ptr<Window> window2(CreateTestWindowWithId(2, top_container));
    264   wm::ActivateWindow(window0.get());
    265 
    266   // Simulate pressing and releasing Alt-tab.
    267   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    268   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    269 
    270   // Window lists should return the topmost window in front.
    271   ASSERT_TRUE(controller->window_cycle_list());
    272   ASSERT_EQ(3u, controller->window_cycle_list()->windows().size());
    273   EXPECT_EQ(window0.get(), controller->window_cycle_list()->windows()[0]);
    274   EXPECT_EQ(window2.get(), controller->window_cycle_list()->windows()[1]);
    275   EXPECT_EQ(window1.get(), controller->window_cycle_list()->windows()[2]);
    276 
    277   controller->StopCycling();
    278   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    279 
    280   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    281   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    282 
    283   controller->StopCycling();
    284 
    285   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    286   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    287 
    288   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    289   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    290 
    291   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    292   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    293 }
    294 
    295 TEST_F(WindowCycleControllerTest, AlwaysOnTopMultiWindow) {
    296   WindowCycleController* controller =
    297       Shell::GetInstance()->window_cycle_controller();
    298 
    299   // Set up several windows to use to test cycling.
    300   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    301   scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
    302 
    303   Window* top_container =
    304       Shell::GetContainer(
    305           Shell::GetPrimaryRootWindow(),
    306           kShellWindowId_AlwaysOnTopContainer);
    307   scoped_ptr<Window> window2(CreateTestWindowWithId(2, top_container));
    308   scoped_ptr<Window> window3(CreateTestWindowWithId(3, top_container));
    309   wm::ActivateWindow(window0.get());
    310 
    311   // Simulate pressing and releasing Alt-tab.
    312   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    313   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    314 
    315   // Window lists should return the topmost window in front.
    316   ASSERT_TRUE(controller->window_cycle_list());
    317   ASSERT_EQ(4u, controller->window_cycle_list()->windows().size());
    318   EXPECT_EQ(window0.get(), controller->window_cycle_list()->windows()[0]);
    319   EXPECT_EQ(window3.get(), controller->window_cycle_list()->windows()[1]);
    320   EXPECT_EQ(window2.get(), controller->window_cycle_list()->windows()[2]);
    321   EXPECT_EQ(window1.get(), controller->window_cycle_list()->windows()[3]);
    322 
    323   controller->StopCycling();
    324   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    325 
    326   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    327   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    328 
    329   controller->StopCycling();
    330 
    331   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    332   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    333 
    334   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    335   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    336 
    337   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    338   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    339 
    340   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    341   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    342 }
    343 
    344 TEST_F(WindowCycleControllerTest, AlwaysOnTopMultipleRootWindows) {
    345   if (!SupportsMultipleDisplays())
    346     return;
    347 
    348   // Set up a second root window
    349   UpdateDisplay("1000x600,600x400");
    350   aura::Window::Windows root_windows = Shell::GetAllRootWindows();
    351   ASSERT_EQ(2U, root_windows.size());
    352 
    353   WindowCycleController* controller =
    354       Shell::GetInstance()->window_cycle_controller();
    355 
    356   Shell::GetInstance()->set_target_root_window(root_windows[0]);
    357 
    358   // Create two windows in the primary root.
    359   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    360   EXPECT_EQ(root_windows[0], window0->GetRootWindow());
    361   Window* top_container0 =
    362       Shell::GetContainer(
    363           root_windows[0],
    364           kShellWindowId_AlwaysOnTopContainer);
    365   scoped_ptr<Window> window1(CreateTestWindowWithId(1, top_container0));
    366   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    367 
    368   // And two on the secondary root.
    369   Shell::GetInstance()->set_target_root_window(root_windows[1]);
    370   scoped_ptr<Window> window2(CreateTestWindowInShellWithId(2));
    371   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    372 
    373   Window* top_container1 =
    374       Shell::GetContainer(
    375           root_windows[1],
    376           kShellWindowId_AlwaysOnTopContainer);
    377   scoped_ptr<Window> window3(CreateTestWindowWithId(3, top_container1));
    378   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    379 
    380   // Move the active root window to the secondary.
    381   Shell::GetInstance()->set_target_root_window(root_windows[1]);
    382 
    383   wm::ActivateWindow(window2.get());
    384 
    385   EXPECT_EQ(root_windows[0], window0->GetRootWindow());
    386   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
    387   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
    388   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
    389 
    390   // Simulate pressing and releasing Alt-tab.
    391   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    392   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    393 
    394   // Window lists should return the topmost window in front.
    395   ASSERT_TRUE(controller->window_cycle_list());
    396   ASSERT_EQ(4u, controller->window_cycle_list()->windows().size());
    397   EXPECT_EQ(window2.get(), controller->window_cycle_list()->windows()[0]);
    398   EXPECT_EQ(window3.get(), controller->window_cycle_list()->windows()[1]);
    399   EXPECT_EQ(window1.get(), controller->window_cycle_list()->windows()[2]);
    400   EXPECT_EQ(window0.get(), controller->window_cycle_list()->windows()[3]);
    401 
    402   controller->StopCycling();
    403   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    404 
    405   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    406   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    407 
    408   controller->StopCycling();
    409 
    410   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    411   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
    412 
    413   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    414   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    415 
    416   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    417   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    418 
    419   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    420   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    421 }
    422 
    423 TEST_F(WindowCycleControllerTest, MostRecentlyUsed) {
    424   WindowCycleController* controller =
    425       Shell::GetInstance()->window_cycle_controller();
    426 
    427   // Set up several windows to use to test cycling.
    428   scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
    429   scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
    430   scoped_ptr<Window> window2(CreateTestWindowInShellWithId(2));
    431 
    432   wm::ActivateWindow(window0.get());
    433 
    434   // Simulate pressing and releasing Alt-tab.
    435   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    436   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    437 
    438   // Window lists should return the topmost window in front.
    439   ASSERT_TRUE(controller->window_cycle_list());
    440   ASSERT_EQ(3u, controller->window_cycle_list()->windows().size());
    441   EXPECT_EQ(window0.get(), controller->window_cycle_list()->windows()[0]);
    442   EXPECT_EQ(window2.get(), controller->window_cycle_list()->windows()[1]);
    443   EXPECT_EQ(window1.get(), controller->window_cycle_list()->windows()[2]);
    444 
    445   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    446   controller->StopCycling();
    447   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    448 
    449 
    450   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    451   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    452 
    453   controller->StopCycling();
    454 
    455   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    456   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
    457 
    458   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    459   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    460 
    461   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    462   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    463 }
    464 
    465 // Tests that beginning window selection hides the app list.
    466 TEST_F(WindowCycleControllerTest, SelectingHidesAppList) {
    467   WindowCycleController* controller =
    468       Shell::GetInstance()->window_cycle_controller();
    469 
    470   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    471   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    472   Shell::GetInstance()->ShowAppList(NULL);
    473   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
    474   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    475   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
    476 }
    477 
    478 // Tests that cycling through windows shows and minimizes windows as they
    479 // are passed.
    480 TEST_F(WindowCycleControllerTest, CyclePreservesMinimization) {
    481   WindowCycleController* controller =
    482       Shell::GetInstance()->window_cycle_controller();
    483 
    484   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    485   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    486   wm::ActivateWindow(window1.get());
    487   wm::GetWindowState(window1.get())->Minimize();
    488   wm::ActivateWindow(window0.get());
    489   EXPECT_TRUE(wm::IsWindowMinimized(window1.get()));
    490 
    491   // On window 2.
    492   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    493   EXPECT_FALSE(wm::IsWindowMinimized(window1.get()));
    494 
    495   // Back on window 1.
    496   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    497   EXPECT_TRUE(wm::IsWindowMinimized(window1.get()));
    498 
    499   controller->StopCycling();
    500 
    501   EXPECT_TRUE(wm::IsWindowMinimized(window1.get()));
    502 }
    503 
    504 // Tests cycles between panel and normal windows.
    505 TEST_F(WindowCycleControllerTest, CyclePanels) {
    506   WindowCycleController* controller =
    507       Shell::GetInstance()->window_cycle_controller();
    508 
    509   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    510   scoped_ptr<aura::Window> panel0(CreatePanelWindow());
    511   scoped_ptr<aura::Window> panel1(CreatePanelWindow());
    512   wm::ActivateWindow(window0.get());
    513   wm::ActivateWindow(panel1.get());
    514   wm::ActivateWindow(panel0.get());
    515   EXPECT_TRUE(wm::IsActiveWindow(panel0.get()));
    516 
    517   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    518   controller->StopCycling();
    519   EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
    520 
    521   // Cycling again should select the most recently used panel.
    522   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    523   controller->StopCycling();
    524   EXPECT_TRUE(wm::IsActiveWindow(panel0.get()));
    525 
    526   // Cycling twice again should select the first window.
    527   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    528   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    529   controller->StopCycling();
    530   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    531 }
    532 
    533 // Tests cycles between panel and normal windows.
    534 TEST_F(WindowCycleControllerTest, CyclePanelsDestroyed) {
    535   WindowCycleController* controller =
    536       Shell::GetInstance()->window_cycle_controller();
    537 
    538   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    539   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    540   scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
    541   scoped_ptr<aura::Window> panel0(CreatePanelWindow());
    542   scoped_ptr<aura::Window> panel1(CreatePanelWindow());
    543   wm::ActivateWindow(window2.get());
    544   wm::ActivateWindow(panel1.get());
    545   wm::ActivateWindow(panel0.get());
    546   wm::ActivateWindow(window1.get());
    547   wm::ActivateWindow(window0.get());
    548   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    549 
    550   // Cycling once highlights window2.
    551   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    552   // All panels are destroyed.
    553   panel0.reset();
    554   panel1.reset();
    555   // Cycling again should now select window2.
    556   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    557   controller->StopCycling();
    558   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
    559 }
    560 
    561 // Tests cycles between panel and normal windows.
    562 TEST_F(WindowCycleControllerTest, CycleMruPanelDestroyed) {
    563   WindowCycleController* controller =
    564       Shell::GetInstance()->window_cycle_controller();
    565 
    566   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    567   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    568   scoped_ptr<aura::Window> panel0(CreatePanelWindow());
    569   scoped_ptr<aura::Window> panel1(CreatePanelWindow());
    570   wm::ActivateWindow(panel1.get());
    571   wm::ActivateWindow(panel0.get());
    572   wm::ActivateWindow(window1.get());
    573   wm::ActivateWindow(window0.get());
    574   EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
    575 
    576   // Cycling once highlights window2.
    577   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    578 
    579   // Panel 1 is the next item as the MRU panel, removing it should make panel 2
    580   // the next window to be selected.
    581   panel0.reset();
    582   // Cycling again should now select panel1.
    583   controller->HandleCycleWindow(WindowCycleController::FORWARD);
    584   controller->StopCycling();
    585   EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
    586 }
    587 
    588 }  // namespace ash
    589