- add sources.
[platform/framework/web/crosswalk.git] / src / ash / wm / overview / window_selector_unittest.cc
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_launcher_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:
45   virtual bool ShouldActivate() const OVERRIDE {
46     return false;
47   }
48 };
49
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
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.
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:
103   WindowSelectorTest() {}
104   virtual ~WindowSelectorTest() {}
105
106   virtual void SetUp() OVERRIDE {
107     test::AshTestBase::SetUp();
108     ASSERT_TRUE(test::TestLauncherDelegate::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
115   aura::Window* CreateWindow(const gfx::Rect& bounds) {
116     return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds);
117   }
118
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
127   aura::Window* CreatePanelWindow(const gfx::Rect& bounds) {
128     aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
129         NULL, aura::client::WINDOW_TYPE_PANEL, 0, bounds);
130     test::TestLauncherDelegate::instance()->AddLauncherItem(window);
131     shelf_view_test()->RunMessageLoopUntilAnimationsDone();
132     return window;
133   }
134
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
141   void ToggleOverview() {
142     ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview();
143   }
144
145   void Cycle(WindowSelector::Direction direction) {
146     ash::Shell::GetInstance()->window_selector_controller()->
147         HandleCycleWindow(direction);
148   }
149
150   void StopCycling() {
151     ash::Shell::GetInstance()->window_selector_controller()->window_selector_->
152         SelectWindow();
153   }
154
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
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
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
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
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
197   bool IsSelecting() {
198     return ash::Shell::GetInstance()->window_selector_controller()->
199         IsSelecting();
200   }
201
202   aura::Window* GetFocusedWindow() {
203     return aura::client::GetFocusClient(
204         Shell::GetPrimaryRootWindow())->GetFocusedWindow();
205   }
206
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.
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 that the shelf dimming state is removed while in overview and restored
263 // on exiting overview.
264 TEST_F(WindowSelectorTest, OverviewUndimsShelf) {
265   gfx::Rect bounds(0, 0, 400, 400);
266   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
267   wm::WindowState* window_state = wm::GetWindowState(window1.get());
268   window_state->Maximize();
269   ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf();
270   EXPECT_TRUE(shelf->GetDimsShelf());
271   ToggleOverview();
272   EXPECT_FALSE(shelf->GetDimsShelf());
273   ToggleOverview();
274   EXPECT_TRUE(shelf->GetDimsShelf());
275 }
276
277 // Tests that beginning window selection hides the app list.
278 TEST_F(WindowSelectorTest, SelectingHidesAppList) {
279   gfx::Rect bounds(0, 0, 400, 400);
280   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
281   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
282   Shell::GetInstance()->ToggleAppList(NULL);
283   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
284   ToggleOverview();
285   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
286   ToggleOverview();
287
288   // The app list uses an animation to fade out. If it is toggled on immediately
289   // after being removed the old widget is re-used and it does not gain focus.
290   // When running under normal circumstances this shouldn't be possible, but
291   // it is in a test without letting the message loop run.
292   RunAllPendingInMessageLoop();
293
294   Shell::GetInstance()->ToggleAppList(NULL);
295   EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
296   Cycle(WindowSelector::FORWARD);
297   EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
298   StopCycling();
299 }
300
301 // Tests that a minimized window's visibility and layer visibility is correctly
302 // changed when entering overview and restored when leaving overview mode.
303 TEST_F(WindowSelectorTest, MinimizedWindowVisibility) {
304   gfx::Rect bounds(0, 0, 400, 400);
305   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
306   wm::WindowState* window_state = wm::GetWindowState(window1.get());
307   window_state->Minimize();
308   EXPECT_FALSE(window1->IsVisible());
309   EXPECT_FALSE(window1->layer()->GetTargetVisibility());
310   {
311     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
312         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
313     ToggleOverview();
314     EXPECT_TRUE(window1->IsVisible());
315     EXPECT_TRUE(window1->layer()->GetTargetVisibility());
316   }
317   {
318     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
319         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
320     ToggleOverview();
321     EXPECT_FALSE(window1->IsVisible());
322     EXPECT_FALSE(window1->layer()->GetTargetVisibility());
323   }
324 }
325
326 // Tests that a bounds change during overview is corrected for.
327 TEST_F(WindowSelectorTest, BoundsChangeDuringOverview) {
328   scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400)));
329   ToggleOverview();
330   gfx::Rect overview_bounds =
331       ToEnclosingRect(GetTransformedTargetBounds(window.get()));
332   window->SetBounds(gfx::Rect(200, 0, 200, 200));
333   gfx::Rect new_overview_bounds =
334       ToEnclosingRect(GetTransformedTargetBounds(window.get()));
335   EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
336   EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
337   EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
338   EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
339   ToggleOverview();
340 }
341
342 // Tests entering overview mode with three windows and cycling through them.
343 TEST_F(WindowSelectorTest, BasicCycle) {
344   gfx::Rect bounds(0, 0, 400, 400);
345   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
346   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
347   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
348   wm::ActivateWindow(window3.get());
349   wm::ActivateWindow(window2.get());
350   wm::ActivateWindow(window1.get());
351   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
352   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
353   EXPECT_FALSE(wm::IsActiveWindow(window3.get()));
354
355   Cycle(WindowSelector::FORWARD);
356   EXPECT_TRUE(IsSelecting());
357   Cycle(WindowSelector::FORWARD);
358   StopCycling();
359   EXPECT_FALSE(IsSelecting());
360   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
361   EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
362   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
363 }
364
365 // Tests that cycling through windows preserves the window stacking order.
366 TEST_F(WindowSelectorTest, CyclePreservesStackingOrder) {
367   gfx::Rect bounds(0, 0, 400, 400);
368   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
369   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
370   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
371   wm::ActivateWindow(window3.get());
372   wm::ActivateWindow(window2.get());
373   wm::ActivateWindow(window1.get());
374   // Window order from top to bottom is 1, 2, 3.
375   EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
376   EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get()));
377
378   // On window 2.
379   Cycle(WindowSelector::FORWARD);
380   EXPECT_TRUE(IsWindowAbove(window2.get(), window1.get()));
381   EXPECT_TRUE(IsWindowAbove(window1.get(), window3.get()));
382
383   // On window 3.
384   Cycle(WindowSelector::FORWARD);
385   EXPECT_TRUE(IsWindowAbove(window3.get(), window1.get()));
386   EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
387
388   // Back on window 1.
389   Cycle(WindowSelector::FORWARD);
390   EXPECT_TRUE(IsWindowAbove(window1.get(), window2.get()));
391   EXPECT_TRUE(IsWindowAbove(window2.get(), window3.get()));
392   StopCycling();
393 }
394
395 // Tests that cycling through windows shows and minimizes windows as they
396 // are passed.
397 TEST_F(WindowSelectorTest, CyclePreservesMinimization) {
398   gfx::Rect bounds(0, 0, 400, 400);
399   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
400   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
401   wm::ActivateWindow(window2.get());
402   wm::GetWindowState(window2.get())->Minimize();
403   wm::ActivateWindow(window1.get());
404   EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
405
406   // On window 2.
407   Cycle(WindowSelector::FORWARD);
408   EXPECT_FALSE(wm::IsWindowMinimized(window2.get()));
409
410   // Back on window 1.
411   Cycle(WindowSelector::FORWARD);
412   EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
413
414   StopCycling();
415   EXPECT_TRUE(wm::IsWindowMinimized(window2.get()));
416 }
417
418 // Tests beginning cycling while in overview mode.
419 TEST_F(WindowSelectorTest, OverviewTransitionToCycle) {
420   gfx::Rect bounds(0, 0, 400, 400);
421   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
422   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
423   wm::ActivateWindow(window2.get());
424   wm::ActivateWindow(window1.get());
425
426   ToggleOverview();
427   Cycle(WindowSelector::FORWARD);
428   StopCycling();
429
430   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
431   EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
432   EXPECT_EQ(window2.get(), GetFocusedWindow());
433 }
434
435 // Tests cycles between panel and normal windows.
436 TEST_F(WindowSelectorTest, CyclePanels) {
437   gfx::Rect bounds(0, 0, 400, 400);
438   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
439   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
440   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
441   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
442   wm::ActivateWindow(window2.get());
443   wm::ActivateWindow(window1.get());
444   wm::ActivateWindow(panel2.get());
445   wm::ActivateWindow(panel1.get());
446   EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
447
448   // Cycling once should select window1 since the panels are grouped into a
449   // single selectable item.
450   Cycle(WindowSelector::FORWARD);
451   StopCycling();
452   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
453
454   // Cycling again should select the most recently used panel.
455   Cycle(WindowSelector::FORWARD);
456   StopCycling();
457   EXPECT_TRUE(wm::IsActiveWindow(panel1.get()));
458 }
459
460 // Tests the visibility of panel windows during cycling.
461 TEST_F(WindowSelectorTest, CyclePanelVisibility) {
462   gfx::Rect bounds(0, 0, 400, 400);
463   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
464   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
465   wm::ActivateWindow(panel1.get());
466   wm::ActivateWindow(window1.get());
467
468   Cycle(WindowSelector::FORWARD);
469   FireOverviewStartTimer();
470   EXPECT_EQ(1.0f, panel1->layer()->GetTargetOpacity());
471   StopCycling();
472 }
473
474 // Tests cycles between panel and normal windows.
475 TEST_F(WindowSelectorTest, CyclePanelsDestroyed) {
476   gfx::Rect bounds(0, 0, 400, 400);
477   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
478   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
479   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
480   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
481   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
482   wm::ActivateWindow(window3.get());
483   wm::ActivateWindow(panel2.get());
484   wm::ActivateWindow(panel1.get());
485   wm::ActivateWindow(window2.get());
486   wm::ActivateWindow(window1.get());
487   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
488
489   // Cycling once highlights window2.
490   Cycle(WindowSelector::FORWARD);
491   // All panels are destroyed.
492   panel1.reset();
493   panel2.reset();
494   // Cycling again should now select window3.
495   Cycle(WindowSelector::FORWARD);
496   StopCycling();
497   EXPECT_TRUE(wm::IsActiveWindow(window3.get()));
498 }
499
500 // Tests cycles between panel and normal windows.
501 TEST_F(WindowSelectorTest, CycleMruPanelDestroyed) {
502   gfx::Rect bounds(0, 0, 400, 400);
503   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
504   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
505   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
506   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
507   wm::ActivateWindow(panel2.get());
508   wm::ActivateWindow(panel1.get());
509   wm::ActivateWindow(window2.get());
510   wm::ActivateWindow(window1.get());
511   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
512
513   // Cycling once highlights window2.
514   Cycle(WindowSelector::FORWARD);
515   // Panel 1 is the next item as the MRU panel, removing it should make panel 2
516   // the next window to be selected.
517   panel1.reset();
518   // Cycling again should now select window3.
519   Cycle(WindowSelector::FORWARD);
520   StopCycling();
521   EXPECT_TRUE(wm::IsActiveWindow(panel2.get()));
522 }
523
524 // Tests that a newly created window aborts overview.
525 TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) {
526   gfx::Rect bounds(0, 0, 400, 400);
527   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
528   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
529   ToggleOverview();
530   EXPECT_TRUE(IsSelecting());
531
532   // A window being created should exit overview mode.
533   scoped_ptr<aura::Window> window3(CreateWindow(bounds));
534   EXPECT_FALSE(IsSelecting());
535 }
536
537 // Tests that a window activation exits overview mode.
538 TEST_F(WindowSelectorTest, ActivationCancelsOveriew) {
539   gfx::Rect bounds(0, 0, 400, 400);
540   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
541   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
542   window2->Focus();
543   ToggleOverview();
544   EXPECT_TRUE(IsSelecting());
545
546   // A window being activated should exit overview mode.
547   window1->Focus();
548   EXPECT_FALSE(IsSelecting());
549
550   // window1 should be focused after exiting even though window2 was focused on
551   // entering overview because we exited due to an activation.
552   EXPECT_EQ(window1.get(), GetFocusedWindow());
553 }
554
555 // Verifies that overview mode only begins after a delay when cycling.
556 TEST_F(WindowSelectorTest, CycleOverviewDelay) {
557   gfx::Rect bounds(0, 0, 400, 400);
558   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
559   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
560   EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
561
562   // When cycling first starts, the windows will still be overlapping.
563   Cycle(WindowSelector::FORWARD);
564   EXPECT_TRUE(IsSelecting());
565   EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
566
567   // Once the overview timer fires, the windows should no longer overlap.
568   FireOverviewStartTimer();
569   EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
570   StopCycling();
571 }
572
573 // Tests that exiting overview mode without selecting a window restores focus
574 // to the previously focused window.
575 TEST_F(WindowSelectorTest, CancelRestoresFocus) {
576   gfx::Rect bounds(0, 0, 400, 400);
577   scoped_ptr<aura::Window> window(CreateWindow(bounds));
578   wm::ActivateWindow(window.get());
579   EXPECT_EQ(window.get(), GetFocusedWindow());
580
581   // In overview mode, focus should be removed.
582   ToggleOverview();
583   EXPECT_EQ(NULL, GetFocusedWindow());
584
585   // If canceling overview mode, focus should be restored.
586   ToggleOverview();
587   EXPECT_EQ(window.get(), GetFocusedWindow());
588 }
589
590 // Tests that overview mode is exited if the last remaining window is destroyed.
591 TEST_F(WindowSelectorTest, LastWindowDestroyed) {
592   gfx::Rect bounds(0, 0, 400, 400);
593   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
594   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
595   ToggleOverview();
596
597   window1.reset();
598   window2.reset();
599   EXPECT_FALSE(IsSelecting());
600 }
601
602 // Tests that entering overview mode restores a window to its original
603 // target location.
604 TEST_F(WindowSelectorTest, QuickReentryRestoresInitialTransform) {
605   gfx::Rect bounds(0, 0, 400, 400);
606   scoped_ptr<aura::Window> window(CreateWindow(bounds));
607   gfx::Rect initial_bounds = ToEnclosingRect(
608       GetTransformedBounds(window.get()));
609   ToggleOverview();
610   // Quickly exit and reenter overview mode. The window should still be
611   // animating when we reenter. We cannot short circuit animations for this but
612   // we also don't have to wait for them to complete.
613   {
614     ui::ScopedAnimationDurationScaleMode normal_duration_mode(
615         ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
616     ToggleOverview();
617     ToggleOverview();
618   }
619   EXPECT_NE(initial_bounds, ToEnclosingRect(
620       GetTransformedTargetBounds(window.get())));
621   ToggleOverview();
622   EXPECT_FALSE(IsSelecting());
623   EXPECT_EQ(initial_bounds, ToEnclosingRect(
624       GetTransformedTargetBounds(window.get())));
625 }
626
627 // Tests that non-activatable windows are hidden when entering overview mode.
628 TEST_F(WindowSelectorTest, NonActivatableWindowsHidden) {
629   gfx::Rect bounds(0, 0, 400, 400);
630   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
631   scoped_ptr<aura::Window> window2(CreateWindow(bounds));
632   scoped_ptr<aura::Window> non_activatable_window(
633       CreateNonActivatableWindow(Shell::GetPrimaryRootWindow()->bounds()));
634   EXPECT_TRUE(non_activatable_window->IsVisible());
635   ToggleOverview();
636   EXPECT_FALSE(non_activatable_window->IsVisible());
637   ToggleOverview();
638   EXPECT_TRUE(non_activatable_window->IsVisible());
639
640   // Test that a window behind the fullscreen non-activatable window can be
641   // clicked.
642   non_activatable_window->parent()->StackChildAtTop(
643       non_activatable_window.get());
644   ToggleOverview();
645   ClickWindow(window1.get());
646   EXPECT_FALSE(IsSelecting());
647   EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
648 }
649
650 // Tests that windows with modal child windows are transformed with the modal
651 // child even though not activatable themselves.
652 TEST_F(WindowSelectorTest, ModalChild) {
653   gfx::Rect bounds(0, 0, 400, 400);
654   scoped_ptr<aura::Window> window1(CreateWindow(bounds));
655   scoped_ptr<aura::Window> child1(CreateWindow(bounds));
656   child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
657   window1->AddTransientChild(child1.get());
658   EXPECT_EQ(window1->parent(), child1->parent());
659   ToggleOverview();
660   EXPECT_TRUE(window1->IsVisible());
661   EXPECT_TRUE(child1->IsVisible());
662   EXPECT_EQ(ToEnclosingRect(GetTransformedTargetBounds(child1.get())),
663       ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
664   ToggleOverview();
665 }
666
667 // Tests that clicking a modal window's parent activates the modal window in
668 // overview.
669 TEST_F(WindowSelectorTest, ClickModalWindowParent) {
670   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 180, 180)));
671   scoped_ptr<aura::Window> child1(CreateWindow(gfx::Rect(200, 0, 180, 180)));
672   child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
673   window1->AddTransientChild(child1.get());
674   EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
675   EXPECT_EQ(window1->parent(), child1->parent());
676   ToggleOverview();
677   // Given that their relative positions are preserved, the windows should still
678   // not overlap.
679   EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
680   ClickWindow(window1.get());
681   EXPECT_FALSE(IsSelecting());
682
683   // Clicking on window1 should activate child1.
684   EXPECT_TRUE(wm::IsActiveWindow(child1.get()));
685 }
686
687 // Tests that windows remain on the display they are currently on in overview
688 // mode.
689 TEST_F(WindowSelectorTest, MultipleDisplays) {
690   if (!SupportsMultipleDisplays())
691     return;
692
693   UpdateDisplay("600x400,600x400");
694   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
695   gfx::Rect bounds1(0, 0, 400, 400);
696   gfx::Rect bounds2(650, 0, 400, 400);
697
698   scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
699   scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
700   scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
701   scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
702   scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1));
703   scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds1));
704   scoped_ptr<aura::Window> panel3(CreatePanelWindow(bounds2));
705   scoped_ptr<aura::Window> panel4(CreatePanelWindow(bounds2));
706   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
707   EXPECT_EQ(root_windows[0], window2->GetRootWindow());
708   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
709   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
710
711   EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
712   EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
713   EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
714   EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
715
716   // In overview mode, each window remains in the same root window.
717   ToggleOverview();
718   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
719   EXPECT_EQ(root_windows[0], window2->GetRootWindow());
720   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
721   EXPECT_EQ(root_windows[1], window4->GetRootWindow());
722   EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
723   EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
724   EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
725   EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
726
727   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
728       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
729   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
730       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
731   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
732       ToEnclosingRect(GetTransformedTargetBounds(window3.get()))));
733   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
734       ToEnclosingRect(GetTransformedTargetBounds(window4.get()))));
735
736   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
737       ToEnclosingRect(GetTransformedTargetBounds(panel1.get()))));
738   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
739       ToEnclosingRect(GetTransformedTargetBounds(panel2.get()))));
740   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
741       ToEnclosingRect(GetTransformedTargetBounds(panel3.get()))));
742   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
743       ToEnclosingRect(GetTransformedTargetBounds(panel4.get()))));
744   EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
745   EXPECT_TRUE(WindowsOverlapping(panel3.get(), panel4.get()));
746   EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel3.get()));
747 }
748
749 // Verifies that the single display overview used during alt tab cycling uses
750 // the display of the initial window by default.
751 TEST_F(WindowSelectorTest, CycleOverviewUsesInitialDisplay) {
752   if (!SupportsMultipleDisplays())
753     return;
754
755   UpdateDisplay("400x400,400x400");
756   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
757
758   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
759   scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
760   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
761   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
762   wm::ActivateWindow(window2.get());
763   wm::ActivateWindow(window1.get());
764   EXPECT_EQ(root_windows[0], Shell::GetTargetRootWindow());
765
766   Cycle(WindowSelector::FORWARD);
767   FireOverviewStartTimer();
768
769   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
770       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
771   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
772       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
773   StopCycling();
774 }
775
776 // Verifies that the windows being shown on another display are copied.
777 TEST_F(WindowSelectorTest, CycleMultipleDisplaysCopiesWindows) {
778   if (!SupportsMultipleDisplays())
779     return;
780
781   UpdateDisplay("400x400,400x400");
782   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
783
784   gfx::Rect root1_rect(0, 0, 100, 100);
785   gfx::Rect root2_rect(450, 0, 100, 100);
786   scoped_ptr<aura::Window> unmoved1(CreateWindow(root2_rect));
787   scoped_ptr<aura::Window> unmoved2(CreateWindow(root2_rect));
788   scoped_ptr<aura::Window> moved1_trans_parent(CreateWindow(root1_rect));
789   scoped_ptr<aura::Window> moved1(CreateWindow(root1_rect));
790   unmoved1->SetName("unmoved1");
791   unmoved2->SetName("unmoved2");
792   moved1->SetName("moved1");
793   moved1->SetProperty(aura::client::kModalKey,
794                       ui::MODAL_TYPE_WINDOW);
795   moved1_trans_parent->AddTransientChild(moved1.get());
796   moved1_trans_parent->SetName("moved1_trans_parent");
797
798   EXPECT_EQ(root_windows[0], moved1->GetRootWindow());
799   EXPECT_EQ(root_windows[0], moved1_trans_parent->GetRootWindow());
800   EXPECT_EQ(root_windows[1], unmoved1->GetRootWindow());
801   EXPECT_EQ(root_windows[1], unmoved2->GetRootWindow());
802   wm::ActivateWindow(unmoved2.get());
803   wm::ActivateWindow(unmoved1.get());
804
805   Cycle(WindowSelector::FORWARD);
806   FireOverviewStartTimer();
807
808   // All windows are moved to second root window.
809   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
810       ToEnclosingRect(GetTransformedTargetBounds(unmoved1.get()))));
811   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
812       ToEnclosingRect(GetTransformedTargetBounds(unmoved2.get()))));
813   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
814       ToEnclosingRect(GetTransformedTargetBounds(moved1.get()))));
815   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
816       ToEnclosingRect(GetTransformedTargetBounds(moved1_trans_parent.get()))));
817
818   // unmoved1 and unmoved2 were already on the correct display and should not
819   // have been copied.
820   EXPECT_TRUE(!GetCopyWindow(unmoved1.get()));
821   EXPECT_TRUE(!GetCopyWindow(unmoved2.get()));
822
823   // moved1 and its transient parent moved1_trans_parent should have also been
824   // copied for displaying on root_windows[1].
825   aura::Window* copy1 = GetCopyWindow(moved1.get());
826   aura::Window* copy1_trans_parent = GetCopyWindow(moved1_trans_parent.get());
827   ASSERT_FALSE(!copy1);
828   ASSERT_FALSE(!copy1_trans_parent);
829
830   // Verify that the bounds and transform of the copy match the original window
831   // but that it is on the other root window.
832   EXPECT_EQ(root_windows[1], copy1->GetRootWindow());
833   EXPECT_EQ(moved1->GetBoundsInScreen(), copy1->GetBoundsInScreen());
834   EXPECT_EQ(moved1->layer()->GetTargetTransform(),
835             copy1->layer()->GetTargetTransform());
836   StopCycling();
837
838   // After cycling the copy windows should have been destroyed.
839   RunAllPendingInMessageLoop();
840   EXPECT_TRUE(!GetCopyWindow(moved1.get()));
841   EXPECT_TRUE(!GetCopyWindow(moved1_trans_parent.get()));
842 }
843
844 // Tests that beginning to cycle from overview mode moves windows to the
845 // active display.
846 TEST_F(WindowSelectorTest, MultipleDisplaysOverviewTransitionToCycle) {
847   if (!SupportsMultipleDisplays())
848     return;
849
850   UpdateDisplay("400x400,400x400");
851   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
852
853   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
854   scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
855   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
856   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
857   wm::ActivateWindow(window2.get());
858   wm::ActivateWindow(window1.get());
859
860   ToggleOverview();
861   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
862       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
863   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(
864       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
865
866   Cycle(WindowSelector::FORWARD);
867   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
868       ToEnclosingRect(GetTransformedTargetBounds(window1.get()))));
869   EXPECT_TRUE(root_windows[0]->GetBoundsInScreen().Contains(
870       ToEnclosingRect(GetTransformedTargetBounds(window2.get()))));
871   StopCycling();
872 }
873
874 // Tests that a bounds change during overview is corrected for.
875 TEST_F(WindowSelectorTest, BoundsChangeDuringCycleOnOtherDisplay) {
876   if (!SupportsMultipleDisplays())
877     return;
878
879   UpdateDisplay("400x400,400x400");
880   Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
881
882   scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 100, 100)));
883   scoped_ptr<aura::Window> window2(CreateWindow(gfx::Rect(450, 0, 100, 100)));
884   scoped_ptr<aura::Window> window3(CreateWindow(gfx::Rect(450, 0, 100, 100)));
885   EXPECT_EQ(root_windows[0], window1->GetRootWindow());
886   EXPECT_EQ(root_windows[1], window2->GetRootWindow());
887   EXPECT_EQ(root_windows[1], window3->GetRootWindow());
888   wm::ActivateWindow(window1.get());
889   wm::ActivateWindow(window2.get());
890   wm::ActivateWindow(window3.get());
891
892   Cycle(WindowSelector::FORWARD);
893   FireOverviewStartTimer();
894
895   gfx::Rect overview_bounds(
896       ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
897   EXPECT_TRUE(root_windows[1]->GetBoundsInScreen().Contains(overview_bounds));
898
899   // Change the position and size of window1 (being displayed on the second
900   // root window) and it should remain within the same bounds.
901   window1->SetBounds(gfx::Rect(100, 0, 200, 200));
902   gfx::Rect new_overview_bounds =
903       ToEnclosingRect(GetTransformedTargetBounds(window1.get()));
904   EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
905   EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
906   EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
907   EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
908   StopCycling();
909 }
910
911 }  // namespace internal
912 }  // namespace ash