Disable Vsync when Aero Glass is enabled.
[chromium-blink-merge.git] / ash / wm / window_cycle_controller_unittest.cc
blob67df90ef2f6e24562243107fea179b5d0e702a03
1 // Copyright (c) 2012 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.
5 #include "ash/wm/window_cycle_controller.h"
7 #include <algorithm>
9 #include "ash/session_state_delegate.h"
10 #include "ash/shell.h"
11 #include "ash/shell_window_ids.h"
12 #include "ash/test/ash_test_base.h"
13 #include "ash/test/test_shell_delegate.h"
14 #include "ash/wm/window_cycle_list.h"
15 #include "ash/wm/window_state.h"
16 #include "ash/wm/window_util.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "ui/aura/client/aura_constants.h"
19 #include "ui/aura/client/screen_position_client.h"
20 #include "ui/aura/env.h"
21 #include "ui/aura/root_window.h"
22 #include "ui/aura/test/test_windows.h"
23 #include "ui/aura/window.h"
24 #include "ui/gfx/rect.h"
25 #include "ui/gfx/screen.h"
27 namespace ash {
29 namespace {
31 using aura::test::CreateTestWindowWithId;
32 using aura::test::TestWindowDelegate;
33 using aura::Window;
35 typedef test::AshTestBase WindowCycleControllerTest;
37 TEST_F(WindowCycleControllerTest, HandleCycleWindowBaseCases) {
38 WindowCycleController* controller =
39 Shell::GetInstance()->window_cycle_controller();
41 // Cycling doesn't crash if there are no windows.
42 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
44 // Create a single test window.
45 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
46 wm::ActivateWindow(window0.get());
47 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
49 // Cycling works for a single window, even though nothing changes.
50 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
51 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
54 // Verifies if there is only one window and it isn't active that cycling
55 // activates it.
56 TEST_F(WindowCycleControllerTest, SingleWindowNotActive) {
57 WindowCycleController* controller =
58 Shell::GetInstance()->window_cycle_controller();
60 // Create a single test window.
61 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
62 wm::ActivateWindow(window0.get());
63 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
65 // Rotate focus, this should move focus to another window that isn't part of
66 // the default container.
67 Shell::GetInstance()->RotateFocus(Shell::FORWARD);
68 EXPECT_FALSE(wm::IsActiveWindow(window0.get()));
70 // Cycling should activate the window.
71 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
72 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
75 TEST_F(WindowCycleControllerTest, HandleCycleWindow) {
76 WindowCycleController* controller =
77 Shell::GetInstance()->window_cycle_controller();
79 // Set up several windows to use to test cycling. Create them in reverse
80 // order so they are stacked 0 over 1 over 2.
81 scoped_ptr<Window> window2(CreateTestWindowInShellWithId(2));
82 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
83 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
84 wm::ActivateWindow(window0.get());
86 // Simulate pressing and releasing Alt-tab.
87 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
88 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
90 // Window lists should return the topmost window in front.
91 ASSERT_TRUE(controller->windows());
92 ASSERT_EQ(3u, controller->windows()->windows().size());
93 ASSERT_EQ(window0.get(), controller->windows()->windows()[0]);
94 ASSERT_EQ(window1.get(), controller->windows()->windows()[1]);
95 ASSERT_EQ(window2.get(), controller->windows()->windows()[2]);
97 controller->AltKeyReleased();
98 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
100 // Pressing and releasing Alt-tab again should cycle back to the most-
101 // recently-used window in the current child order.
102 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
103 controller->AltKeyReleased();
104 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
106 // Pressing Alt-tab multiple times without releasing Alt should cycle through
107 // all the windows and wrap around.
108 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
109 EXPECT_TRUE(controller->IsCycling());
110 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
112 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
113 EXPECT_TRUE(controller->IsCycling());
114 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
116 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
117 EXPECT_TRUE(controller->IsCycling());
118 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
120 controller->AltKeyReleased();
121 EXPECT_FALSE(controller->IsCycling());
122 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
124 // Reset our stacking order.
125 wm::ActivateWindow(window2.get());
126 wm::ActivateWindow(window1.get());
127 wm::ActivateWindow(window0.get());
129 // Likewise we can cycle backwards through all the windows.
130 controller->HandleCycleWindow(WindowCycleController::BACKWARD, true);
131 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
132 controller->HandleCycleWindow(WindowCycleController::BACKWARD, true);
133 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
134 controller->HandleCycleWindow(WindowCycleController::BACKWARD, true);
135 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
136 controller->AltKeyReleased();
137 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
139 // Passing false for is_alt_down does not start a cycle gesture.
140 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
141 EXPECT_FALSE(controller->IsCycling());
142 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
144 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
145 EXPECT_FALSE(controller->IsCycling());
146 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
148 // When the screen is locked, cycling window does not take effect.
149 Shell::GetInstance()->session_state_delegate()->LockScreen();
150 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
151 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
152 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
153 controller->HandleCycleWindow(WindowCycleController::BACKWARD, false);
154 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
156 Shell::GetInstance()->session_state_delegate()->UnlockScreen();
157 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
158 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
159 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
160 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
161 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
163 // When a modal window is active, cycling window does not take effect.
164 aura::Window* modal_container =
165 ash::Shell::GetContainer(
166 Shell::GetPrimaryRootWindow(),
167 internal::kShellWindowId_SystemModalContainer);
168 scoped_ptr<Window> modal_window(
169 CreateTestWindowWithId(-2, modal_container));
170 modal_window->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_SYSTEM);
171 wm::ActivateWindow(modal_window.get());
172 EXPECT_TRUE(wm::IsActiveWindow(modal_window.get()));
173 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
174 EXPECT_TRUE(wm::IsActiveWindow(modal_window.get()));
175 EXPECT_FALSE(wm::IsActiveWindow(window0.get()));
176 EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
177 EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
178 controller->HandleCycleWindow(WindowCycleController::BACKWARD, false);
179 EXPECT_TRUE(wm::IsActiveWindow(modal_window.get()));
180 EXPECT_FALSE(wm::IsActiveWindow(window0.get()));
181 EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
182 EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
185 // Cycles between a maximized and normal window.
186 TEST_F(WindowCycleControllerTest, MaximizedWindow) {
187 // Create a couple of test windows.
188 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
189 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
190 wm::WindowState* window1_state = wm::GetWindowState(window1.get());
191 window1_state->Maximize();
192 window1_state->Activate();
193 EXPECT_TRUE(window1_state->IsActive());
195 // Rotate focus, this should move focus to window0.
196 WindowCycleController* controller =
197 Shell::GetInstance()->window_cycle_controller();
198 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
199 EXPECT_TRUE(wm::GetWindowState(window0.get())->IsActive());
201 // One more time.
202 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
203 EXPECT_TRUE(window1_state->IsActive());
206 // Cycles to a minimized window.
207 TEST_F(WindowCycleControllerTest, Minimized) {
208 // Create a couple of test windows.
209 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
210 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
211 wm::WindowState* window0_state = wm::GetWindowState(window0.get());
212 wm::WindowState* window1_state = wm::GetWindowState(window1.get());
214 window1_state->Minimize();
215 window0_state->Activate();
216 EXPECT_TRUE(window0_state->IsActive());
218 // Rotate focus, this should move focus to window1 and unminimize it.
219 WindowCycleController* controller =
220 Shell::GetInstance()->window_cycle_controller();
221 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
222 EXPECT_FALSE(window1_state->IsMinimized());
223 EXPECT_TRUE(window1_state->IsActive());
225 // One more time back to w0.
226 controller->HandleCycleWindow(WindowCycleController::FORWARD, false);
227 EXPECT_TRUE(window0_state->IsActive());
230 TEST_F(WindowCycleControllerTest, AlwaysOnTopWindow) {
231 WindowCycleController* controller =
232 Shell::GetInstance()->window_cycle_controller();
234 // Set up several windows to use to test cycling.
235 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
236 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
238 Window* top_container =
239 Shell::GetContainer(
240 Shell::GetPrimaryRootWindow(),
241 internal::kShellWindowId_AlwaysOnTopContainer);
242 scoped_ptr<Window> window2(CreateTestWindowWithId(2, top_container));
243 wm::ActivateWindow(window0.get());
245 // Simulate pressing and releasing Alt-tab.
246 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
247 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
249 // Window lists should return the topmost window in front.
250 ASSERT_TRUE(controller->windows());
251 ASSERT_EQ(3u, controller->windows()->windows().size());
252 EXPECT_EQ(window0.get(), controller->windows()->windows()[0]);
253 EXPECT_EQ(window2.get(), controller->windows()->windows()[1]);
254 EXPECT_EQ(window1.get(), controller->windows()->windows()[2]);
256 controller->AltKeyReleased();
257 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
259 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
260 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
262 controller->AltKeyReleased();
264 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
265 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
267 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
268 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
270 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
271 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
274 TEST_F(WindowCycleControllerTest, AlwaysOnTopMultiWindow) {
275 WindowCycleController* controller =
276 Shell::GetInstance()->window_cycle_controller();
278 // Set up several windows to use to test cycling.
279 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
280 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
282 Window* top_container =
283 Shell::GetContainer(
284 Shell::GetPrimaryRootWindow(),
285 internal::kShellWindowId_AlwaysOnTopContainer);
286 scoped_ptr<Window> window2(CreateTestWindowWithId(2, top_container));
287 scoped_ptr<Window> window3(CreateTestWindowWithId(3, top_container));
288 wm::ActivateWindow(window0.get());
290 // Simulate pressing and releasing Alt-tab.
291 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
292 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
294 // Window lists should return the topmost window in front.
295 ASSERT_TRUE(controller->windows());
296 ASSERT_EQ(4u, controller->windows()->windows().size());
297 EXPECT_EQ(window0.get(), controller->windows()->windows()[0]);
298 EXPECT_EQ(window3.get(), controller->windows()->windows()[1]);
299 EXPECT_EQ(window2.get(), controller->windows()->windows()[2]);
300 EXPECT_EQ(window1.get(), controller->windows()->windows()[3]);
302 controller->AltKeyReleased();
303 EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
305 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
306 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
308 controller->AltKeyReleased();
310 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
311 EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
313 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
314 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
316 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
317 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
319 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
320 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
323 TEST_F(WindowCycleControllerTest, AlwaysOnTopMultipleRootWindows) {
324 if (!SupportsMultipleDisplays())
325 return;
327 // Set up a second root window
328 UpdateDisplay("1000x600,600x400");
329 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
330 ASSERT_EQ(2U, root_windows.size());
332 WindowCycleController* controller =
333 Shell::GetInstance()->window_cycle_controller();
335 Shell::GetInstance()->set_target_root_window(root_windows[0]);
337 // Create two windows in the primary root.
338 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
339 EXPECT_EQ(root_windows[0], window0->GetRootWindow());
340 Window* top_container0 =
341 Shell::GetContainer(
342 root_windows[0],
343 internal::kShellWindowId_AlwaysOnTopContainer);
344 scoped_ptr<Window> window1(CreateTestWindowWithId(1, top_container0));
345 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
347 // And two on the secondary root.
348 Shell::GetInstance()->set_target_root_window(root_windows[1]);
349 scoped_ptr<Window> window2(CreateTestWindowInShellWithId(2));
350 EXPECT_EQ(root_windows[1], window2->GetRootWindow());
352 Window* top_container1 =
353 Shell::GetContainer(
354 root_windows[1],
355 internal::kShellWindowId_AlwaysOnTopContainer);
356 scoped_ptr<Window> window3(CreateTestWindowWithId(3, top_container1));
357 EXPECT_EQ(root_windows[1], window3->GetRootWindow());
359 // Move the active root window to the secondary.
360 Shell::GetInstance()->set_target_root_window(root_windows[1]);
362 wm::ActivateWindow(window2.get());
364 EXPECT_EQ(root_windows[0], window0->GetRootWindow());
365 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
366 EXPECT_EQ(root_windows[1], window2->GetRootWindow());
367 EXPECT_EQ(root_windows[1], window3->GetRootWindow());
369 // Simulate pressing and releasing Alt-tab.
370 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
371 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
373 // Window lists should return the topmost window in front.
374 ASSERT_TRUE(controller->windows());
375 ASSERT_EQ(4u, controller->windows()->windows().size());
376 EXPECT_EQ(window2.get(), controller->windows()->windows()[0]);
377 EXPECT_EQ(window3.get(), controller->windows()->windows()[1]);
378 EXPECT_EQ(window1.get(), controller->windows()->windows()[2]);
379 EXPECT_EQ(window0.get(), controller->windows()->windows()[3]);
381 controller->AltKeyReleased();
382 EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
384 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
385 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
387 controller->AltKeyReleased();
389 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
390 EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
392 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
393 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
395 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
396 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
398 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
399 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
402 TEST_F(WindowCycleControllerTest, MostRecentlyUsed) {
403 WindowCycleController* controller =
404 Shell::GetInstance()->window_cycle_controller();
406 // Set up several windows to use to test cycling.
407 scoped_ptr<Window> window0(CreateTestWindowInShellWithId(0));
408 scoped_ptr<Window> window1(CreateTestWindowInShellWithId(1));
409 scoped_ptr<Window> window2(CreateTestWindowInShellWithId(2));
411 wm::ActivateWindow(window0.get());
413 // Simulate pressing and releasing Alt-tab.
414 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
415 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
417 // Window lists should return the topmost window in front.
418 ASSERT_TRUE(controller->windows());
419 ASSERT_EQ(3u, controller->windows()->windows().size());
420 EXPECT_EQ(window0.get(), controller->windows()->windows()[0]);
421 EXPECT_EQ(window2.get(), controller->windows()->windows()[1]);
422 EXPECT_EQ(window1.get(), controller->windows()->windows()[2]);
424 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
425 controller->AltKeyReleased();
426 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
429 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
430 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
432 controller->AltKeyReleased();
434 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
435 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
437 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
438 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
440 controller->HandleCycleWindow(WindowCycleController::FORWARD, true);
441 EXPECT_TRUE(wm::IsActiveWindow(window0.get()));
444 } // namespace
446 } // namespace ash