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