Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / ash / wm / overview / window_selector_unittest.cc
blob6bea3bd2a0b0661a480db08a861de0a60623fdce
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.
5 #include <algorithm>
6 #include <vector>
8 #include "ash/accessibility_delegate.h"
9 #include "ash/ash_switches.h"
10 #include "ash/display/display_layout.h"
11 #include "ash/drag_drop/drag_drop_controller.h"
12 #include "ash/root_window_controller.h"
13 #include "ash/screen_util.h"
14 #include "ash/shelf/shelf.h"
15 #include "ash/shelf/shelf_widget.h"
16 #include "ash/shell.h"
17 #include "ash/shell_window_ids.h"
18 #include "ash/test/ash_test_base.h"
19 #include "ash/test/shelf_test_api.h"
20 #include "ash/test/shelf_view_test_api.h"
21 #include "ash/test/shell_test_api.h"
22 #include "ash/test/test_shelf_delegate.h"
23 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
24 #include "ash/wm/mru_window_tracker.h"
25 #include "ash/wm/overview/window_grid.h"
26 #include "ash/wm/overview/window_selector.h"
27 #include "ash/wm/overview/window_selector_controller.h"
28 #include "ash/wm/overview/window_selector_item.h"
29 #include "ash/wm/panels/panel_layout_manager.h"
30 #include "ash/wm/window_state.h"
31 #include "ash/wm/window_util.h"
32 #include "ash/wm/wm_event.h"
33 #include "base/basictypes.h"
34 #include "base/command_line.h"
35 #include "base/compiler_specific.h"
36 #include "base/memory/scoped_vector.h"
37 #include "base/run_loop.h"
38 #include "base/strings/string_piece.h"
39 #include "base/strings/utf_string_conversions.h"
40 #include "base/test/user_action_tester.h"
41 #include "ui/aura/client/aura_constants.h"
42 #include "ui/aura/client/cursor_client.h"
43 #include "ui/aura/client/focus_client.h"
44 #include "ui/aura/test/test_window_delegate.h"
45 #include "ui/aura/test/test_windows.h"
46 #include "ui/aura/window.h"
47 #include "ui/aura/window_event_dispatcher.h"
48 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
49 #include "ui/events/event_utils.h"
50 #include "ui/events/test/event_generator.h"
51 #include "ui/gfx/geometry/point_conversions.h"
52 #include "ui/gfx/geometry/rect_conversions.h"
53 #include "ui/gfx/transform.h"
54 #include "ui/gfx/transform_util.h"
55 #include "ui/views/controls/button/label_button.h"
56 #include "ui/views/widget/native_widget_aura.h"
57 #include "ui/views/widget/widget_delegate.h"
58 #include "ui/wm/core/window_util.h"
59 #include "ui/wm/public/activation_delegate.h"
61 namespace ash {
62 namespace {
64 const char kActiveWindowChangedFromOverview[] =
65 "WindowSelector_ActiveWindowChanged";
67 class NonActivatableActivationDelegate
68 : public aura::client::ActivationDelegate {
69 public:
70 bool ShouldActivate() const override { return false; }
73 void CancelDrag(DragDropController* controller, bool* canceled) {
74 if (controller->IsDragDropInProgress()) {
75 *canceled = true;
76 controller->DragCancel();
80 } // namespace
82 // TODO(bruthig): Move all non-simple method definitions out of class
83 // declaration.
84 class WindowSelectorTest : public test::AshTestBase {
85 public:
86 WindowSelectorTest() {}
87 ~WindowSelectorTest() override {}
89 void SetUp() override {
90 base::CommandLine::ForCurrentProcess()->AppendSwitch(
91 switches::kAshEnableStableOverviewOrder);
92 test::AshTestBase::SetUp();
93 ASSERT_TRUE(test::TestShelfDelegate::instance());
95 shelf_view_test_.reset(new test::ShelfViewTestAPI(
96 test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view()));
97 shelf_view_test_->SetAnimationDuration(1);
100 aura::Window* CreateWindow(const gfx::Rect& bounds) {
101 return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds);
104 aura::Window* CreateWindowWithId(const gfx::Rect& bounds, int id) {
105 return CreateTestWindowInShellWithDelegate(&delegate_, id, bounds);
107 aura::Window* CreateNonActivatableWindow(const gfx::Rect& bounds) {
108 aura::Window* window = CreateWindow(bounds);
109 aura::client::SetActivationDelegate(window,
110 &non_activatable_activation_delegate_);
111 EXPECT_FALSE(ash::wm::CanActivateWindow(window));
112 return window;
115 // Creates a Widget containing a Window with the given |bounds|. This should
116 // be used when the test requires a Widget. For example any test that will
117 // cause a window to be closed via
118 // views::Widget::GetWidgetForNativeView(window)->Close().
119 scoped_ptr<views::Widget> CreateWindowWidget(const gfx::Rect& bounds) {
120 scoped_ptr<views::Widget> widget(new views::Widget);
121 views::Widget::InitParams params;
122 params.bounds = bounds;
123 params.type = views::Widget::InitParams::TYPE_WINDOW;
124 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
125 widget->Init(params);
126 widget->Show();
127 ParentWindowInPrimaryRootWindow(widget->GetNativeWindow());
128 return widget.Pass();
131 aura::Window* CreatePanelWindow(const gfx::Rect& bounds) {
132 aura::Window* window = CreateTestWindowInShellWithDelegateAndType(
133 nullptr, ui::wm::WINDOW_TYPE_PANEL, 0, bounds);
134 test::TestShelfDelegate::instance()->AddShelfItem(window);
135 shelf_view_test()->RunMessageLoopUntilAnimationsDone();
136 return window;
139 bool WindowsOverlapping(aura::Window* window1, aura::Window* window2) {
140 gfx::RectF window1_bounds = GetTransformedTargetBounds(window1);
141 gfx::RectF window2_bounds = GetTransformedTargetBounds(window2);
142 return window1_bounds.Intersects(window2_bounds);
145 void ToggleOverview() {
146 ash::Shell::GetInstance()->window_selector_controller()->ToggleOverview();
149 gfx::RectF GetTransformedBounds(aura::Window* window) {
150 gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
151 window->parent(), window->layer()->bounds()));
152 gfx::Transform transform(gfx::TransformAboutPivot(
153 gfx::ToFlooredPoint(bounds.origin()),
154 window->layer()->transform()));
155 transform.TransformRect(&bounds);
156 return bounds;
159 gfx::RectF GetTransformedTargetBounds(aura::Window* window) {
160 gfx::RectF bounds(ScreenUtil::ConvertRectToScreen(
161 window->parent(), window->layer()->GetTargetBounds()));
162 gfx::Transform transform(gfx::TransformAboutPivot(
163 gfx::ToFlooredPoint(bounds.origin()),
164 window->layer()->GetTargetTransform()));
165 transform.TransformRect(&bounds);
166 return bounds;
169 gfx::RectF GetTransformedBoundsInRootWindow(aura::Window* window) {
170 gfx::RectF bounds = gfx::Rect(window->bounds().size());
171 aura::Window* root = window->GetRootWindow();
172 CHECK(window->layer());
173 CHECK(root->layer());
174 gfx::Transform transform;
175 if (!window->layer()->GetTargetTransformRelativeTo(root->layer(),
176 &transform)) {
177 return gfx::RectF();
179 transform.TransformRect(&bounds);
180 return bounds;
183 void ClickWindow(aura::Window* window) {
184 ui::test::EventGenerator event_generator(window->GetRootWindow(), window);
185 gfx::RectF target = GetTransformedBounds(window);
186 event_generator.ClickLeftButton();
189 void SendKey(ui::KeyboardCode key) {
190 ui::test::EventGenerator event_generator(Shell::GetPrimaryRootWindow());
191 event_generator.PressKey(key, 0);
192 event_generator.ReleaseKey(key, 0);
195 bool IsSelecting() {
196 return ash::Shell::GetInstance()->window_selector_controller()->
197 IsSelecting();
200 aura::Window* GetFocusedWindow() {
201 return aura::client::GetFocusClient(
202 Shell::GetPrimaryRootWindow())->GetFocusedWindow();
205 const std::vector<WindowSelectorItem*>& GetWindowItemsForRoot(int index) {
206 return ash::Shell::GetInstance()->window_selector_controller()->
207 window_selector_->grid_list_[index]->window_list_.get();
210 WindowSelectorItem* GetWindowItemForWindow(int grid_index,
211 aura::Window* window) {
212 const std::vector<WindowSelectorItem*>& windows =
213 GetWindowItemsForRoot(grid_index);
214 auto iter = std::find_if(windows.cbegin(), windows.cend(),
215 [window](const WindowSelectorItem* item) {
216 return item->Contains(window);
218 if (iter == windows.end())
219 return nullptr;
220 return *iter;
223 // Selects |window| in the active overview session by cycling through all
224 // windows in overview until it is found. Returns true if |window| was found,
225 // false otherwise.
226 bool SelectWindow(const aura::Window* window) {
227 if (GetSelectedWindow() == nullptr)
228 SendKey(ui::VKEY_TAB);
229 const aura::Window* start_window = GetSelectedWindow();
230 if (start_window == window)
231 return true;
232 do {
233 SendKey(ui::VKEY_TAB);
234 } while (GetSelectedWindow() != window &&
235 GetSelectedWindow() != start_window);
236 return GetSelectedWindow() == window;
239 const aura::Window* GetSelectedWindow() {
240 WindowSelector* ws = ash::Shell::GetInstance()->
241 window_selector_controller()->window_selector_.get();
242 WindowSelectorItem* item =
243 ws->grid_list_[ws->selected_grid_index_]->SelectedWindow();
244 if (!item)
245 return nullptr;
246 return item->GetWindow();
249 bool selection_widget_active() {
250 WindowSelector* ws = ash::Shell::GetInstance()->
251 window_selector_controller()->window_selector_.get();
252 return ws->grid_list_[ws->selected_grid_index_]->is_selecting();
255 bool showing_filter_widget() {
256 WindowSelector* ws = ash::Shell::GetInstance()->
257 window_selector_controller()->window_selector_.get();
258 return ws->text_filter_widget_->GetNativeWindow()->layer()->
259 GetTargetTransform().IsIdentity();
262 views::Widget* GetCloseButton(ash::WindowSelectorItem* window) {
263 return &(window->close_button_widget_);
266 views::LabelButton* GetLabelButtonView(ash::WindowSelectorItem* window) {
267 return window->window_label_button_view_;
270 // Tests that a window is contained within a given WindowSelectorItem, and
271 // that both the window and its matching close button are within the same
272 // screen.
273 void IsWindowAndCloseButtonInScreen(aura::Window* window,
274 WindowSelectorItem* window_item) {
275 aura::Window* root_window = window_item->root_window();
276 EXPECT_TRUE(window_item->Contains(window));
277 EXPECT_TRUE(root_window->GetBoundsInScreen().Contains(
278 ToEnclosingRect(GetTransformedTargetBounds(window))));
279 EXPECT_TRUE(root_window->GetBoundsInScreen().Contains(
280 ToEnclosingRect(GetTransformedTargetBounds(
281 GetCloseButton(window_item)->GetNativeView()))));
284 void FilterItems(const base::StringPiece& pattern) {
285 ash::Shell::GetInstance()->
286 window_selector_controller()->window_selector_.get()->
287 ContentsChanged(nullptr, base::UTF8ToUTF16(pattern));
290 test::ShelfViewTestAPI* shelf_view_test() {
291 return shelf_view_test_.get();
294 views::Widget* text_filter_widget() {
295 return ash::Shell::GetInstance()->
296 window_selector_controller()->window_selector_.get()->
297 text_filter_widget_.get();
300 private:
301 aura::test::TestWindowDelegate delegate_;
302 NonActivatableActivationDelegate non_activatable_activation_delegate_;
303 scoped_ptr<test::ShelfViewTestAPI> shelf_view_test_;
305 DISALLOW_COPY_AND_ASSIGN(WindowSelectorTest);
308 // Tests that the text field in the overview menu is repositioned and resized
309 // after a screen rotation.
310 TEST_F(WindowSelectorTest, OverviewScreenRotation) {
311 gfx::Rect bounds(0, 0, 400, 300);
312 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
313 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
315 // In overview mode the windows should no longer overlap and the text filter
316 // widget should be focused.
317 ToggleOverview();
319 views::Widget* text_filter = text_filter_widget();
320 UpdateDisplay("400x300");
322 // Formula for initial placement found in window_selector.cc using
323 // width = 400, height = 300:
324 // x: root_window->bounds().width() / 2 * (1 - kTextFilterScreenProportion).
325 // y: -kTextFilterDistanceFromTop (since there's no text in the filter).
326 // w: root_window->bounds().width() * kTextFilterScreenProportion.
327 // h: kTextFilterHeight.
328 EXPECT_EQ("150,-32 100x32",
329 text_filter->GetClientAreaBoundsInScreen().ToString());
331 // Rotates the display, which triggers the WindowSelector's
332 // RepositionTextFilterOnDisplayMetricsChange method.
333 UpdateDisplay("400x300/r");
335 // Uses the same formulas as abuve using width = 300, height = 400.
336 EXPECT_EQ("112,-32 75x32",
337 text_filter->GetClientAreaBoundsInScreen().ToString());
340 // Tests that an a11y alert is sent on entering overview mode.
341 TEST_F(WindowSelectorTest, A11yAlertOnOverviewMode) {
342 gfx::Rect bounds(0, 0, 400, 400);
343 AccessibilityDelegate* delegate =
344 ash::Shell::GetInstance()->accessibility_delegate();
345 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
346 EXPECT_NE(delegate->GetLastAccessibilityAlert(),
347 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
348 ToggleOverview();
349 EXPECT_EQ(delegate->GetLastAccessibilityAlert(),
350 ui::A11Y_ALERT_WINDOW_OVERVIEW_MODE_ENTERED);
353 // Tests entering overview mode with two windows and selecting one by clicking.
354 TEST_F(WindowSelectorTest, Basic) {
355 gfx::Rect bounds(0, 0, 400, 400);
356 aura::Window* root_window = Shell::GetPrimaryRootWindow();
357 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
358 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
359 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
360 scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds));
362 EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
363 EXPECT_TRUE(WindowsOverlapping(panel1.get(), panel2.get()));
364 wm::ActivateWindow(window2.get());
365 EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
366 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
367 EXPECT_EQ(window2.get(), GetFocusedWindow());
368 // Hide the cursor before entering overview to test that it will be shown.
369 aura::client::GetCursorClient(root_window)->HideCursor();
371 // In overview mode the windows should no longer overlap and the text filter
372 // widget should be focused.
373 ToggleOverview();
374 EXPECT_EQ(text_filter_widget()->GetNativeWindow(), GetFocusedWindow());
375 EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
376 EXPECT_FALSE(WindowsOverlapping(window1.get(), panel1.get()));
377 EXPECT_FALSE(WindowsOverlapping(panel1.get(), panel2.get()));
379 // Clicking window 1 should activate it.
380 ClickWindow(window1.get());
381 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
382 EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
383 EXPECT_EQ(window1.get(), GetFocusedWindow());
385 // Cursor should have been unlocked.
386 EXPECT_FALSE(aura::client::GetCursorClient(root_window)->IsCursorLocked());
389 // Tests that the ordering of windows is near the windows' original positions.
390 TEST_F(WindowSelectorTest, MinimizeMovement) {
391 aura::Window* root_window = Shell::GetPrimaryRootWindow();
392 gfx::Rect left_bounds(0, 0, root_window->bounds().width() / 2,
393 root_window->bounds().height());
394 gfx::Rect right_bounds(root_window->bounds().width() / 2, 0,
395 root_window->bounds().width() / 2,
396 root_window->bounds().height());
397 scoped_ptr<aura::Window> left_window(CreateWindow(left_bounds));
398 scoped_ptr<aura::Window> right_window(CreateWindow(right_bounds));
400 // The window should stay on the same side of the screen regardless of which
401 // one was active on entering overview mode.
402 wm::GetWindowState(left_window.get())->Activate();
403 ToggleOverview();
404 const std::vector<WindowSelectorItem*>& overview1(GetWindowItemsForRoot(0));
405 EXPECT_EQ(overview1[0]->GetWindow(), left_window.get());
406 EXPECT_EQ(overview1[1]->GetWindow(), right_window.get());
407 ToggleOverview();
409 // Active the right window, the order should be the same.
410 wm::GetWindowState(right_window.get())->Activate();
411 ToggleOverview();
412 const std::vector<WindowSelectorItem*>& overview2(GetWindowItemsForRoot(0));
413 EXPECT_EQ(overview2[0]->GetWindow(), left_window.get());
414 EXPECT_EQ(overview2[1]->GetWindow(), right_window.get());
415 ToggleOverview();
417 // Switch the window positions, and the order should be switched.
418 left_window->SetBounds(right_bounds);
419 right_window->SetBounds(left_bounds);
420 ToggleOverview();
421 const std::vector<WindowSelectorItem*>& overview3(GetWindowItemsForRoot(0));
422 EXPECT_EQ(overview3[0]->GetWindow(), right_window.get());
423 EXPECT_EQ(overview3[1]->GetWindow(), left_window.get());
424 ToggleOverview();
427 // Tests that the ordering of windows is near the windows' original positions
428 // on a second display.
429 TEST_F(WindowSelectorTest, MinimizeMovementSecondDisplay) {
430 if (!SupportsMultipleDisplays())
431 return;
433 // Verify the same works on the second display
434 UpdateDisplay("400x400,400x400");
435 gfx::Rect left_bounds(400, 0, 200, 400);
436 gfx::Rect right_bounds(600, 0, 200, 400);
437 scoped_ptr<aura::Window> left_window(CreateWindow(left_bounds));
438 scoped_ptr<aura::Window> right_window(CreateWindow(right_bounds));
440 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
441 EXPECT_EQ(root_windows[1], left_window->GetRootWindow());
442 EXPECT_EQ(root_windows[1], right_window->GetRootWindow());
444 wm::GetWindowState(left_window.get())->Activate();
445 ToggleOverview();
446 const std::vector<WindowSelectorItem*>& overview1(GetWindowItemsForRoot(0));
447 EXPECT_EQ(overview1[0]->GetWindow(), left_window.get());
448 EXPECT_EQ(overview1[1]->GetWindow(), right_window.get());
449 ToggleOverview();
451 // Active the right window, the order should be the same.
452 wm::GetWindowState(right_window.get())->Activate();
453 ToggleOverview();
454 const std::vector<WindowSelectorItem*>& overview2(GetWindowItemsForRoot(0));
455 EXPECT_EQ(overview2[0]->GetWindow(), left_window.get());
456 EXPECT_EQ(overview2[1]->GetWindow(), right_window.get());
457 ToggleOverview();
460 // Tests that the ordering of windows is stable across different overview
461 // sessions even when the windows have the same bounds.
462 TEST_F(WindowSelectorTest, StableOrder) {
463 gfx::Rect bounds(0, 0, 400, 400);
464 scoped_ptr<aura::Window> window1(CreateWindowWithId(bounds, 1));
465 scoped_ptr<aura::Window> window2(CreateWindowWithId(bounds, 2));
467 // The initial ordering is not defined, but should remain consistent the next
468 // time overview is started.
469 wm::GetWindowState(window1.get())->Activate();
470 ToggleOverview();
471 const std::vector<WindowSelectorItem*>& overview1(GetWindowItemsForRoot(0));
472 int initial_order[2] = {overview1[0]->GetWindow()->id(),
473 overview1[1]->GetWindow()->id()};
474 ToggleOverview();
476 // Activate the other window, the order should be the same.
477 wm::GetWindowState(window2.get())->Activate();
478 ToggleOverview();
479 const std::vector<WindowSelectorItem*>& overview2(GetWindowItemsForRoot(0));
480 EXPECT_EQ(initial_order[0], overview2[0]->GetWindow()->id());
481 EXPECT_EQ(initial_order[1], overview2[1]->GetWindow()->id());
482 ToggleOverview();
485 // Tests entering overview mode with docked windows
486 TEST_F(WindowSelectorTest, BasicWithDocked) {
487 // aura::Window* root_window = Shell::GetPrimaryRootWindow();
488 gfx::Rect bounds(300, 0, 200, 200);
489 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
490 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
491 scoped_ptr<aura::Window> docked1(CreateWindow(bounds));
492 scoped_ptr<aura::Window> docked2(CreateWindow(bounds));
494 wm::WMEvent dock_event(wm::WM_EVENT_DOCK);
495 wm::GetWindowState(docked1.get())->OnWMEvent(&dock_event);
497 wm::WindowState* docked_state2 = wm::GetWindowState(docked2.get());
498 docked_state2->OnWMEvent(&dock_event);
499 wm::WMEvent minimize_event(wm::WM_EVENT_MINIMIZE);
500 docked_state2->OnWMEvent(&minimize_event);
502 EXPECT_TRUE(WindowsOverlapping(window1.get(), window2.get()));
503 gfx::Rect docked_bounds = docked1->GetBoundsInScreen();
505 EXPECT_NE(bounds.ToString(), docked_bounds.ToString());
506 EXPECT_FALSE(WindowsOverlapping(window1.get(), docked1.get()));
507 EXPECT_FALSE(WindowsOverlapping(window1.get(), docked2.get()));
508 EXPECT_FALSE(docked2->IsVisible());
510 EXPECT_EQ(wm::WINDOW_STATE_TYPE_DOCKED,
511 wm::GetWindowState(docked1.get())->GetStateType());
512 EXPECT_EQ(wm::WINDOW_STATE_TYPE_DOCKED_MINIMIZED,
513 wm::GetWindowState(docked2.get())->GetStateType());
515 ToggleOverview();
517 EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
518 // Docked windows stays the same.
519 EXPECT_EQ(docked_bounds.ToString(), docked1->GetBoundsInScreen().ToString());
520 EXPECT_FALSE(docked2->IsVisible());
522 // Docked window can still be activated, which will exit the overview mode.
523 ClickWindow(docked1.get());
524 EXPECT_TRUE(wm::IsActiveWindow(docked1.get()));
525 EXPECT_FALSE(
526 ash::Shell::GetInstance()->window_selector_controller()->IsSelecting());
529 // Tests selecting a window by tapping on it.
530 TEST_F(WindowSelectorTest, BasicGesture) {
531 gfx::Rect bounds(0, 0, 400, 400);
532 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
533 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
534 wm::ActivateWindow(window1.get());
535 EXPECT_EQ(window1.get(), GetFocusedWindow());
536 ToggleOverview();
537 EXPECT_EQ(text_filter_widget()->GetNativeWindow(), GetFocusedWindow());
538 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
539 window2.get());
540 generator.GestureTapAt(gfx::ToEnclosingRect(
541 GetTransformedTargetBounds(window2.get())).CenterPoint());
542 EXPECT_EQ(window2.get(), GetFocusedWindow());
545 // Tests that the user action WindowSelector_ActiveWindowChanged is
546 // recorded when the mouse/touchscreen/keyboard are used to select a window
547 // in overview mode which is different from the previously-active window.
548 TEST_F(WindowSelectorTest, ActiveWindowChangedUserActionRecorded) {
549 base::UserActionTester user_action_tester;
550 gfx::Rect bounds(0, 0, 400, 400);
551 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
552 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
554 // Tap on |window2| to activate it and exit overview.
555 wm::ActivateWindow(window1.get());
556 ToggleOverview();
557 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
558 window2.get());
559 generator.GestureTapAt(
560 gfx::ToEnclosingRect(GetTransformedTargetBounds(window2.get()))
561 .CenterPoint());
562 EXPECT_EQ(
563 1, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
565 // Click on |window2| to activate it and exit overview.
566 wm::ActivateWindow(window1.get());
567 ToggleOverview();
568 ClickWindow(window2.get());
569 EXPECT_EQ(
570 2, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
572 // Select |window2| using the arrow keys. Activate it (and exit overview) by
573 // pressing the return key.
574 wm::ActivateWindow(window1.get());
575 ToggleOverview();
576 ASSERT_TRUE(SelectWindow(window2.get()));
577 SendKey(ui::VKEY_RETURN);
578 EXPECT_EQ(
579 3, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
582 // Tests that the user action WindowSelector_ActiveWindowChanged is not
583 // recorded when the mouse/touchscreen/keyboard are used to select the
584 // already-active window from overview mode. Also verifies that entering and
585 // exiting overview without selecting a window does not record the action.
586 TEST_F(WindowSelectorTest, ActiveWindowChangedUserActionNotRecorded) {
587 base::UserActionTester user_action_tester;
588 gfx::Rect bounds(0, 0, 400, 400);
589 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
590 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
592 // Set |window1| to be initially active.
593 wm::ActivateWindow(window1.get());
594 ToggleOverview();
596 // Tap on |window1| to exit overview.
597 ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
598 window1.get());
599 generator.GestureTapAt(
600 gfx::ToEnclosingRect(GetTransformedTargetBounds(window1.get()))
601 .CenterPoint());
602 EXPECT_EQ(
603 0, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
605 // |window1| remains active. Click on it to exit overview.
606 ASSERT_EQ(window1.get(), GetFocusedWindow());
607 ToggleOverview();
608 ClickWindow(window1.get());
609 EXPECT_EQ(
610 0, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
612 // |window1| remains active. Select using the keyboard.
613 ASSERT_EQ(window1.get(), GetFocusedWindow());
614 ToggleOverview();
615 ASSERT_TRUE(SelectWindow(window1.get()));
616 SendKey(ui::VKEY_RETURN);
617 EXPECT_EQ(
618 0, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
620 // Entering and exiting overview without user input should not record
621 // the action.
622 ToggleOverview();
623 ToggleOverview();
624 EXPECT_EQ(
625 0, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
628 // Tests that the user action WindowSelector_ActiveWindowChanged is not
629 // recorded when overview mode exits as a result of closing its only window.
630 TEST_F(WindowSelectorTest, ActiveWindowChangedUserActionWindowClose) {
631 base::UserActionTester user_action_tester;
632 scoped_ptr<views::Widget> widget =
633 CreateWindowWidget(gfx::Rect(0, 0, 400, 400));
635 ToggleOverview();
637 aura::Window* window = widget->GetNativeWindow();
638 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window);
639 gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1);
640 ui::test::EventGenerator event_generator(window->GetRootWindow(), point);
642 ASSERT_FALSE(widget->IsClosed());
643 event_generator.ClickLeftButton();
644 ASSERT_TRUE(widget->IsClosed());
645 EXPECT_EQ(
646 0, user_action_tester.GetActionCount(kActiveWindowChangedFromOverview));
649 // Tests that we do not crash and overview mode remains engaged if the desktop
650 // is tapped while a finger is already down over a window.
651 TEST_F(WindowSelectorTest, NoCrashWithDesktopTap) {
652 scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(200, 300, 250, 450)));
654 ToggleOverview();
656 gfx::Rect bounds =
657 gfx::ToEnclosingRect(GetTransformedBoundsInRootWindow(window.get()));
658 ui::test::EventGenerator event_generator(window->GetRootWindow(),
659 bounds.CenterPoint());
661 // Press down on the window.
662 const int kTouchId = 19;
663 event_generator.PressTouchId(kTouchId);
665 // Tap on the desktop, which should not cause a crash. Overview mode should
666 // be disengaged.
667 event_generator.GestureTapAt(gfx::Point(0, 0));
668 EXPECT_FALSE(IsSelecting());
670 event_generator.ReleaseTouchId(kTouchId);
673 // Tests that we do not crash and a window is selected when appropriate when
674 // we click on a window during touch.
675 TEST_F(WindowSelectorTest, ClickOnWindowDuringTouch) {
676 gfx::Rect bounds(0, 0, 400, 400);
677 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
678 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
679 wm::ActivateWindow(window2.get());
680 EXPECT_FALSE(wm::IsActiveWindow(window1.get()));
681 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
683 ToggleOverview();
685 gfx::Rect window1_bounds =
686 gfx::ToEnclosingRect(GetTransformedBoundsInRootWindow(window1.get()));
687 ui::test::EventGenerator event_generator(window1->GetRootWindow(),
688 window1_bounds.CenterPoint());
690 // Clicking on |window2| while touching on |window1| should not cause a
691 // crash, overview mode should be disengaged and |window2| should be active.
692 const int kTouchId = 19;
693 event_generator.PressTouchId(kTouchId);
694 event_generator.MoveMouseToCenterOf(window2.get());
695 event_generator.ClickLeftButton();
696 EXPECT_FALSE(IsSelecting());
697 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
698 event_generator.ReleaseTouchId(kTouchId);
700 ToggleOverview();
702 // Clicking on |window1| while touching on |window1| should not cause
703 // a crash, overview mode should be disengaged, and |window1| should
704 // be active.
705 event_generator.MoveMouseToCenterOf(window1.get());
706 event_generator.PressTouchId(kTouchId);
707 event_generator.ClickLeftButton();
708 EXPECT_FALSE(IsSelecting());
709 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
710 EXPECT_FALSE(wm::IsActiveWindow(window2.get()));
711 event_generator.ReleaseTouchId(kTouchId);
714 // Tests that a window does not receive located events when in overview mode.
715 TEST_F(WindowSelectorTest, WindowDoesNotReceiveEvents) {
716 gfx::Rect window_bounds(20, 10, 200, 300);
717 aura::Window* root_window = Shell::GetPrimaryRootWindow();
718 scoped_ptr<aura::Window> window(CreateWindow(window_bounds));
720 gfx::Point point1(window_bounds.x() + 10, window_bounds.y() + 10);
722 ui::MouseEvent event1(ui::ET_MOUSE_PRESSED, point1, point1,
723 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
725 ui::EventTarget* root_target = root_window;
726 ui::EventTargeter* targeter = root_target->GetEventTargeter();
728 // The event should target the window because we are still not in overview
729 // mode.
730 EXPECT_EQ(window, static_cast<aura::Window*>(
731 targeter->FindTargetForEvent(root_target, &event1)));
733 ToggleOverview();
735 // The bounds have changed, take that into account.
736 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window.get());
737 gfx::Point point2(bounds.x() + 10, bounds.y() + 10);
738 ui::MouseEvent event2(ui::ET_MOUSE_PRESSED, point2, point2,
739 ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE);
741 // Now the transparent window should be intercepting this event.
742 EXPECT_NE(window, static_cast<aura::Window*>(
743 targeter->FindTargetForEvent(root_target, &event2)));
746 // Tests that clicking on the close button effectively closes the window.
747 TEST_F(WindowSelectorTest, CloseButton) {
748 scoped_ptr<views::Widget> widget =
749 CreateWindowWidget(gfx::Rect(0, 0, 400, 400));
751 ToggleOverview();
753 aura::Window* window = widget->GetNativeWindow();
754 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window);
755 gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1);
756 ui::test::EventGenerator event_generator(window->GetRootWindow(), point);
758 EXPECT_FALSE(widget->IsClosed());
759 event_generator.ClickLeftButton();
760 EXPECT_TRUE(widget->IsClosed());
763 // Tests that clicking on the close button on a secondary display effectively
764 // closes the window.
765 TEST_F(WindowSelectorTest, CloseButtonOnMultipleDisplay) {
766 if (!SupportsMultipleDisplays())
767 return;
769 UpdateDisplay("600x400,600x400");
770 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
772 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(650, 300, 250, 450)));
774 // We need a widget for the close button to work because windows are closed
775 // via the widget. We also use the widget to determine if the window has been
776 // closed or not. We explicity create the widget so that the window can be
777 // parented to a non-primary root window.
778 scoped_ptr<views::Widget> widget(new views::Widget);
779 views::Widget::InitParams params;
780 params.bounds = gfx::Rect(650, 0, 400, 400);
781 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
782 params.parent = window1->parent();
783 widget->Init(params);
784 widget->Show();
786 ASSERT_EQ(root_windows[1], window1->GetRootWindow());
788 ToggleOverview();
790 aura::Window* window2 = widget->GetNativeWindow();
791 gfx::RectF bounds = GetTransformedBoundsInRootWindow(window2);
792 gfx::Point point(bounds.top_right().x() - 1, bounds.top_right().y() - 1);
793 ui::test::EventGenerator event_generator(window2->GetRootWindow(), point);
795 EXPECT_FALSE(widget->IsClosed());
796 event_generator.ClickLeftButton();
797 EXPECT_TRUE(widget->IsClosed());
800 // Tests entering overview mode with two windows and selecting one.
801 TEST_F(WindowSelectorTest, FullscreenWindow) {
802 gfx::Rect bounds(0, 0, 400, 400);
803 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
804 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
805 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds));
806 wm::ActivateWindow(window1.get());
808 const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
809 wm::GetWindowState(window1.get())->OnWMEvent(&toggle_fullscreen_event);
810 // The panel is hidden in fullscreen mode.
811 EXPECT_FALSE(panel1->IsVisible());
812 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
814 // Enter overview and select the fullscreen window.
815 ToggleOverview();
817 // The panel becomes temporarily visible for the overview.
818 EXPECT_TRUE(panel1->IsVisible());
819 ClickWindow(window1.get());
821 // The window is still fullscreen as it was selected. The panel should again
822 // be hidden.
823 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
824 EXPECT_FALSE(panel1->IsVisible());
826 // Entering overview and selecting another window, the previous window remains
827 // fullscreen.
828 // TODO(flackr): Currently the panel remains hidden, but should become visible
829 // again.
830 ToggleOverview();
831 ClickWindow(window2.get());
832 EXPECT_TRUE(wm::GetWindowState(window1.get())->IsFullscreen());
835 // Tests that the shelf dimming state is removed while in overview and restored
836 // on exiting overview.
837 TEST_F(WindowSelectorTest, OverviewUndimsShelf) {
838 gfx::Rect bounds(0, 0, 400, 400);
839 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
840 wm::WindowState* window_state = wm::GetWindowState(window1.get());
841 window_state->Maximize();
842 ash::ShelfWidget* shelf = Shell::GetPrimaryRootWindowController()->shelf();
843 EXPECT_TRUE(shelf->GetDimsShelf());
844 ToggleOverview();
845 EXPECT_FALSE(shelf->GetDimsShelf());
846 ToggleOverview();
847 EXPECT_TRUE(shelf->GetDimsShelf());
850 // Tests that entering overview when a fullscreen window is active in maximized
851 // mode correctly applies the transformations to the window and correctly
852 // updates the window bounds on exiting overview mode: http://crbug.com/401664.
853 TEST_F(WindowSelectorTest, FullscreenWindowMaximizeMode) {
854 gfx::Rect bounds(0, 0, 400, 400);
855 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
856 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
857 Shell::GetInstance()->maximize_mode_controller()->
858 EnableMaximizeModeWindowManager(true);
859 wm::ActivateWindow(window2.get());
860 wm::ActivateWindow(window1.get());
861 gfx::Rect normal_window_bounds(window1->bounds());
862 const wm::WMEvent toggle_fullscreen_event(wm::WM_EVENT_TOGGLE_FULLSCREEN);
863 wm::GetWindowState(window1.get())->OnWMEvent(&toggle_fullscreen_event);
864 gfx::Rect fullscreen_window_bounds(window1->bounds());
865 EXPECT_NE(normal_window_bounds.ToString(),
866 fullscreen_window_bounds.ToString());
867 EXPECT_EQ(fullscreen_window_bounds.ToString(),
868 window2->GetTargetBounds().ToString());
869 ToggleOverview();
870 // Window 2 would normally resize to normal window bounds on showing the shelf
871 // for overview but this is deferred until overview is exited.
872 EXPECT_EQ(fullscreen_window_bounds.ToString(),
873 window2->GetTargetBounds().ToString());
874 EXPECT_FALSE(WindowsOverlapping(window1.get(), window2.get()));
875 ToggleOverview();
877 // Since the fullscreen window is still active, window2 will still have the
878 // larger bounds.
879 EXPECT_EQ(fullscreen_window_bounds.ToString(),
880 window2->GetTargetBounds().ToString());
882 // Enter overview again and select window 2. Selecting window 2 should show
883 // the shelf bringing window2 back to the normal bounds.
884 ToggleOverview();
885 ClickWindow(window2.get());
886 EXPECT_EQ(normal_window_bounds.ToString(),
887 window2->GetTargetBounds().ToString());
890 // Tests that beginning window selection hides the app list.
891 TEST_F(WindowSelectorTest, SelectingHidesAppList) {
892 gfx::Rect bounds(0, 0, 400, 400);
893 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
894 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
895 Shell::GetInstance()->ShowAppList(nullptr);
896 EXPECT_TRUE(Shell::GetInstance()->GetAppListTargetVisibility());
897 ToggleOverview();
898 EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
899 ToggleOverview();
902 // Tests that a minimized window's visibility and layer visibility is correctly
903 // changed when entering overview and restored when leaving overview mode.
904 // Crashes after the skia roll in http://crrev.com/274114.
905 // http://crbug.com/379570
906 TEST_F(WindowSelectorTest, DISABLED_MinimizedWindowVisibility) {
907 gfx::Rect bounds(0, 0, 400, 400);
908 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
909 wm::WindowState* window_state = wm::GetWindowState(window1.get());
910 window_state->Minimize();
911 EXPECT_FALSE(window1->IsVisible());
912 EXPECT_FALSE(window1->layer()->GetTargetVisibility());
914 ui::ScopedAnimationDurationScaleMode test_duration_mode(
915 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
916 ToggleOverview();
917 EXPECT_TRUE(window1->IsVisible());
918 EXPECT_TRUE(window1->layer()->GetTargetVisibility());
921 ui::ScopedAnimationDurationScaleMode test_duration_mode(
922 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
923 ToggleOverview();
924 EXPECT_FALSE(window1->IsVisible());
925 EXPECT_FALSE(window1->layer()->GetTargetVisibility());
929 // Tests that a bounds change during overview is corrected for.
930 TEST_F(WindowSelectorTest, BoundsChangeDuringOverview) {
931 scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 400, 400)));
932 ToggleOverview();
933 gfx::Rect overview_bounds =
934 ToEnclosingRect(GetTransformedTargetBounds(window.get()));
935 window->SetBounds(gfx::Rect(200, 0, 200, 200));
936 gfx::Rect new_overview_bounds =
937 ToEnclosingRect(GetTransformedTargetBounds(window.get()));
938 EXPECT_EQ(overview_bounds.x(), new_overview_bounds.x());
939 EXPECT_EQ(overview_bounds.y(), new_overview_bounds.y());
940 EXPECT_EQ(overview_bounds.width(), new_overview_bounds.width());
941 EXPECT_EQ(overview_bounds.height(), new_overview_bounds.height());
942 ToggleOverview();
945 // Tests that a newly created window aborts overview.
946 TEST_F(WindowSelectorTest, NewWindowCancelsOveriew) {
947 gfx::Rect bounds(0, 0, 400, 400);
948 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
949 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
950 ToggleOverview();
951 EXPECT_TRUE(IsSelecting());
953 // A window being created should exit overview mode.
954 scoped_ptr<aura::Window> window3(CreateWindow(bounds));
955 EXPECT_FALSE(IsSelecting());
958 // Tests that a window activation exits overview mode.
959 TEST_F(WindowSelectorTest, ActivationCancelsOveriew) {
960 gfx::Rect bounds(0, 0, 400, 400);
961 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
962 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
963 window2->Focus();
964 ToggleOverview();
965 EXPECT_TRUE(IsSelecting());
967 // A window being activated should exit overview mode.
968 window1->Focus();
969 EXPECT_FALSE(IsSelecting());
971 // window1 should be focused after exiting even though window2 was focused on
972 // entering overview because we exited due to an activation.
973 EXPECT_EQ(window1.get(), GetFocusedWindow());
976 // Tests that exiting overview mode without selecting a window restores focus
977 // to the previously focused window.
978 TEST_F(WindowSelectorTest, CancelRestoresFocus) {
979 gfx::Rect bounds(0, 0, 400, 400);
980 scoped_ptr<aura::Window> window(CreateWindow(bounds));
981 wm::ActivateWindow(window.get());
982 EXPECT_EQ(window.get(), GetFocusedWindow());
984 // In overview mode, the text filter widget should be focused.
985 ToggleOverview();
986 EXPECT_EQ(text_filter_widget()->GetNativeWindow(), GetFocusedWindow());
988 // If canceling overview mode, focus should be restored.
989 ToggleOverview();
990 EXPECT_EQ(window.get(), GetFocusedWindow());
993 // Tests that overview mode is exited if the last remaining window is destroyed.
994 TEST_F(WindowSelectorTest, LastWindowDestroyed) {
995 gfx::Rect bounds(0, 0, 400, 400);
996 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
997 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
998 ToggleOverview();
1000 window1.reset();
1001 window2.reset();
1002 EXPECT_FALSE(IsSelecting());
1005 // Tests that entering overview mode restores a window to its original
1006 // target location.
1007 TEST_F(WindowSelectorTest, QuickReentryRestoresInitialTransform) {
1008 gfx::Rect bounds(0, 0, 400, 400);
1009 scoped_ptr<aura::Window> window(CreateWindow(bounds));
1010 gfx::Rect initial_bounds = ToEnclosingRect(
1011 GetTransformedBounds(window.get()));
1012 ToggleOverview();
1013 // Quickly exit and reenter overview mode. The window should still be
1014 // animating when we reenter. We cannot short circuit animations for this but
1015 // we also don't have to wait for them to complete.
1017 ui::ScopedAnimationDurationScaleMode test_duration_mode(
1018 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
1019 ToggleOverview();
1020 ToggleOverview();
1022 EXPECT_NE(initial_bounds, ToEnclosingRect(
1023 GetTransformedTargetBounds(window.get())));
1024 ToggleOverview();
1025 EXPECT_FALSE(IsSelecting());
1026 EXPECT_EQ(initial_bounds, ToEnclosingRect(
1027 GetTransformedTargetBounds(window.get())));
1030 // Tests that windows with modal child windows are transformed with the modal
1031 // child even though not activatable themselves.
1032 TEST_F(WindowSelectorTest, ModalChild) {
1033 gfx::Rect bounds(0, 0, 400, 400);
1034 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1035 scoped_ptr<aura::Window> child1(CreateWindow(bounds));
1036 child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
1037 ::wm::AddTransientChild(window1.get(), child1.get());
1038 EXPECT_EQ(window1->parent(), child1->parent());
1039 ToggleOverview();
1040 EXPECT_TRUE(window1->IsVisible());
1041 EXPECT_TRUE(child1->IsVisible());
1042 EXPECT_EQ(ToEnclosingRect(GetTransformedTargetBounds(child1.get())),
1043 ToEnclosingRect(GetTransformedTargetBounds(window1.get())));
1044 ToggleOverview();
1047 // Tests that clicking a modal window's parent activates the modal window in
1048 // overview.
1049 TEST_F(WindowSelectorTest, ClickModalWindowParent) {
1050 scoped_ptr<aura::Window> window1(CreateWindow(gfx::Rect(0, 0, 180, 180)));
1051 scoped_ptr<aura::Window> child1(CreateWindow(gfx::Rect(200, 0, 180, 180)));
1052 child1->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_WINDOW);
1053 ::wm::AddTransientChild(window1.get(), child1.get());
1054 EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
1055 EXPECT_EQ(window1->parent(), child1->parent());
1056 ToggleOverview();
1057 // Given that their relative positions are preserved, the windows should still
1058 // not overlap.
1059 EXPECT_FALSE(WindowsOverlapping(window1.get(), child1.get()));
1060 ClickWindow(window1.get());
1061 EXPECT_FALSE(IsSelecting());
1063 // Clicking on window1 should activate child1.
1064 EXPECT_TRUE(wm::IsActiveWindow(child1.get()));
1067 // Tests that windows remain on the display they are currently on in overview
1068 // mode, and that the close buttons are on matching displays.
1069 TEST_F(WindowSelectorTest, MultipleDisplays) {
1070 if (!SupportsMultipleDisplays())
1071 return;
1073 UpdateDisplay("600x400,600x400");
1074 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1075 gfx::Rect bounds1(0, 0, 400, 400);
1076 gfx::Rect bounds2(650, 0, 400, 400);
1078 scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
1079 scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
1080 scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
1081 scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
1082 scoped_ptr<aura::Window> panel1(CreatePanelWindow(bounds1));
1083 scoped_ptr<aura::Window> panel2(CreatePanelWindow(bounds1));
1084 scoped_ptr<aura::Window> panel3(CreatePanelWindow(bounds2));
1085 scoped_ptr<aura::Window> panel4(CreatePanelWindow(bounds2));
1086 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
1087 EXPECT_EQ(root_windows[0], window2->GetRootWindow());
1088 EXPECT_EQ(root_windows[1], window3->GetRootWindow());
1089 EXPECT_EQ(root_windows[1], window4->GetRootWindow());
1091 EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
1092 EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
1093 EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
1094 EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
1096 // In overview mode, each window remains in the same root window.
1097 ToggleOverview();
1098 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
1099 EXPECT_EQ(root_windows[0], window2->GetRootWindow());
1100 EXPECT_EQ(root_windows[1], window3->GetRootWindow());
1101 EXPECT_EQ(root_windows[1], window4->GetRootWindow());
1102 EXPECT_EQ(root_windows[0], panel1->GetRootWindow());
1103 EXPECT_EQ(root_windows[0], panel2->GetRootWindow());
1104 EXPECT_EQ(root_windows[1], panel3->GetRootWindow());
1105 EXPECT_EQ(root_windows[1], panel4->GetRootWindow());
1107 // Window indices are based on top-down order. The reverse of our creation.
1108 IsWindowAndCloseButtonInScreen(window1.get(),
1109 GetWindowItemForWindow(0, window1.get()));
1110 IsWindowAndCloseButtonInScreen(window2.get(),
1111 GetWindowItemForWindow(0, window2.get()));
1112 IsWindowAndCloseButtonInScreen(window3.get(),
1113 GetWindowItemForWindow(1, window3.get()));
1114 IsWindowAndCloseButtonInScreen(window4.get(),
1115 GetWindowItemForWindow(1, window4.get()));
1117 IsWindowAndCloseButtonInScreen(panel1.get(),
1118 GetWindowItemForWindow(0, panel1.get()));
1119 IsWindowAndCloseButtonInScreen(panel2.get(),
1120 GetWindowItemForWindow(0, panel2.get()));
1121 IsWindowAndCloseButtonInScreen(panel3.get(),
1122 GetWindowItemForWindow(1, panel3.get()));
1123 IsWindowAndCloseButtonInScreen(panel4.get(),
1124 GetWindowItemForWindow(1, panel4.get()));
1127 // Tests shutting down during overview.
1128 TEST_F(WindowSelectorTest, Shutdown) {
1129 gfx::Rect bounds(0, 0, 400, 400);
1130 // These windows will be deleted when the test exits and the Shell instance
1131 // is shut down.
1132 aura::Window* window1(CreateWindow(bounds));
1133 aura::Window* window2(CreateWindow(bounds));
1134 aura::Window* window3(CreatePanelWindow(bounds));
1135 aura::Window* window4(CreatePanelWindow(bounds));
1137 wm::ActivateWindow(window4);
1138 wm::ActivateWindow(window3);
1139 wm::ActivateWindow(window2);
1140 wm::ActivateWindow(window1);
1142 ToggleOverview();
1145 // Tests removing a display during overview.
1146 TEST_F(WindowSelectorTest, RemoveDisplay) {
1147 if (!SupportsMultipleDisplays())
1148 return;
1150 UpdateDisplay("400x400,400x400");
1151 gfx::Rect bounds1(0, 0, 100, 100);
1152 gfx::Rect bounds2(450, 0, 100, 100);
1153 scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
1154 scoped_ptr<aura::Window> window2(CreateWindow(bounds2));
1155 scoped_ptr<aura::Window> window3(CreatePanelWindow(bounds1));
1156 scoped_ptr<aura::Window> window4(CreatePanelWindow(bounds2));
1158 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1159 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
1160 EXPECT_EQ(root_windows[1], window2->GetRootWindow());
1161 EXPECT_EQ(root_windows[0], window3->GetRootWindow());
1162 EXPECT_EQ(root_windows[1], window4->GetRootWindow());
1164 wm::ActivateWindow(window4.get());
1165 wm::ActivateWindow(window3.get());
1166 wm::ActivateWindow(window2.get());
1167 wm::ActivateWindow(window1.get());
1169 ToggleOverview();
1170 EXPECT_TRUE(IsSelecting());
1171 UpdateDisplay("400x400");
1172 EXPECT_FALSE(IsSelecting());
1175 // Tests starting overview during a drag and drop tracking operation.
1176 // TODO(flackr): Fix memory corruption crash when running locally (not failing
1177 // on bots). See http://crbug.com/342528.
1178 TEST_F(WindowSelectorTest, DISABLED_DragDropInProgress) {
1179 bool drag_canceled_by_test = false;
1180 gfx::Rect bounds(0, 0, 400, 400);
1181 scoped_ptr<aura::Window> window(CreateWindow(bounds));
1182 test::ShellTestApi shell_test_api(Shell::GetInstance());
1183 ash::DragDropController* drag_drop_controller =
1184 shell_test_api.drag_drop_controller();
1185 ui::OSExchangeData data;
1186 base::MessageLoopForUI::current()->PostTask(FROM_HERE,
1187 base::Bind(&WindowSelectorTest::ToggleOverview,
1188 base::Unretained(this)));
1189 base::MessageLoopForUI::current()->PostTask(FROM_HERE,
1190 base::Bind(&CancelDrag, drag_drop_controller, &drag_canceled_by_test));
1191 data.SetString(base::UTF8ToUTF16("I am being dragged"));
1192 drag_drop_controller->StartDragAndDrop(data, window->GetRootWindow(),
1193 window.get(), gfx::Point(5, 5), ui::DragDropTypes::DRAG_MOVE,
1194 ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
1195 RunAllPendingInMessageLoop();
1196 EXPECT_FALSE(drag_canceled_by_test);
1197 ASSERT_TRUE(IsSelecting());
1198 RunAllPendingInMessageLoop();
1201 // Test that a label is created under the window on entering overview mode.
1202 TEST_F(WindowSelectorTest, CreateLabelUnderWindow) {
1203 scoped_ptr<aura::Window> window(CreateWindow(gfx::Rect(0, 0, 100, 100)));
1204 base::string16 window_title = base::UTF8ToUTF16("My window");
1205 window->SetTitle(window_title);
1206 ToggleOverview();
1207 WindowSelectorItem* window_item = GetWindowItemsForRoot(0).back();
1208 views::LabelButton* label = GetLabelButtonView(window_item);
1209 // Has the label view been created?
1210 ASSERT_TRUE(label);
1212 // Verify the label matches the window title.
1213 EXPECT_EQ(label->GetText(), window_title);
1215 // Update the window title and check that the label is updated, too.
1216 base::string16 updated_title = base::UTF8ToUTF16("Updated title");
1217 window->SetTitle(updated_title);
1218 EXPECT_EQ(label->GetText(), updated_title);
1220 // Labels are located based on target_bounds, not the actual window item
1221 // bounds.
1222 gfx::Rect label_bounds = label->GetWidget()->GetNativeWindow()->bounds();
1223 EXPECT_EQ(label_bounds, window_item->target_bounds());
1226 // Tests that overview updates the window positions if the display orientation
1227 // changes.
1228 TEST_F(WindowSelectorTest, DisplayOrientationChanged) {
1229 if (!SupportsHostWindowResize())
1230 return;
1232 aura::Window* root_window = Shell::GetInstance()->GetPrimaryRootWindow();
1233 UpdateDisplay("600x200");
1234 EXPECT_EQ("0,0 600x200", root_window->bounds().ToString());
1235 gfx::Rect window_bounds(0, 0, 150, 150);
1236 ScopedVector<aura::Window> windows;
1237 for (int i = 0; i < 3; i++) {
1238 windows.push_back(CreateWindow(window_bounds));
1241 ToggleOverview();
1242 for (ScopedVector<aura::Window>::iterator iter = windows.begin();
1243 iter != windows.end(); ++iter) {
1244 EXPECT_TRUE(root_window->bounds().Contains(
1245 ToEnclosingRect(GetTransformedTargetBounds(*iter))));
1248 // Rotate the display, windows should be repositioned to be within the screen
1249 // bounds.
1250 UpdateDisplay("600x200/r");
1251 EXPECT_EQ("0,0 200x600", root_window->bounds().ToString());
1252 for (ScopedVector<aura::Window>::iterator iter = windows.begin();
1253 iter != windows.end(); ++iter) {
1254 EXPECT_TRUE(root_window->bounds().Contains(
1255 ToEnclosingRect(GetTransformedTargetBounds(*iter))));
1259 // Tests traversing some windows in overview mode with the tab key.
1260 TEST_F(WindowSelectorTest, BasicTabKeyNavigation) {
1261 gfx::Rect bounds(0, 0, 100, 100);
1262 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
1263 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1264 ToggleOverview();
1266 const std::vector<WindowSelectorItem*>& overview_windows =
1267 GetWindowItemsForRoot(0);
1268 SendKey(ui::VKEY_TAB);
1269 EXPECT_EQ(GetSelectedWindow(), overview_windows[0]->GetWindow());
1270 SendKey(ui::VKEY_TAB);
1271 EXPECT_EQ(GetSelectedWindow(), overview_windows[1]->GetWindow());
1272 SendKey(ui::VKEY_TAB);
1273 EXPECT_EQ(GetSelectedWindow(), overview_windows[0]->GetWindow());
1276 // Tests traversing some windows in overview mode with the arrow keys in every
1277 // possible direction.
1278 TEST_F(WindowSelectorTest, BasicArrowKeyNavigation) {
1279 if (!SupportsHostWindowResize())
1280 return;
1281 const size_t test_windows = 9;
1282 UpdateDisplay("800x600");
1283 ScopedVector<aura::Window> windows;
1284 for (size_t i = test_windows; i > 0; i--)
1285 windows.push_back(CreateWindowWithId(gfx::Rect(0, 0, 100, 100), i));
1287 ui::KeyboardCode arrow_keys[] = {
1288 ui::VKEY_RIGHT,
1289 ui::VKEY_DOWN,
1290 ui::VKEY_LEFT,
1291 ui::VKEY_UP
1293 // Expected window layout, assuming that the text filtering feature is
1294 // enabled by default (i.e., --ash-disable-text-filtering-in-overview-mode
1295 // is not being used).
1296 // +-------+ +-------+ +-------+ +-------+
1297 // | 1 | | 2 | | 3 | | 4 |
1298 // +-------+ +-------+ +-------+ +-------+
1299 // +-------+ +-------+ +-------+ +-------+
1300 // | 5 | | 6 | | 7 | | 8 |
1301 // +-------+ +-------+ +-------+ +-------+
1302 // +-------+
1303 // | 9 |
1304 // +-------+
1305 // Index for each window during a full loop plus wrapping around.
1306 int index_path_for_direction[][test_windows + 1] = {
1307 {1, 2, 3, 4, 5, 6, 7, 8, 9, 1}, // Right
1308 {1, 5, 9, 2, 6, 3, 7, 4, 8, 1}, // Down
1309 {9, 8, 7, 6, 5, 4, 3, 2, 1, 9}, // Left
1310 {8, 4, 7, 3, 6, 2, 9, 5, 1, 8} // Up
1313 for (size_t key_index = 0; key_index < arraysize(arrow_keys); key_index++) {
1314 ToggleOverview();
1315 const std::vector<WindowSelectorItem*>& overview_windows =
1316 GetWindowItemsForRoot(0);
1317 for (size_t i = 0; i < test_windows + 1; i++) {
1318 SendKey(arrow_keys[key_index]);
1319 // TODO(flackr): Add a more readable error message by constructing a
1320 // string from the window IDs.
1321 EXPECT_EQ(GetSelectedWindow()->id(),
1322 overview_windows[index_path_for_direction[key_index][i] - 1]
1323 ->GetWindow()
1324 ->id());
1326 ToggleOverview();
1330 // Tests basic selection across multiple monitors.
1331 TEST_F(WindowSelectorTest, BasicMultiMonitorArrowKeyNavigation) {
1332 if (!SupportsMultipleDisplays())
1333 return;
1335 UpdateDisplay("400x400,400x400");
1336 gfx::Rect bounds1(0, 0, 100, 100);
1337 gfx::Rect bounds2(450, 0, 100, 100);
1338 scoped_ptr<aura::Window> window4(CreateWindow(bounds2));
1339 scoped_ptr<aura::Window> window3(CreateWindow(bounds2));
1340 scoped_ptr<aura::Window> window2(CreateWindow(bounds1));
1341 scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
1344 ToggleOverview();
1346 const std::vector<WindowSelectorItem*>& overview_root1 =
1347 GetWindowItemsForRoot(0);
1348 const std::vector<WindowSelectorItem*>& overview_root2 =
1349 GetWindowItemsForRoot(1);
1350 SendKey(ui::VKEY_RIGHT);
1351 EXPECT_EQ(GetSelectedWindow(), overview_root1[0]->GetWindow());
1352 SendKey(ui::VKEY_RIGHT);
1353 EXPECT_EQ(GetSelectedWindow(), overview_root1[1]->GetWindow());
1354 SendKey(ui::VKEY_RIGHT);
1355 EXPECT_EQ(GetSelectedWindow(), overview_root2[0]->GetWindow());
1356 SendKey(ui::VKEY_RIGHT);
1357 EXPECT_EQ(GetSelectedWindow(), overview_root2[1]->GetWindow());
1360 // Tests first monitor when display order doesn't match left to right screen
1361 // positions.
1362 TEST_F(WindowSelectorTest, MultiMonitorReversedOrder) {
1363 if (!SupportsMultipleDisplays())
1364 return;
1366 UpdateDisplay("400x400,400x400");
1367 DisplayLayout layout(DisplayLayout::LEFT, 0);
1368 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(layout);
1369 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1370 gfx::Rect bounds1(-350, 0, 100, 100);
1371 gfx::Rect bounds2(0, 0, 100, 100);
1372 scoped_ptr<aura::Window> window2(CreateWindow(bounds2));
1373 scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
1374 EXPECT_EQ(root_windows[1], window1->GetRootWindow());
1375 EXPECT_EQ(root_windows[0], window2->GetRootWindow());
1377 ToggleOverview();
1379 // Coming from the left to right, we should select window1 first being on the
1380 // display to the left.
1381 SendKey(ui::VKEY_RIGHT);
1382 EXPECT_EQ(GetSelectedWindow(), window1.get());
1384 ToggleOverview();
1385 ToggleOverview();
1387 // Coming from right to left, we should select window2 first being on the
1388 // display on the right.
1389 SendKey(ui::VKEY_LEFT);
1390 EXPECT_EQ(GetSelectedWindow(), window2.get());
1393 // Tests three monitors where the grid becomes empty on one of the monitors.
1394 TEST_F(WindowSelectorTest, ThreeMonitor) {
1395 if (!SupportsMultipleDisplays())
1396 return;
1398 UpdateDisplay("400x400,400x400,400x400");
1399 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
1400 gfx::Rect bounds1(0, 0, 100, 100);
1401 gfx::Rect bounds2(400, 0, 100, 100);
1402 gfx::Rect bounds3(800, 0, 100, 100);
1403 scoped_ptr<aura::Window> window3(CreateWindow(bounds3));
1404 scoped_ptr<aura::Window> window2(CreateWindow(bounds2));
1405 scoped_ptr<aura::Window> window1(CreateWindow(bounds1));
1406 EXPECT_EQ(root_windows[0], window1->GetRootWindow());
1407 EXPECT_EQ(root_windows[1], window2->GetRootWindow());
1408 EXPECT_EQ(root_windows[2], window3->GetRootWindow());
1410 ToggleOverview();
1412 SendKey(ui::VKEY_RIGHT);
1413 SendKey(ui::VKEY_RIGHT);
1414 SendKey(ui::VKEY_RIGHT);
1415 EXPECT_EQ(GetSelectedWindow(), window3.get());
1417 // If the last window on a display closes it should select the previous
1418 // display's window.
1419 window3.reset();
1420 EXPECT_EQ(GetSelectedWindow(), window2.get());
1421 ToggleOverview();
1423 window3.reset(CreateWindow(bounds3));
1424 ToggleOverview();
1425 SendKey(ui::VKEY_RIGHT);
1426 SendKey(ui::VKEY_RIGHT);
1427 SendKey(ui::VKEY_RIGHT);
1429 // If the window on the second display is removed, the selected window should
1430 // remain window3.
1431 EXPECT_EQ(GetSelectedWindow(), window3.get());
1432 window2.reset();
1433 EXPECT_EQ(GetSelectedWindow(), window3.get());
1436 // Tests selecting a window in overview mode with the return key.
1437 TEST_F(WindowSelectorTest, SelectWindowWithReturnKey) {
1438 gfx::Rect bounds(0, 0, 100, 100);
1439 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
1440 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1441 ToggleOverview();
1443 // Pressing the return key without a selection widget should not do anything.
1444 SendKey(ui::VKEY_RETURN);
1445 EXPECT_TRUE(IsSelecting());
1447 // Select the first window.
1448 ASSERT_TRUE(SelectWindow(window1.get()));
1449 SendKey(ui::VKEY_RETURN);
1450 ASSERT_FALSE(IsSelecting());
1451 EXPECT_TRUE(wm::IsActiveWindow(window1.get()));
1453 // Select the second window.
1454 ToggleOverview();
1455 ASSERT_TRUE(SelectWindow(window2.get()));
1456 SendKey(ui::VKEY_RETURN);
1457 EXPECT_FALSE(IsSelecting());
1458 EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
1461 // Tests that overview mode hides the callout widget.
1462 TEST_F(WindowSelectorTest, WindowOverviewHidesCalloutWidgets) {
1463 scoped_ptr<aura::Window> panel1(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
1464 scoped_ptr<aura::Window> panel2(CreatePanelWindow(gfx::Rect(0, 0, 100, 100)));
1465 PanelLayoutManager* panel_manager =
1466 static_cast<PanelLayoutManager*>(panel1->parent()->layout_manager());
1468 // By default, panel callout widgets are visible.
1469 EXPECT_TRUE(
1470 panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
1471 EXPECT_TRUE(
1472 panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
1474 // Toggling the overview should hide the callout widgets.
1475 ToggleOverview();
1476 EXPECT_FALSE(
1477 panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
1478 EXPECT_FALSE(
1479 panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
1481 // Ending the overview should show them again.
1482 ToggleOverview();
1483 EXPECT_TRUE(
1484 panel_manager->GetCalloutWidgetForPanel(panel1.get())->IsVisible());
1485 EXPECT_TRUE(
1486 panel_manager->GetCalloutWidgetForPanel(panel2.get())->IsVisible());
1489 // Creates three windows and tests filtering them by title.
1490 TEST_F(WindowSelectorTest, BasicTextFiltering) {
1491 gfx::Rect bounds(0, 0, 100, 100);
1492 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
1493 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1494 scoped_ptr<aura::Window> window0(CreateWindow(bounds));
1495 base::string16 window2_title = base::UTF8ToUTF16("Highway to test");
1496 base::string16 window1_title = base::UTF8ToUTF16("For those about to test");
1497 base::string16 window0_title = base::UTF8ToUTF16("We salute you");
1498 window0->SetTitle(window0_title);
1499 window1->SetTitle(window1_title);
1500 window2->SetTitle(window2_title);
1501 ToggleOverview();
1503 EXPECT_FALSE(selection_widget_active());
1504 EXPECT_FALSE(showing_filter_widget());
1505 FilterItems("Test");
1507 // The selection widget should appear when filtering starts, and should be
1508 // selecting one of the matching windows above.
1509 EXPECT_TRUE(selection_widget_active());
1510 EXPECT_TRUE(showing_filter_widget());
1511 // window0 does not contain the text "test".
1512 EXPECT_NE(GetSelectedWindow(), window0.get());
1514 // Window 0 has no "test" on it so it should be the only dimmed item.
1515 const int grid_index = 0;
1516 std::vector<WindowSelectorItem*> items = GetWindowItemsForRoot(0);
1517 EXPECT_TRUE(GetWindowItemForWindow(grid_index, window0.get())->dimmed());
1518 EXPECT_FALSE(GetWindowItemForWindow(grid_index, window1.get())->dimmed());
1519 EXPECT_FALSE(GetWindowItemForWindow(grid_index, window2.get())->dimmed());
1521 // No items match the search.
1522 FilterItems("I'm testing 'n testing");
1523 EXPECT_TRUE(GetWindowItemForWindow(grid_index, window0.get())->dimmed());
1524 EXPECT_TRUE(GetWindowItemForWindow(grid_index, window1.get())->dimmed());
1525 EXPECT_TRUE(GetWindowItemForWindow(grid_index, window2.get())->dimmed());
1527 // All the items should match the empty string. The filter widget should also
1528 // disappear.
1529 FilterItems("");
1530 EXPECT_FALSE(showing_filter_widget());
1531 EXPECT_FALSE(GetWindowItemForWindow(grid_index, window0.get())->dimmed());
1532 EXPECT_FALSE(GetWindowItemForWindow(grid_index, window1.get())->dimmed());
1533 EXPECT_FALSE(GetWindowItemForWindow(grid_index, window2.get())->dimmed());
1536 // Tests selecting in the overview with dimmed and undimmed items.
1537 TEST_F(WindowSelectorTest, TextFilteringSelection) {
1538 gfx::Rect bounds(0, 0, 100, 100);
1539 scoped_ptr<aura::Window> window2(CreateWindow(bounds));
1540 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1541 scoped_ptr<aura::Window> window0(CreateWindow(bounds));
1542 base::string16 window2_title = base::UTF8ToUTF16("Rock and roll");
1543 base::string16 window1_title = base::UTF8ToUTF16("Rock and");
1544 base::string16 window0_title = base::UTF8ToUTF16("Rock");
1545 window0->SetTitle(window0_title);
1546 window1->SetTitle(window1_title);
1547 window2->SetTitle(window2_title);
1548 ToggleOverview();
1549 EXPECT_TRUE(SelectWindow(window0.get()));
1550 EXPECT_TRUE(selection_widget_active());
1552 // Dim the first item, the selection should jump to the next item.
1553 std::vector<WindowSelectorItem*> items = GetWindowItemsForRoot(0);
1554 FilterItems("Rock and");
1555 EXPECT_NE(GetSelectedWindow(), window0.get());
1557 // Cycle the selection, the dimmed window should not be selected.
1558 EXPECT_FALSE(SelectWindow(window0.get()));
1560 // Dimming all the items should hide the selection widget.
1561 FilterItems("Pop");
1562 EXPECT_FALSE(selection_widget_active());
1564 // Undimming one window should automatically select it.
1565 FilterItems("Rock and roll");
1566 EXPECT_EQ(GetSelectedWindow(), window2.get());
1569 // Tests clicking on the desktop itself to cancel overview mode.
1570 TEST_F(WindowSelectorTest, CancelOverviewOnMouseClick) {
1571 // Overview disabled by default.
1572 EXPECT_FALSE(IsSelecting());
1574 // Point and bounds selected so that they don't intersect. This causes
1575 // events located at the point to be passed to DesktopBackgroundController,
1576 // and not the window.
1577 gfx::Point point_in_background_page(0, 0);
1578 gfx::Rect bounds(10, 10, 100, 100);
1579 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1580 ui::test::EventGenerator& generator = GetEventGenerator();
1581 // Move mouse to point in the background page. Sending an event here will pass
1582 // it to the DesktopBackgroundController in both regular and overview mode.
1583 generator.MoveMouseTo(point_in_background_page);
1585 // Clicking on the background page while not in overview should not toggle
1586 // overview.
1587 generator.ClickLeftButton();
1588 EXPECT_FALSE(IsSelecting());
1590 // Switch to overview mode.
1591 ToggleOverview();
1592 ASSERT_TRUE(IsSelecting());
1594 // Click should now exit overview mode.
1595 generator.ClickLeftButton();
1596 EXPECT_FALSE(IsSelecting());
1599 // Tests tapping on the desktop itself to cancel overview mode.
1600 TEST_F(WindowSelectorTest, CancelOverviewOnTap) {
1601 // Overview disabled by default.
1602 EXPECT_FALSE(IsSelecting());
1604 // Point and bounds selected so that they don't intersect. This causes
1605 // events located at the point to be passed to DesktopBackgroundController,
1606 // and not the window.
1607 gfx::Point point_in_background_page(0, 0);
1608 gfx::Rect bounds(10, 10, 100, 100);
1609 scoped_ptr<aura::Window> window1(CreateWindow(bounds));
1610 ui::test::EventGenerator& generator = GetEventGenerator();
1612 // Tapping on the background page while not in overview should not toggle
1613 // overview.
1614 generator.GestureTapAt(point_in_background_page);
1615 EXPECT_FALSE(IsSelecting());
1617 // Switch to overview mode.
1618 ToggleOverview();
1619 ASSERT_TRUE(IsSelecting());
1621 // Tap should now exit overview mode.
1622 generator.GestureTapAt(point_in_background_page);
1623 EXPECT_FALSE(IsSelecting());
1626 } // namespace ash