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();