1 // Copyright (c) 2012 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 "ash/wm/workspace/multi_window_resize_controller.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/test/shell_test_api.h"
10 #include "ash/wm/window_util.h"
11 #include "ash/wm/workspace/workspace_event_handler_test_helper.h"
12 #include "ash/wm/workspace_controller.h"
13 #include "ash/wm/workspace_controller_test_helper.h"
14 #include "ui/aura/test/test_window_delegate.h"
15 #include "ui/aura/window.h"
16 #include "ui/base/hit_test.h"
17 #include "ui/events/test/event_generator.h"
18 #include "ui/gfx/screen.h"
19 #include "ui/views/widget/widget.h"
23 class MultiWindowResizeControllerTest
: public test::AshTestBase
{
25 MultiWindowResizeControllerTest() : resize_controller_(NULL
) {}
26 virtual ~MultiWindowResizeControllerTest() {}
28 virtual void SetUp() OVERRIDE
{
29 test::AshTestBase::SetUp();
30 WorkspaceController
* wc
=
31 test::ShellTestApi(Shell::GetInstance()).workspace_controller();
32 WorkspaceEventHandler
* event_handler
=
33 WorkspaceControllerTestHelper(wc
).GetEventHandler();
34 resize_controller_
= WorkspaceEventHandlerTestHelper(event_handler
).
39 aura::Window
* CreateTestWindow(aura::WindowDelegate
* delegate
,
40 const gfx::Rect
& bounds
) {
41 aura::Window
* window
= new aura::Window(delegate
);
42 window
->SetType(ui::wm::WINDOW_TYPE_NORMAL
);
43 window
->Init(aura::WINDOW_LAYER_TEXTURED
);
44 ParentWindowInPrimaryRootWindow(window
);
45 window
->SetBounds(bounds
);
51 resize_controller_
->ShowNow();
55 return resize_controller_
->IsShowing();
58 bool HasPendingShow() {
59 return resize_controller_
->show_timer_
.IsRunning();
62 bool HasPendingHide() {
63 return resize_controller_
->hide_timer_
.IsRunning();
67 resize_controller_
->Hide();
70 bool HasTarget(aura::Window
* window
) {
71 if (!resize_controller_
->windows_
.is_valid())
73 if ((resize_controller_
->windows_
.window1
== window
||
74 resize_controller_
->windows_
.window2
== window
))
77 i
< resize_controller_
->windows_
.other_windows
.size(); ++i
) {
78 if (resize_controller_
->windows_
.other_windows
[i
] == window
)
84 bool IsOverWindows(const gfx::Point
& loc
) {
85 return resize_controller_
->IsOverWindows(loc
);
88 views::Widget
* resize_widget() {
89 return resize_controller_
->resize_widget_
.get();
92 MultiWindowResizeController
* resize_controller_
;
95 DISALLOW_COPY_AND_ASSIGN(MultiWindowResizeControllerTest
);
98 // Assertions around moving mouse over 2 windows.
99 TEST_F(MultiWindowResizeControllerTest
, BasicTests
) {
100 aura::test::TestWindowDelegate delegate1
;
101 scoped_ptr
<aura::Window
> w1(
102 CreateTestWindow(&delegate1
, gfx::Rect(0, 0, 100, 100)));
103 delegate1
.set_window_component(HTRIGHT
);
104 aura::test::TestWindowDelegate delegate2
;
105 scoped_ptr
<aura::Window
> w2(
106 CreateTestWindow(&delegate2
, gfx::Rect(100, 0, 100, 100)));
107 delegate2
.set_window_component(HTRIGHT
);
108 ui::test::EventGenerator
generator(w1
->GetRootWindow());
109 generator
.MoveMouseTo(w1
->bounds().CenterPoint());
110 EXPECT_TRUE(HasPendingShow());
111 EXPECT_TRUE(IsShowing());
112 EXPECT_FALSE(HasPendingHide());
116 EXPECT_FALSE(HasPendingShow());
117 EXPECT_TRUE(IsShowing());
118 EXPECT_FALSE(HasPendingHide());
120 EXPECT_FALSE(IsOverWindows(gfx::Point(200, 200)));
122 // Have to explicitly invoke this as MouseWatcher listens for native events.
123 resize_controller_
->MouseMovedOutOfHost();
124 EXPECT_FALSE(HasPendingShow());
125 EXPECT_FALSE(IsShowing());
126 EXPECT_FALSE(HasPendingHide());
129 // Makes sure deleting a window hides.
130 TEST_F(MultiWindowResizeControllerTest
, DeleteWindow
) {
131 aura::test::TestWindowDelegate delegate1
;
132 scoped_ptr
<aura::Window
> w1(
133 CreateTestWindow(&delegate1
, gfx::Rect(0, 0, 100, 100)));
134 delegate1
.set_window_component(HTRIGHT
);
135 aura::test::TestWindowDelegate delegate2
;
136 scoped_ptr
<aura::Window
> w2(
137 CreateTestWindow(&delegate2
, gfx::Rect(100, 0, 100, 100)));
138 delegate2
.set_window_component(HTRIGHT
);
139 ui::test::EventGenerator
generator(w1
->GetRootWindow());
140 generator
.MoveMouseTo(w1
->bounds().CenterPoint());
141 EXPECT_TRUE(HasPendingShow());
142 EXPECT_TRUE(IsShowing());
143 EXPECT_FALSE(HasPendingHide());
147 EXPECT_FALSE(HasPendingShow());
148 EXPECT_TRUE(IsShowing());
149 EXPECT_FALSE(HasPendingHide());
151 // Move the mouse over the resize widget.
152 ASSERT_TRUE(resize_widget());
153 gfx::Rect
bounds(resize_widget()->GetWindowBoundsInScreen());
154 generator
.MoveMouseTo(bounds
.x() + 1, bounds
.y() + 1);
155 EXPECT_FALSE(HasPendingShow());
156 EXPECT_TRUE(IsShowing());
157 EXPECT_FALSE(HasPendingHide());
159 // Move the resize widget
160 generator
.PressLeftButton();
161 generator
.MoveMouseTo(bounds
.x() + 10, bounds
.y() + 10);
165 EXPECT_TRUE(resize_widget() == NULL
);
166 EXPECT_FALSE(HasPendingShow());
167 EXPECT_FALSE(IsShowing());
168 EXPECT_FALSE(HasPendingHide());
169 EXPECT_FALSE(HasTarget(w1
.get()));
173 TEST_F(MultiWindowResizeControllerTest
, Drag
) {
174 aura::test::TestWindowDelegate delegate1
;
175 scoped_ptr
<aura::Window
> w1(
176 CreateTestWindow(&delegate1
, gfx::Rect(0, 0, 100, 100)));
177 delegate1
.set_window_component(HTRIGHT
);
178 aura::test::TestWindowDelegate delegate2
;
179 scoped_ptr
<aura::Window
> w2(
180 CreateTestWindow(&delegate2
, gfx::Rect(100, 0, 100, 100)));
181 delegate2
.set_window_component(HTRIGHT
);
182 ui::test::EventGenerator
generator(w1
->GetRootWindow());
183 generator
.MoveMouseTo(w1
->bounds().CenterPoint());
184 EXPECT_TRUE(HasPendingShow());
185 EXPECT_TRUE(IsShowing());
186 EXPECT_FALSE(HasPendingHide());
190 EXPECT_FALSE(HasPendingShow());
191 EXPECT_TRUE(IsShowing());
192 EXPECT_FALSE(HasPendingHide());
194 // Move the mouse over the resize widget.
195 ASSERT_TRUE(resize_widget());
196 gfx::Rect
bounds(resize_widget()->GetWindowBoundsInScreen());
197 generator
.MoveMouseTo(bounds
.x() + 1, bounds
.y() + 1);
198 EXPECT_FALSE(HasPendingShow());
199 EXPECT_TRUE(IsShowing());
200 EXPECT_FALSE(HasPendingHide());
202 // Move the resize widget
203 generator
.PressLeftButton();
204 generator
.MoveMouseTo(bounds
.x() + 11, bounds
.y() + 10);
205 generator
.ReleaseLeftButton();
207 EXPECT_TRUE(resize_widget());
208 EXPECT_FALSE(HasPendingShow());
209 EXPECT_TRUE(IsShowing());
210 EXPECT_FALSE(HasPendingHide());
211 EXPECT_EQ("0,0 110x100", w1
->bounds().ToString());
212 EXPECT_EQ("110,0 100x100", w2
->bounds().ToString());
215 // Makes sure three windows are picked up.
216 TEST_F(MultiWindowResizeControllerTest
, Three
) {
217 aura::test::TestWindowDelegate delegate1
;
218 scoped_ptr
<aura::Window
> w1(
219 CreateTestWindow(&delegate1
, gfx::Rect(0, 0, 100, 100)));
220 delegate1
.set_window_component(HTRIGHT
);
221 aura::test::TestWindowDelegate delegate2
;
222 scoped_ptr
<aura::Window
> w2(
223 CreateTestWindow(&delegate2
, gfx::Rect(100, 0, 100, 100)));
224 delegate2
.set_window_component(HTRIGHT
);
225 aura::test::TestWindowDelegate delegate3
;
226 scoped_ptr
<aura::Window
> w3(
227 CreateTestWindow(&delegate3
, gfx::Rect(200, 0, 100, 100)));
228 delegate3
.set_window_component(HTRIGHT
);
230 ui::test::EventGenerator
generator(w1
->GetRootWindow());
231 generator
.MoveMouseTo(w1
->bounds().CenterPoint());
232 EXPECT_TRUE(HasPendingShow());
233 EXPECT_TRUE(IsShowing());
234 EXPECT_FALSE(HasPendingHide());
235 EXPECT_FALSE(HasTarget(w3
.get()));
238 EXPECT_FALSE(HasPendingShow());
239 EXPECT_TRUE(IsShowing());
240 EXPECT_FALSE(HasPendingHide());
242 // w3 should be picked up when resize is started.
243 gfx::Rect
bounds(resize_widget()->GetWindowBoundsInScreen());
244 generator
.MoveMouseTo(bounds
.x() + 1, bounds
.y() + 1);
245 generator
.PressLeftButton();
246 generator
.MoveMouseTo(bounds
.x() + 11, bounds
.y() + 10);
248 EXPECT_TRUE(HasTarget(w3
.get()));
250 // Release the mouse. The resizer should still be visible and a subsequent
251 // press should not trigger a DCHECK.
252 generator
.ReleaseLeftButton();
253 EXPECT_TRUE(IsShowing());
254 generator
.PressLeftButton();