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