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.
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"
64 const char kActiveWindowChangedFromOverview
[] =
65 "WindowSelector_ActiveWindowChanged";
67 class NonActivatableActivationDelegate
68 : public aura::client::ActivationDelegate
{
70 bool ShouldActivate() const override
{ return false; }
73 void CancelDrag(DragDropController
* controller
, bool* canceled
) {
74 if (controller
->IsDragDropInProgress()) {
76 controller
->DragCancel();
82 // TODO(bruthig): Move all non-simple method definitions out of class
84 class WindowSelectorTest
: public test::AshTestBase
{
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
));
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
);
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();
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
);
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
);
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(),
179 transform
.TransformRect(&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);
196 return ash::Shell::GetInstance()->window_selector_controller()->
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())
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,
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
)
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();
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
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();
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.
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
);
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.
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();
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());
409 // Active the right window, the order should be the same.
410 wm::GetWindowState(right_window
.get())->Activate();
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());
417 // Switch the window positions, and the order should be switched.
418 left_window
->SetBounds(right_bounds
);
419 right_window
->SetBounds(left_bounds
);
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());
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())
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();
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());
451 // Active the right window, the order should be the same.
452 wm::GetWindowState(right_window
.get())->Activate();
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());
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();
471 const std::vector
<WindowSelectorItem
*>& overview1(GetWindowItemsForRoot(0));
472 int initial_order
[2] = {overview1
[0]->GetWindow()->id(),
473 overview1
[1]->GetWindow()->id()};
476 // Activate the other window, the order should be the same.
477 wm::GetWindowState(window2
.get())->Activate();
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());
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());
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()));
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());
537 EXPECT_EQ(text_filter_widget()->GetNativeWindow(), GetFocusedWindow());
538 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
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());
557 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
559 generator
.GestureTapAt(
560 gfx::ToEnclosingRect(GetTransformedTargetBounds(window2
.get()))
563 1, user_action_tester
.GetActionCount(kActiveWindowChangedFromOverview
));
565 // Click on |window2| to activate it and exit overview.
566 wm::ActivateWindow(window1
.get());
568 ClickWindow(window2
.get());
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());
576 ASSERT_TRUE(SelectWindow(window2
.get()));
577 SendKey(ui::VKEY_RETURN
);
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());
596 // Tap on |window1| to exit overview.
597 ui::test::EventGenerator
generator(Shell::GetPrimaryRootWindow(),
599 generator
.GestureTapAt(
600 gfx::ToEnclosingRect(GetTransformedTargetBounds(window1
.get()))
603 0, user_action_tester
.GetActionCount(kActiveWindowChangedFromOverview
));
605 // |window1| remains active. Click on it to exit overview.
606 ASSERT_EQ(window1
.get(), GetFocusedWindow());
608 ClickWindow(window1
.get());
610 0, user_action_tester
.GetActionCount(kActiveWindowChangedFromOverview
));
612 // |window1| remains active. Select using the keyboard.
613 ASSERT_EQ(window1
.get(), GetFocusedWindow());
615 ASSERT_TRUE(SelectWindow(window1
.get()));
616 SendKey(ui::VKEY_RETURN
);
618 0, user_action_tester
.GetActionCount(kActiveWindowChangedFromOverview
));
620 // Entering and exiting overview without user input should not record
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));
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());
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)));
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
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()));
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
);
702 // Clicking on |window1| while touching on |window1| should not cause
703 // a crash, overview mode should be disengaged, and |window1| should
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
730 EXPECT_EQ(window
, static_cast<aura::Window
*>(
731 targeter
->FindTargetForEvent(root_target
, &event1
)));
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));
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())
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
);
786 ASSERT_EQ(root_windows
[1], window1
->GetRootWindow());
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.
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
823 EXPECT_TRUE(wm::GetWindowState(window1
.get())->IsFullscreen());
824 EXPECT_FALSE(panel1
->IsVisible());
826 // Entering overview and selecting another window, the previous window remains
828 // TODO(flackr): Currently the panel remains hidden, but should become visible
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());
845 EXPECT_FALSE(shelf
->GetDimsShelf());
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());
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()));
877 // Since the fullscreen window is still active, window2 will still have the
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.
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());
898 EXPECT_FALSE(Shell::GetInstance()->GetAppListTargetVisibility());
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
);
917 EXPECT_TRUE(window1
->IsVisible());
918 EXPECT_TRUE(window1
->layer()->GetTargetVisibility());
921 ui::ScopedAnimationDurationScaleMode
test_duration_mode(
922 ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION
);
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)));
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());
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
));
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
));
965 EXPECT_TRUE(IsSelecting());
967 // A window being activated should exit overview mode.
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.
986 EXPECT_EQ(text_filter_widget()->GetNativeWindow(), GetFocusedWindow());
988 // If canceling overview mode, focus should be restored.
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
));
1002 EXPECT_FALSE(IsSelecting());
1005 // Tests that entering overview mode restores a window to its original
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()));
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
);
1022 EXPECT_NE(initial_bounds
, ToEnclosingRect(
1023 GetTransformedTargetBounds(window
.get())));
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());
1040 EXPECT_TRUE(window1
->IsVisible());
1041 EXPECT_TRUE(child1
->IsVisible());
1042 EXPECT_EQ(ToEnclosingRect(GetTransformedTargetBounds(child1
.get())),
1043 ToEnclosingRect(GetTransformedTargetBounds(window1
.get())));
1047 // Tests that clicking a modal window's parent activates the modal window in
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());
1057 // Given that their relative positions are preserved, the windows should still
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())
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.
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
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
);
1145 // Tests removing a display during overview.
1146 TEST_F(WindowSelectorTest
, RemoveDisplay
) {
1147 if (!SupportsMultipleDisplays())
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());
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
);
1207 WindowSelectorItem
* window_item
= GetWindowItemsForRoot(0).back();
1208 views::LabelButton
* label
= GetLabelButtonView(window_item
);
1209 // Has the label view been created?
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
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
1228 TEST_F(WindowSelectorTest
, DisplayOrientationChanged
) {
1229 if (!SupportsHostWindowResize())
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
));
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
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
));
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())
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
[] = {
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 // +-------+ +-------+ +-------+ +-------+
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
++) {
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]
1330 // Tests basic selection across multiple monitors.
1331 TEST_F(WindowSelectorTest
, BasicMultiMonitorArrowKeyNavigation
) {
1332 if (!SupportsMultipleDisplays())
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
));
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
1362 TEST_F(WindowSelectorTest
, MultiMonitorReversedOrder
) {
1363 if (!SupportsMultipleDisplays())
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());
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());
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())
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());
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.
1420 EXPECT_EQ(GetSelectedWindow(), window2
.get());
1423 window3
.reset(CreateWindow(bounds3
));
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
1431 EXPECT_EQ(GetSelectedWindow(), window3
.get());
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
));
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.
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.
1470 panel_manager
->GetCalloutWidgetForPanel(panel1
.get())->IsVisible());
1472 panel_manager
->GetCalloutWidgetForPanel(panel2
.get())->IsVisible());
1474 // Toggling the overview should hide the callout widgets.
1477 panel_manager
->GetCalloutWidgetForPanel(panel1
.get())->IsVisible());
1479 panel_manager
->GetCalloutWidgetForPanel(panel2
.get())->IsVisible());
1481 // Ending the overview should show them again.
1484 panel_manager
->GetCalloutWidgetForPanel(panel1
.get())->IsVisible());
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
);
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
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
);
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.
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
1587 generator
.ClickLeftButton();
1588 EXPECT_FALSE(IsSelecting());
1590 // Switch to overview mode.
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
1614 generator
.GestureTapAt(point_in_background_page
);
1615 EXPECT_FALSE(IsSelecting());
1617 // Switch to overview mode.
1619 ASSERT_TRUE(IsSelecting());
1621 // Tap should now exit overview mode.
1622 generator
.GestureTapAt(point_in_background_page
);
1623 EXPECT_FALSE(IsSelecting());