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