• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "ash/wm/workspace/multi_window_resize_controller.h"
6 
7 #include "ash/shell.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_controller.h"
12 #include "ash/wm/workspace_controller_test_helper.h"
13 #include "ash/wm/workspace/workspace_event_handler_test_helper.h"
14 #include "ui/aura/test/event_generator.h"
15 #include "ui/aura/test/test_window_delegate.h"
16 #include "ui/aura/window.h"
17 #include "ui/base/hit_test.h"
18 #include "ui/gfx/screen.h"
19 #include "ui/views/widget/widget.h"
20 
21 namespace ash {
22 namespace internal {
23 
24 class MultiWindowResizeControllerTest : public test::AshTestBase {
25  public:
MultiWindowResizeControllerTest()26   MultiWindowResizeControllerTest() : resize_controller_(NULL) {}
~MultiWindowResizeControllerTest()27   virtual ~MultiWindowResizeControllerTest() {}
28 
SetUp()29   virtual void SetUp() OVERRIDE {
30     test::AshTestBase::SetUp();
31     WorkspaceController* wc =
32         test::ShellTestApi(Shell::GetInstance()).workspace_controller();
33     WorkspaceEventHandler* event_handler =
34         WorkspaceControllerTestHelper(wc).GetEventHandler();
35     resize_controller_ = WorkspaceEventHandlerTestHelper(event_handler).
36         resize_controller();
37   }
38 
39  protected:
CreateTestWindow(aura::WindowDelegate * delegate,const gfx::Rect & bounds)40   aura::Window* CreateTestWindow(aura::WindowDelegate* delegate,
41                                  const gfx::Rect& bounds) {
42     aura::Window* window = new aura::Window(delegate);
43     window->SetType(aura::client::WINDOW_TYPE_NORMAL);
44     window->Init(ui::LAYER_TEXTURED);
45     ParentWindowInPrimaryRootWindow(window);
46     window->SetBounds(bounds);
47     window->Show();
48     return window;
49   }
50 
ShowNow()51   void ShowNow() {
52     resize_controller_->ShowNow();
53   }
54 
IsShowing()55   bool IsShowing() {
56     return resize_controller_->IsShowing();
57   }
58 
HasPendingShow()59   bool HasPendingShow() {
60     return resize_controller_->show_timer_.IsRunning();
61   }
62 
HasPendingHide()63   bool HasPendingHide() {
64     return resize_controller_->hide_timer_.IsRunning();
65   }
66 
Hide()67   void Hide() {
68     resize_controller_->Hide();
69   }
70 
HasTarget(aura::Window * window)71   bool HasTarget(aura::Window* window) {
72     if (!resize_controller_->windows_.is_valid())
73       return false;
74     if ((resize_controller_->windows_.window1 == window ||
75          resize_controller_->windows_.window2 == window))
76       return true;
77     for (size_t i = 0;
78          i < resize_controller_->windows_.other_windows.size(); ++i) {
79       if (resize_controller_->windows_.other_windows[i] == window)
80         return true;
81     }
82     return false;
83   }
84 
IsOverWindows(const gfx::Point & loc)85   bool IsOverWindows(const gfx::Point& loc) {
86     return resize_controller_->IsOverWindows(loc);
87   }
88 
resize_widget()89   views::Widget* resize_widget() {
90     return resize_controller_->resize_widget_.get();
91   }
92 
93   MultiWindowResizeController* resize_controller_;
94 
95  private:
96   DISALLOW_COPY_AND_ASSIGN(MultiWindowResizeControllerTest);
97 };
98 
99 // Assertions around moving mouse over 2 windows.
TEST_F(MultiWindowResizeControllerTest,BasicTests)100 TEST_F(MultiWindowResizeControllerTest, BasicTests) {
101   aura::test::TestWindowDelegate delegate1;
102   scoped_ptr<aura::Window> w1(
103       CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
104   delegate1.set_window_component(HTRIGHT);
105   aura::test::TestWindowDelegate delegate2;
106   scoped_ptr<aura::Window> w2(
107       CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
108   delegate2.set_window_component(HTRIGHT);
109   aura::test::EventGenerator generator(w1->GetRootWindow());
110   generator.MoveMouseTo(99, 50);
111   EXPECT_TRUE(HasPendingShow());
112   EXPECT_TRUE(IsShowing());
113   EXPECT_FALSE(HasPendingHide());
114 
115   // Force a show now.
116   ShowNow();
117   EXPECT_FALSE(HasPendingShow());
118   EXPECT_TRUE(IsShowing());
119   EXPECT_FALSE(HasPendingHide());
120 
121   EXPECT_FALSE(IsOverWindows(gfx::Point(200, 200)));
122 
123   // Have to explicitly invoke this as MouseWatcher listens for native events.
124   resize_controller_->MouseMovedOutOfHost();
125   EXPECT_FALSE(HasPendingShow());
126   EXPECT_FALSE(IsShowing());
127   EXPECT_FALSE(HasPendingHide());
128 }
129 
130 // Makes sure deleting a window hides.
TEST_F(MultiWindowResizeControllerTest,DeleteWindow)131 TEST_F(MultiWindowResizeControllerTest, DeleteWindow) {
132   aura::test::TestWindowDelegate delegate1;
133   scoped_ptr<aura::Window> w1(
134       CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
135   delegate1.set_window_component(HTRIGHT);
136   aura::test::TestWindowDelegate delegate2;
137   scoped_ptr<aura::Window> w2(
138       CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
139   delegate2.set_window_component(HTRIGHT);
140   aura::test::EventGenerator generator(w1->GetRootWindow());
141   generator.MoveMouseTo(99, 50);
142   EXPECT_TRUE(HasPendingShow());
143   EXPECT_TRUE(IsShowing());
144   EXPECT_FALSE(HasPendingHide());
145 
146   // Force a show now.
147   ShowNow();
148   EXPECT_FALSE(HasPendingShow());
149   EXPECT_TRUE(IsShowing());
150   EXPECT_FALSE(HasPendingHide());
151 
152   // Move the mouse over the resize widget.
153   ASSERT_TRUE(resize_widget());
154   gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen());
155   generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1);
156   EXPECT_FALSE(HasPendingShow());
157   EXPECT_TRUE(IsShowing());
158   EXPECT_FALSE(HasPendingHide());
159 
160   // Move the resize widget
161   generator.PressLeftButton();
162   generator.MoveMouseTo(bounds.x() + 10, bounds.y() + 10);
163 
164   // Delete w2.
165   w2.reset();
166   EXPECT_TRUE(resize_widget() == NULL);
167   EXPECT_FALSE(HasPendingShow());
168   EXPECT_FALSE(IsShowing());
169   EXPECT_FALSE(HasPendingHide());
170   EXPECT_FALSE(HasTarget(w1.get()));
171 }
172 
173 // Tests resizing.
TEST_F(MultiWindowResizeControllerTest,Drag)174 TEST_F(MultiWindowResizeControllerTest, Drag) {
175   aura::test::TestWindowDelegate delegate1;
176   scoped_ptr<aura::Window> w1(
177       CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
178   delegate1.set_window_component(HTRIGHT);
179   aura::test::TestWindowDelegate delegate2;
180   scoped_ptr<aura::Window> w2(
181       CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
182   delegate2.set_window_component(HTRIGHT);
183   aura::test::EventGenerator generator(w1->GetRootWindow());
184   generator.MoveMouseTo(99, 50);
185   EXPECT_TRUE(HasPendingShow());
186   EXPECT_TRUE(IsShowing());
187   EXPECT_FALSE(HasPendingHide());
188 
189   // Force a show now.
190   ShowNow();
191   EXPECT_FALSE(HasPendingShow());
192   EXPECT_TRUE(IsShowing());
193   EXPECT_FALSE(HasPendingHide());
194 
195   // Move the mouse over the resize widget.
196   ASSERT_TRUE(resize_widget());
197   gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen());
198   generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1);
199   EXPECT_FALSE(HasPendingShow());
200   EXPECT_TRUE(IsShowing());
201   EXPECT_FALSE(HasPendingHide());
202 
203   // Move the resize widget
204   generator.PressLeftButton();
205   generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10);
206   generator.ReleaseLeftButton();
207 
208   EXPECT_TRUE(resize_widget());
209   EXPECT_FALSE(HasPendingShow());
210   EXPECT_TRUE(IsShowing());
211   EXPECT_FALSE(HasPendingHide());
212   EXPECT_EQ("0,0 110x100", w1->bounds().ToString());
213   EXPECT_EQ("110,0 100x100", w2->bounds().ToString());
214 }
215 
216 // Makes sure three windows are picked up.
TEST_F(MultiWindowResizeControllerTest,Three)217 TEST_F(MultiWindowResizeControllerTest, Three) {
218   aura::test::TestWindowDelegate delegate1;
219   scoped_ptr<aura::Window> w1(
220       CreateTestWindow(&delegate1, gfx::Rect(0, 0, 100, 100)));
221   delegate1.set_window_component(HTRIGHT);
222   aura::test::TestWindowDelegate delegate2;
223   scoped_ptr<aura::Window> w2(
224       CreateTestWindow(&delegate2, gfx::Rect(100, 0, 100, 100)));
225   delegate2.set_window_component(HTRIGHT);
226   aura::test::TestWindowDelegate delegate3;
227   scoped_ptr<aura::Window> w3(
228       CreateTestWindow(&delegate2, gfx::Rect(200, 0, 100, 100)));
229   delegate3.set_window_component(HTRIGHT);
230 
231   aura::test::EventGenerator generator(w1->GetRootWindow());
232   generator.MoveMouseTo(99, 50);
233   EXPECT_TRUE(HasPendingShow());
234   EXPECT_TRUE(IsShowing());
235   EXPECT_FALSE(HasPendingHide());
236   EXPECT_FALSE(HasTarget(w3.get()));
237 
238   ShowNow();
239   EXPECT_FALSE(HasPendingShow());
240   EXPECT_TRUE(IsShowing());
241   EXPECT_FALSE(HasPendingHide());
242 
243   // w3 should be picked up when resize is started.
244   gfx::Rect bounds(resize_widget()->GetWindowBoundsInScreen());
245   generator.MoveMouseTo(bounds.x() + 1, bounds.y() + 1);
246   generator.PressLeftButton();
247   generator.MoveMouseTo(bounds.x() + 11, bounds.y() + 10);
248 
249   EXPECT_TRUE(HasTarget(w3.get()));
250 
251   // Release the mouse. The resizer should still be visible and a subsequent
252   // press should not trigger a DCHECK.
253   generator.ReleaseLeftButton();
254   EXPECT_TRUE(IsShowing());
255   generator.PressLeftButton();
256 }
257 }  // namespace internal
258 }  // namespace ash
259