Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / ash / wm / workspace / workspace_window_resizer_unittest.cc
blob791e843633fe2618248648a0d77cfa5cc64fc605
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/workspace_window_resizer.h"
7 #include "ash/ash_constants.h"
8 #include "ash/ash_switches.h"
9 #include "ash/display/display_manager.h"
10 #include "ash/root_window_controller.h"
11 #include "ash/screen_util.h"
12 #include "ash/shelf/shelf_layout_manager.h"
13 #include "ash/shell.h"
14 #include "ash/shell_window_ids.h"
15 #include "ash/test/ash_test_base.h"
16 #include "ash/wm/window_state.h"
17 #include "ash/wm/window_util.h"
18 #include "ash/wm/wm_event.h"
19 #include "ash/wm/workspace/phantom_window_controller.h"
20 #include "ash/wm/workspace_controller.h"
21 #include "base/command_line.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/strings/stringprintf.h"
24 #include "ui/aura/client/aura_constants.h"
25 #include "ui/aura/test/event_generator.h"
26 #include "ui/aura/test/test_window_delegate.h"
27 #include "ui/aura/window_event_dispatcher.h"
28 #include "ui/base/hit_test.h"
29 #include "ui/events/gestures/gesture_configuration.h"
30 #include "ui/gfx/insets.h"
31 #include "ui/gfx/screen.h"
32 #include "ui/views/widget/widget.h"
34 namespace ash {
35 namespace {
37 const int kRootHeight = 600;
39 // A simple window delegate that returns the specified min size.
40 class TestWindowDelegate : public aura::test::TestWindowDelegate {
41 public:
42 TestWindowDelegate() {
44 virtual ~TestWindowDelegate() {}
46 void set_min_size(const gfx::Size& size) {
47 min_size_ = size;
50 void set_max_size(const gfx::Size& size) {
51 max_size_ = size;
54 private:
55 // Overridden from aura::Test::TestWindowDelegate:
56 virtual gfx::Size GetMinimumSize() const OVERRIDE {
57 return min_size_;
60 virtual gfx::Size GetMaximumSize() const OVERRIDE {
61 return max_size_;
64 gfx::Size min_size_;
65 gfx::Size max_size_;
67 DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
70 } // namespace
72 class WorkspaceWindowResizerTest : public test::AshTestBase {
73 public:
74 WorkspaceWindowResizerTest() : workspace_resizer_(NULL) {}
75 virtual ~WorkspaceWindowResizerTest() {}
77 virtual void SetUp() OVERRIDE {
78 AshTestBase::SetUp();
79 UpdateDisplay(base::StringPrintf("800x%d", kRootHeight));
80 // Ignore the touch slop region.
81 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0);
83 aura::Window* root = Shell::GetPrimaryRootWindow();
84 gfx::Rect root_bounds(root->bounds());
85 #if defined(OS_WIN)
86 // RootWindow and Display can't resize on Windows Ash.
87 // http://crbug.com/165962
88 EXPECT_EQ(kRootHeight, root_bounds.height());
89 #endif
90 EXPECT_EQ(800, root_bounds.width());
91 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
92 window_.reset(new aura::Window(&delegate_));
93 window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
94 window_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
95 ParentWindowInPrimaryRootWindow(window_.get());
96 window_->set_id(1);
98 window2_.reset(new aura::Window(&delegate2_));
99 window2_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
100 window2_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
101 ParentWindowInPrimaryRootWindow(window2_.get());
102 window2_->set_id(2);
104 window3_.reset(new aura::Window(&delegate3_));
105 window3_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
106 window3_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
107 ParentWindowInPrimaryRootWindow(window3_.get());
108 window3_->set_id(3);
110 window4_.reset(new aura::Window(&delegate4_));
111 window4_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
112 window4_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
113 ParentWindowInPrimaryRootWindow(window4_.get());
114 window4_->set_id(4);
117 virtual void TearDown() OVERRIDE {
118 window_.reset();
119 window2_.reset();
120 window3_.reset();
121 window4_.reset();
122 touch_resize_window_.reset();
123 AshTestBase::TearDown();
126 // Returns a string identifying the z-order of each of the known child windows
127 // of |parent|. The returned string constains the id of the known windows and
128 // is ordered from topmost to bottomost windows.
129 std::string WindowOrderAsString(aura::Window* parent) const {
130 std::string result;
131 const aura::Window::Windows& windows = parent->children();
132 for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
133 i != windows.rend(); ++i) {
134 if (*i == window_ || *i == window2_ || *i == window3_) {
135 if (!result.empty())
136 result += " ";
137 result += base::IntToString((*i)->id());
140 return result;
143 protected:
144 WindowResizer* CreateResizerForTest(
145 aura::Window* window,
146 const gfx::Point& point_in_parent,
147 int window_component) {
148 WindowResizer* resizer = CreateWindowResizer(
149 window,
150 point_in_parent,
151 window_component,
152 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release();
153 workspace_resizer_ = WorkspaceWindowResizer::instance_;
154 return resizer;
156 WorkspaceWindowResizer* CreateWorkspaceResizerForTest(
157 aura::Window* window,
158 const gfx::Point& point_in_parent,
159 int window_component,
160 aura::client::WindowMoveSource source,
161 const std::vector<aura::Window*>& attached_windows) {
162 wm::WindowState* window_state = wm::GetWindowState(window);
163 window_state->CreateDragDetails(
164 window, point_in_parent, window_component, source);
165 return WorkspaceWindowResizer::Create(window_state, attached_windows);
168 PhantomWindowController* snap_phantom_window_controller() const {
169 return workspace_resizer_->snap_phantom_window_controller_.get();
172 gfx::Point CalculateDragPoint(const WindowResizer& resizer,
173 int delta_x,
174 int delta_y) const {
175 gfx::Point location = resizer.GetInitialLocation();
176 location.set_x(location.x() + delta_x);
177 location.set_y(location.y() + delta_y);
178 return location;
181 std::vector<aura::Window*> empty_windows() const {
182 return std::vector<aura::Window*>();
185 ShelfLayoutManager* shelf_layout_manager() {
186 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
189 void InitTouchResizeWindow(const gfx::Rect& bounds, int window_component) {
190 touch_resize_delegate_.set_window_component(window_component);
191 touch_resize_window_.reset(
192 CreateTestWindowInShellWithDelegate(&touch_resize_delegate_, 0,
193 bounds));
196 TestWindowDelegate delegate_;
197 TestWindowDelegate delegate2_;
198 TestWindowDelegate delegate3_;
199 TestWindowDelegate delegate4_;
200 scoped_ptr<aura::Window> window_;
201 scoped_ptr<aura::Window> window2_;
202 scoped_ptr<aura::Window> window3_;
203 scoped_ptr<aura::Window> window4_;
205 TestWindowDelegate touch_resize_delegate_;
206 scoped_ptr<aura::Window> touch_resize_window_;
207 WorkspaceWindowResizer* workspace_resizer_;
209 private:
210 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
213 // Assertions around attached window resize dragging from the right with 2
214 // windows.
215 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_2) {
216 window_->SetBounds(gfx::Rect(0, 300, 400, 300));
217 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
219 std::vector<aura::Window*> windows;
220 windows.push_back(window2_.get());
221 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
222 window_.get(), gfx::Point(), HTRIGHT,
223 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
224 ASSERT_TRUE(resizer.get());
225 // Move it 100 to the right, which should expand w1 and push w2.
226 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
227 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
228 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
230 // Push off the screen, w2 should be resized to its min.
231 delegate2_.set_min_size(gfx::Size(20, 20));
232 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
233 EXPECT_EQ("0,300 780x300", window_->bounds().ToString());
234 EXPECT_EQ("780,200 20x200", window2_->bounds().ToString());
236 // Move back to 100 and verify w2 gets its original size.
237 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
238 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
239 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
241 // Revert and make sure everything moves back.
242 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
243 resizer->RevertDrag();
244 EXPECT_EQ("0,300 400x300", window_->bounds().ToString());
245 EXPECT_EQ("400,200 100x200", window2_->bounds().ToString());
248 // Assertions around collapsing and expanding.
249 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_Compress) {
250 window_->SetBounds(gfx::Rect( 0, 300, 400, 300));
251 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
253 std::vector<aura::Window*> windows;
254 windows.push_back(window2_.get());
255 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
256 window_.get(), gfx::Point(), HTRIGHT,
257 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
258 ASSERT_TRUE(resizer.get());
259 // Move it 100 to the left, which should expand w2 and collapse w1.
260 resizer->Drag(CalculateDragPoint(*resizer, -100, 10), 0);
261 EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
262 EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
264 // Collapse all the way to w1's min.
265 delegate_.set_min_size(gfx::Size(20, 20));
266 resizer->Drag(CalculateDragPoint(*resizer, -800, 20), 0);
267 EXPECT_EQ("0,300 20x300", window_->bounds().ToString());
268 EXPECT_EQ("20,200 480x200", window2_->bounds().ToString());
270 // Move 100 to the left.
271 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
272 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
273 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
275 // Back to -100.
276 resizer->Drag(CalculateDragPoint(*resizer, -100, 20), 0);
277 EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
278 EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
281 // Assertions around attached window resize dragging from the right with 3
282 // windows.
283 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3) {
284 window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
285 window2_->SetBounds(gfx::Rect(300, 300, 150, 200));
286 window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
287 delegate2_.set_min_size(gfx::Size(52, 50));
288 delegate3_.set_min_size(gfx::Size(38, 50));
290 std::vector<aura::Window*> windows;
291 windows.push_back(window2_.get());
292 windows.push_back(window3_.get());
293 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
294 window_.get(), gfx::Point(), HTRIGHT,
295 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
296 ASSERT_TRUE(resizer.get());
297 // Move it 100 to the right, which should expand w1 and push w2 and w3.
298 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
299 EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
300 EXPECT_EQ("400,300 150x200", window2_->bounds().ToString());
301 EXPECT_EQ("550,300 100x200", window3_->bounds().ToString());
303 // Move it 300, things should compress.
304 resizer->Drag(CalculateDragPoint(*resizer, 300, -10), 0);
305 EXPECT_EQ("100,300 500x300", window_->bounds().ToString());
306 EXPECT_EQ("600,300 120x200", window2_->bounds().ToString());
307 EXPECT_EQ("720,300 80x200", window3_->bounds().ToString());
309 // Move it so much the last two end up at their min.
310 resizer->Drag(CalculateDragPoint(*resizer, 800, 50), 0);
311 EXPECT_EQ("100,300 610x300", window_->bounds().ToString());
312 EXPECT_EQ("710,300 52x200", window2_->bounds().ToString());
313 EXPECT_EQ("762,300 38x200", window3_->bounds().ToString());
315 // Revert and make sure everything moves back.
316 resizer->RevertDrag();
317 EXPECT_EQ("100,300 200x300", window_->bounds().ToString());
318 EXPECT_EQ("300,300 150x200", window2_->bounds().ToString());
319 EXPECT_EQ("450,300 100x200", window3_->bounds().ToString());
322 // Assertions around attached window resizing (collapsing and expanding) with
323 // 3 windows.
324 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3_Compress) {
325 window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
326 window2_->SetBounds(gfx::Rect(300, 300, 200, 200));
327 window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
328 delegate2_.set_min_size(gfx::Size(52, 50));
329 delegate3_.set_min_size(gfx::Size(38, 50));
331 std::vector<aura::Window*> windows;
332 windows.push_back(window2_.get());
333 windows.push_back(window3_.get());
334 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
335 window_.get(), gfx::Point(), HTRIGHT,
336 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
337 ASSERT_TRUE(resizer.get());
338 // Move it -100 to the right, which should collapse w1 and expand w2 and w3.
339 resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
340 EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
341 EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
342 EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
344 // Move it 100 to the right.
345 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
346 EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
347 EXPECT_EQ("400,300 200x200", window2_->bounds().ToString());
348 EXPECT_EQ("600,300 100x200", window3_->bounds().ToString());
350 // 100 to the left again.
351 resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
352 EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
353 EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
354 EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
357 // Assertions around collapsing and expanding from the bottom.
358 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_Compress) {
359 window_->SetBounds(gfx::Rect( 0, 100, 400, 300));
360 window2_->SetBounds(gfx::Rect(400, 400, 100, 200));
362 std::vector<aura::Window*> windows;
363 windows.push_back(window2_.get());
364 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
365 window_.get(), gfx::Point(), HTBOTTOM,
366 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
367 ASSERT_TRUE(resizer.get());
368 // Move it up 100, which should expand w2 and collapse w1.
369 resizer->Drag(CalculateDragPoint(*resizer, 10, -100), 0);
370 EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
371 EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
373 // Collapse all the way to w1's min.
374 delegate_.set_min_size(gfx::Size(20, 20));
375 resizer->Drag(CalculateDragPoint(*resizer, 20, -800), 0);
376 EXPECT_EQ("0,100 400x20", window_->bounds().ToString());
377 EXPECT_EQ("400,120 100x480", window2_->bounds().ToString());
379 // Move 100 down.
380 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
381 EXPECT_EQ("0,100 400x400", window_->bounds().ToString());
382 EXPECT_EQ("400,500 100x100", window2_->bounds().ToString());
384 // Back to -100.
385 resizer->Drag(CalculateDragPoint(*resizer, 20, -100), 0);
386 EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
387 EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
390 // Assertions around attached window resize dragging from the bottom with 2
391 // windows.
392 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_2) {
393 window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
394 window2_->SetBounds(gfx::Rect(0, 250, 200, 100));
396 std::vector<aura::Window*> windows;
397 windows.push_back(window2_.get());
398 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
399 window_.get(), gfx::Point(), HTBOTTOM,
400 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
401 ASSERT_TRUE(resizer.get());
402 // Move it 100 to the bottom, which should expand w1 and push w2.
403 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
404 EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
405 EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
407 // Push off the screen, w2 should be resized to its min.
408 delegate2_.set_min_size(gfx::Size(20, 20));
409 resizer->Drag(CalculateDragPoint(*resizer, 50, 820), 0);
410 EXPECT_EQ("0,50 400x530", window_->bounds().ToString());
411 EXPECT_EQ("0,580 200x20", window2_->bounds().ToString());
413 // Move back to 100 and verify w2 gets its original size.
414 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
415 EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
416 EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
418 // Revert and make sure everything moves back.
419 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
420 resizer->RevertDrag();
421 EXPECT_EQ("0,50 400x200", window_->bounds().ToString());
422 EXPECT_EQ("0,250 200x100", window2_->bounds().ToString());
425 #if defined(OS_WIN)
426 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
427 #define MAYBE_AttachedResize_BOTTOM_3 DISABLED_AttachedResize_BOTTOM_3
428 #else
429 #define MAYBE_AttachedResize_BOTTOM_3 AttachedResize_BOTTOM_3
430 #endif
432 // Assertions around attached window resize dragging from the bottom with 3
433 // windows.
434 TEST_F(WorkspaceWindowResizerTest, MAYBE_AttachedResize_BOTTOM_3) {
435 UpdateDisplay("600x800");
436 aura::Window* root = Shell::GetPrimaryRootWindow();
437 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
439 window_->SetBounds(gfx::Rect( 300, 100, 300, 200));
440 window2_->SetBounds(gfx::Rect(300, 300, 200, 150));
441 window3_->SetBounds(gfx::Rect(300, 450, 200, 100));
442 delegate2_.set_min_size(gfx::Size(50, 52));
443 delegate3_.set_min_size(gfx::Size(50, 38));
445 std::vector<aura::Window*> windows;
446 windows.push_back(window2_.get());
447 windows.push_back(window3_.get());
448 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
449 window_.get(), gfx::Point(), HTBOTTOM,
450 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
451 ASSERT_TRUE(resizer.get());
452 // Move it 100 down, which should expand w1 and push w2 and w3.
453 resizer->Drag(CalculateDragPoint(*resizer, -10, 100), 0);
454 EXPECT_EQ("300,100 300x300", window_->bounds().ToString());
455 EXPECT_EQ("300,400 200x150", window2_->bounds().ToString());
456 EXPECT_EQ("300,550 200x100", window3_->bounds().ToString());
458 // Move it 296 things should compress.
459 resizer->Drag(CalculateDragPoint(*resizer, -10, 296), 0);
460 EXPECT_EQ("300,100 300x496", window_->bounds().ToString());
461 EXPECT_EQ("300,596 200x123", window2_->bounds().ToString());
462 EXPECT_EQ("300,719 200x81", window3_->bounds().ToString());
464 // Move it so much everything ends up at its min.
465 resizer->Drag(CalculateDragPoint(*resizer, 50, 798), 0);
466 EXPECT_EQ("300,100 300x610", window_->bounds().ToString());
467 EXPECT_EQ("300,710 200x52", window2_->bounds().ToString());
468 EXPECT_EQ("300,762 200x38", window3_->bounds().ToString());
470 // Revert and make sure everything moves back.
471 resizer->RevertDrag();
472 EXPECT_EQ("300,100 300x200", window_->bounds().ToString());
473 EXPECT_EQ("300,300 200x150", window2_->bounds().ToString());
474 EXPECT_EQ("300,450 200x100", window3_->bounds().ToString());
477 // Assertions around attached window resizing (collapsing and expanding) with
478 // 3 windows.
479 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_3_Compress) {
480 window_->SetBounds(gfx::Rect( 0, 0, 200, 200));
481 window2_->SetBounds(gfx::Rect(10, 200, 200, 200));
482 window3_->SetBounds(gfx::Rect(20, 400, 100, 100));
483 delegate2_.set_min_size(gfx::Size(52, 50));
484 delegate3_.set_min_size(gfx::Size(38, 50));
486 std::vector<aura::Window*> windows;
487 windows.push_back(window2_.get());
488 windows.push_back(window3_.get());
489 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
490 window_.get(), gfx::Point(), HTBOTTOM,
491 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
492 ASSERT_TRUE(resizer.get());
493 // Move it 100 up, which should collapse w1 and expand w2 and w3.
494 resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
495 EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
496 EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
497 EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
499 // Move it 100 down.
500 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
501 EXPECT_EQ("0,0 200x300", window_->bounds().ToString());
502 EXPECT_EQ("10,300 200x200", window2_->bounds().ToString());
503 EXPECT_EQ("20,500 100x100", window3_->bounds().ToString());
505 // 100 up again.
506 resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
507 EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
508 EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
509 EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
512 // Tests that touch-dragging a window does not lock the mouse cursor
513 // and therefore shows the cursor on a mousemove.
514 TEST_F(WorkspaceWindowResizerTest, MouseMoveWithTouchDrag) {
515 window_->SetBounds(gfx::Rect(0, 300, 400, 300));
516 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
518 Shell* shell = Shell::GetInstance();
519 aura::test::EventGenerator generator(window_->GetRootWindow());
521 // The cursor should not be locked initially.
522 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
524 std::vector<aura::Window*> windows;
525 windows.push_back(window2_.get());
526 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
527 window_.get(), gfx::Point(), HTRIGHT,
528 aura::client::WINDOW_MOVE_SOURCE_TOUCH, windows));
529 ASSERT_TRUE(resizer.get());
531 // Creating a WorkspaceWindowResizer should not lock the cursor.
532 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
534 // The cursor should be hidden after touching the screen and
535 // starting a drag.
536 EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
537 generator.PressTouch();
538 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
539 EXPECT_FALSE(shell->cursor_manager()->IsCursorVisible());
540 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
542 // Moving the mouse should show the cursor.
543 generator.MoveMouseBy(1, 1);
544 EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
545 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
547 resizer->RevertDrag();
550 // Assertions around dragging to the left/right edge of the screen.
551 TEST_F(WorkspaceWindowResizerTest, Edge) {
552 if (!SupportsHostWindowResize())
553 return;
555 // Resize host window to force insets update.
556 UpdateDisplay("800x700");
557 // TODO(varkha): Insets are reset after every drag because of
558 // http://crbug.com/292238.
559 // Window is wide enough not to get docked right away.
560 window_->SetBounds(gfx::Rect(20, 30, 400, 60));
561 wm::WindowState* window_state = wm::GetWindowState(window_.get());
564 gfx::Rect expected_bounds_in_parent(
565 wm::GetDefaultLeftSnappedWindowBoundsInParent(window_.get()));
567 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
568 window_.get(), gfx::Point(), HTCAPTION));
569 ASSERT_TRUE(resizer.get());
570 resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
571 resizer->CompleteDrag();
573 EXPECT_EQ(expected_bounds_in_parent.ToString(),
574 window_->bounds().ToString());
575 ASSERT_TRUE(window_state->HasRestoreBounds());
576 EXPECT_EQ("20,30 400x60",
577 window_state->GetRestoreBoundsInScreen().ToString());
579 // Try the same with the right side.
581 gfx::Rect expected_bounds_in_parent(
582 wm::GetDefaultRightSnappedWindowBoundsInParent(window_.get()));
584 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
585 window_.get(), gfx::Point(), HTCAPTION));
586 ASSERT_TRUE(resizer.get());
587 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
588 resizer->CompleteDrag();
589 EXPECT_EQ(expected_bounds_in_parent.ToString(),
590 window_->bounds().ToString());
591 ASSERT_TRUE(window_state->HasRestoreBounds());
592 EXPECT_EQ("20,30 400x60",
593 window_state->GetRestoreBoundsInScreen().ToString());
596 // Test if the restore bounds is correct in multiple displays.
597 if (!SupportsMultipleDisplays())
598 return;
600 // Restore the window to clear snapped state.
601 window_state->Restore();
603 UpdateDisplay("800x600,500x600");
604 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
605 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
606 // Window is wide enough not to get docked right away.
607 window_->SetBoundsInScreen(gfx::Rect(800, 10, 400, 60),
608 ScreenUtil::GetSecondaryDisplay());
609 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
611 EXPECT_EQ("800,10 400x60", window_->GetBoundsInScreen().ToString());
613 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
614 window_.get(), gfx::Point(), HTCAPTION));
615 ASSERT_TRUE(resizer.get());
616 resizer->Drag(CalculateDragPoint(*resizer, 499, 0), 0);
617 int bottom =
618 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
619 resizer->CompleteDrag();
620 // With the resolution of 500x600 we will hit in this case the 50% screen
621 // size setting.
622 // TODO(varkha): Insets are updated because of http://crbug.com/292238
623 EXPECT_EQ("250,0 250x" + base::IntToString(bottom),
624 window_->bounds().ToString());
625 EXPECT_EQ("800,10 400x60",
626 window_state->GetRestoreBoundsInScreen().ToString());
630 // Check that non resizable windows will not get resized.
631 TEST_F(WorkspaceWindowResizerTest, NonResizableWindows) {
632 window_->SetBounds(gfx::Rect(20, 30, 50, 60));
633 window_->SetProperty(aura::client::kCanResizeKey, false);
635 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
636 window_.get(), gfx::Point(), HTCAPTION));
637 ASSERT_TRUE(resizer.get());
638 resizer->Drag(CalculateDragPoint(*resizer, -20, 0), 0);
639 resizer->CompleteDrag();
640 EXPECT_EQ("0,30 50x60", window_->bounds().ToString());
643 TEST_F(WorkspaceWindowResizerTest, CancelSnapPhantom) {
644 if (!SupportsMultipleDisplays())
645 return;
647 UpdateDisplay("800x600,800x600");
648 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
649 ASSERT_EQ(2U, root_windows.size());
651 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
652 Shell::GetScreen()->GetPrimaryDisplay());
653 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
654 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
656 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
657 window_.get(), gfx::Point(), HTCAPTION));
658 ASSERT_TRUE(resizer.get());
659 EXPECT_FALSE(snap_phantom_window_controller());
661 // The pointer is on the edge but not shared. The snap phantom window
662 // controller should be non-NULL.
663 resizer->Drag(CalculateDragPoint(*resizer, 799, 0), 0);
664 EXPECT_TRUE(snap_phantom_window_controller());
666 // Move the cursor across the edge. Now the snap phantom window controller
667 // should be canceled.
668 resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0);
669 EXPECT_FALSE(snap_phantom_window_controller());
673 // Verifies that dragging a snapped window unsnaps it.
674 TEST_F(WorkspaceWindowResizerTest, DragSnapped) {
675 wm::WindowState* window_state = ash::wm::GetWindowState(window_.get());
677 const gfx::Rect kInitialBounds(100, 100, 100, 100);
678 window_->SetBounds(kInitialBounds);
679 window_->Show();
680 const wm::WMEvent snap_event(wm::WM_EVENT_SNAP_LEFT);
681 window_state->OnWMEvent(&snap_event);
682 EXPECT_EQ(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
683 gfx::Rect snapped_bounds = window_->bounds();
684 EXPECT_NE(snapped_bounds.ToString(), kInitialBounds.ToString());
685 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
686 kInitialBounds.ToString());
688 // Dragging a side snapped window should unsnap it.
689 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
690 window_.get(), gfx::Point(), HTCAPTION));
691 resizer->Drag(CalculateDragPoint(*resizer, 10, 0), 0);
692 resizer->CompleteDrag();
693 EXPECT_EQ(wm::WINDOW_STATE_TYPE_NORMAL, window_state->GetStateType());
694 EXPECT_EQ("10,0 100x100", window_->bounds().ToString());
695 EXPECT_FALSE(window_state->HasRestoreBounds());
698 // Verifies the behavior of resizing a side snapped window.
699 TEST_F(WorkspaceWindowResizerTest, ResizeSnapped) {
700 wm::WindowState* window_state = ash::wm::GetWindowState(window_.get());
702 const gfx::Rect kInitialBounds(100, 100, 100, 100);
703 window_->SetBounds(kInitialBounds);
704 window_->Show();
706 const wm::WMEvent snap_event(wm::WM_EVENT_SNAP_LEFT);
707 window_state->OnWMEvent(&snap_event);
708 EXPECT_EQ(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
709 gfx::Rect snapped_bounds = window_->bounds();
710 EXPECT_NE(snapped_bounds.ToString(), kInitialBounds.ToString());
711 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
712 kInitialBounds.ToString());
715 // 1) Resizing a side snapped window to make it wider should not unsnap the
716 // window.
717 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
718 window_.get(), gfx::Point(), HTRIGHT));
719 resizer->Drag(CalculateDragPoint(*resizer, 10, 0), 0);
720 resizer->CompleteDrag();
721 EXPECT_EQ(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
722 snapped_bounds.Inset(0, 0, -10, 0);
723 EXPECT_EQ(snapped_bounds.ToString(), window_->bounds().ToString());
724 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
725 kInitialBounds.ToString());
729 // 2) Resizing a side snapped window vertically and then undoing the change
730 // should not unsnap.
731 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
732 window_.get(), gfx::Point(), HTBOTTOM));
733 resizer->Drag(CalculateDragPoint(*resizer, 0, -30), 0);
734 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
735 resizer->CompleteDrag();
736 EXPECT_EQ(wm::WINDOW_STATE_TYPE_LEFT_SNAPPED, window_state->GetStateType());
737 EXPECT_EQ(snapped_bounds.ToString(), window_->bounds().ToString());
738 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
739 kInitialBounds.ToString());
743 // 3) Resizing a side snapped window vertically and then not undoing the
744 // change should unsnap.
745 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
746 window_.get(), gfx::Point(), HTBOTTOM));
747 resizer->Drag(CalculateDragPoint(*resizer, 0, -10), 0);
748 resizer->CompleteDrag();
749 EXPECT_EQ(wm::WINDOW_STATE_TYPE_NORMAL, window_state->GetStateType());
750 gfx::Rect expected_bounds(snapped_bounds);
751 expected_bounds.Inset(0, 0, 0, 10);
752 EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
753 EXPECT_FALSE(window_state->HasRestoreBounds());
757 // Verifies windows are correctly restacked when reordering multiple windows.
758 TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
759 window_->SetBounds(gfx::Rect( 0, 0, 200, 300));
760 window2_->SetBounds(gfx::Rect(200, 0, 100, 200));
761 window3_->SetBounds(gfx::Rect(300, 0, 100, 100));
764 std::vector<aura::Window*> windows;
765 windows.push_back(window2_.get());
766 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
767 window_.get(), gfx::Point(), HTRIGHT,
768 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
769 ASSERT_TRUE(resizer.get());
770 // Move it 100 to the right, which should expand w1 and push w2 and w3.
771 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
773 // 2 should be topmost since it's initially the highest in the stack.
774 EXPECT_EQ("2 1 3", WindowOrderAsString(window_->parent()));
778 std::vector<aura::Window*> windows;
779 windows.push_back(window3_.get());
780 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
781 window2_.get(), gfx::Point(), HTRIGHT,
782 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
783 ASSERT_TRUE(resizer.get());
784 // Move it 100 to the right, which should expand w1 and push w2 and w3.
785 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
787 // 2 should be topmost since it's initially the highest in the stack.
788 EXPECT_EQ("2 3 1", WindowOrderAsString(window_->parent()));
792 // Makes sure we don't allow dragging below the work area.
793 TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) {
794 Shell::GetInstance()->SetDisplayWorkAreaInsets(
795 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
797 ASSERT_EQ(1, Shell::GetScreen()->GetNumDisplays());
799 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
800 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
801 window_.get(), gfx::Point(), HTCAPTION));
802 ASSERT_TRUE(resizer.get());
803 resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
804 int expected_y =
805 kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
806 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
807 window_->bounds().ToString());
810 // Makes sure we don't allow dragging on the work area with multidisplay.
811 TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
812 if (!SupportsMultipleDisplays())
813 return;
815 UpdateDisplay("800x600,800x600");
816 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
818 Shell::GetInstance()->SetDisplayWorkAreaInsets(
819 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
821 // Positions the secondary display at the bottom the primary display.
822 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
823 ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 0));
826 window_->SetBounds(gfx::Rect(100, 200, 300, 20));
827 DCHECK_LT(window_->bounds().height(),
828 WorkspaceWindowResizer::kMinOnscreenHeight);
829 // Drag down avoiding dragging along the edge as that would side-snap.
830 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
831 window_.get(), gfx::Point(10, 0), HTCAPTION));
832 ASSERT_TRUE(resizer.get());
833 resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
834 int expected_y = kRootHeight - window_->bounds().height() - 10;
835 // When the mouse cursor is in the primary display, the window cannot move
836 // on non-work area but can get all the way towards the bottom,
837 // restricted only by the window height.
838 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x20",
839 window_->bounds().ToString());
840 // Revert the drag in order to not remember the restore bounds.
841 resizer->RevertDrag();
844 Shell::GetInstance()->SetDisplayWorkAreaInsets(
845 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
847 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
848 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
849 window_.get(), gfx::Point(10, 0), HTCAPTION));
850 ASSERT_TRUE(resizer.get());
851 // Drag down avoiding dragging along the edge as that would side-snap.
852 resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
853 int expected_y =
854 kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
855 // When the mouse cursor is in the primary display, the window cannot move
856 // on non-work area with kMinOnscreenHeight margin.
857 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
858 window_->bounds().ToString());
859 resizer->CompleteDrag();
863 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
864 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
865 window_.get(), window_->bounds().origin(), HTCAPTION));
866 ASSERT_TRUE(resizer.get());
867 // Drag down avoiding getting stuck against the shelf on the bottom screen.
868 resizer->Drag(CalculateDragPoint(*resizer, 0, 500), 0);
869 // The window can move to the secondary display beyond non-work area of
870 // the primary display.
871 EXPECT_EQ("100,700 300x400", window_->bounds().ToString());
872 resizer->CompleteDrag();
876 // Makes sure we don't allow dragging off the top of the work area.
877 TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) {
878 Shell::GetInstance()->SetDisplayWorkAreaInsets(
879 Shell::GetPrimaryRootWindow(), gfx::Insets(10, 0, 0, 0));
881 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
882 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
883 window_.get(), gfx::Point(), HTCAPTION));
884 ASSERT_TRUE(resizer.get());
885 resizer->Drag(CalculateDragPoint(*resizer, 0, -600), 0);
886 EXPECT_EQ("100,10 300x400", window_->bounds().ToString());
889 TEST_F(WorkspaceWindowResizerTest, ResizeBottomOutsideWorkArea) {
890 Shell::GetInstance()->SetDisplayWorkAreaInsets(
891 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
893 window_->SetBounds(gfx::Rect(100, 200, 300, 380));
894 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
895 window_.get(), gfx::Point(), HTTOP));
896 ASSERT_TRUE(resizer.get());
897 resizer->Drag(CalculateDragPoint(*resizer, 8, 0), 0);
898 EXPECT_EQ("100,200 300x380", window_->bounds().ToString());
901 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideLeftWorkArea) {
902 Shell::GetInstance()->SetDisplayWorkAreaInsets(
903 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
904 int left = ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_.get()).x();
905 int pixels_to_left_border = 50;
906 int window_width = 300;
907 int window_x = left - window_width + pixels_to_left_border;
908 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
909 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
910 window_.get(), gfx::Point(pixels_to_left_border, 0), HTRIGHT));
911 ASSERT_TRUE(resizer.get());
912 resizer->Drag(CalculateDragPoint(*resizer, -window_width, 0), 0);
913 EXPECT_EQ(base::IntToString(window_x) + ",100 " +
914 base::IntToString(kMinimumOnScreenArea - window_x) +
915 "x380", window_->bounds().ToString());
918 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
919 Shell::GetInstance()->SetDisplayWorkAreaInsets(
920 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
921 int right = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
922 window_.get()).right();
923 int pixels_to_right_border = 50;
924 int window_width = 300;
925 int window_x = right - pixels_to_right_border;
926 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
927 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
928 window_.get(), gfx::Point(window_x, 0), HTLEFT));
929 ASSERT_TRUE(resizer.get());
930 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
931 EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
932 ",100 " +
933 base::IntToString(window_width - pixels_to_right_border +
934 kMinimumOnScreenArea) +
935 "x380", window_->bounds().ToString());
938 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
939 Shell::GetInstance()->SetDisplayWorkAreaInsets(
940 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
941 int bottom = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
942 window_.get()).bottom();
943 int delta_to_bottom = 50;
944 int height = 380;
945 window_->SetBounds(gfx::Rect(100, bottom - delta_to_bottom, 300, height));
946 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
947 window_.get(), gfx::Point(0, bottom - delta_to_bottom), HTTOP));
948 ASSERT_TRUE(resizer.get());
949 resizer->Drag(CalculateDragPoint(*resizer, 0, bottom), 0);
950 EXPECT_EQ("100," +
951 base::IntToString(bottom - kMinimumOnScreenArea) +
952 " 300x" +
953 base::IntToString(height - (delta_to_bottom -
954 kMinimumOnScreenArea)),
955 window_->bounds().ToString());
958 // Verifies that 'outside' check of the resizer take into account the extended
959 // desktop in case of repositions.
960 TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
961 // Only primary display. Changes the window position to fit within the
962 // display.
963 Shell::GetInstance()->SetDisplayWorkAreaInsets(
964 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
965 int right = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
966 window_.get()).right();
967 int pixels_to_right_border = 50;
968 int window_width = 300;
969 int window_x = right - pixels_to_right_border;
970 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
971 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
972 window_.get(), gfx::Point(window_x, 0), HTCAPTION));
973 ASSERT_TRUE(resizer.get());
974 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
975 EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
976 ",100 " +
977 base::IntToString(window_width) +
978 "x380", window_->bounds().ToString());
980 if (!SupportsMultipleDisplays())
981 return;
983 // With secondary display. Operation itself is same but doesn't change
984 // the position because the window is still within the secondary display.
985 UpdateDisplay("1000x600,600x400");
986 Shell::GetInstance()->SetDisplayWorkAreaInsets(
987 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
988 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
989 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
990 EXPECT_EQ(base::IntToString(window_x + window_width) +
991 ",100 " +
992 base::IntToString(window_width) +
993 "x380", window_->bounds().ToString());
996 // Verifies snapping to edges works.
997 TEST_F(WorkspaceWindowResizerTest, SnapToEdge) {
998 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
999 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1000 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1001 // Click 50px to the right so that the mouse pointer does not leave the
1002 // workspace ensuring sticky behavior.
1003 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1004 window_.get(),
1005 window_->bounds().origin() + gfx::Vector2d(50, 0),
1006 HTCAPTION));
1007 ASSERT_TRUE(resizer.get());
1008 // Move to an x-coordinate of 15, which should not snap.
1009 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1010 // An x-coordinate of 7 should snap.
1011 resizer->Drag(CalculateDragPoint(*resizer, 7 - 96, 0), 0);
1012 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1013 // Move to -15, should still snap to 0.
1014 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1015 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1016 // At -32 should move past snap points.
1017 resizer->Drag(CalculateDragPoint(*resizer, -32 - 96, 0), 0);
1018 EXPECT_EQ("-32,112 320x160", window_->bounds().ToString());
1019 resizer->Drag(CalculateDragPoint(*resizer, -33 - 96, 0), 0);
1020 EXPECT_EQ("-33,112 320x160", window_->bounds().ToString());
1022 // Right side should similarly snap.
1023 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
1024 EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
1025 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 7, 0), 0);
1026 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1027 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
1028 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1029 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 32, 0), 0);
1030 EXPECT_EQ("512,112 320x160", window_->bounds().ToString());
1031 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 33, 0), 0);
1032 EXPECT_EQ("513,112 320x160", window_->bounds().ToString());
1034 // And the bottom should snap too.
1035 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 - 7), 0);
1036 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1037 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
1038 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1039 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 32), 0);
1040 EXPECT_EQ("96,470 320x160", window_->bounds().ToString());
1041 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 33), 0);
1042 EXPECT_EQ("96,471 320x160", window_->bounds().ToString());
1044 // And the top should snap too.
1045 resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 20), 0);
1046 EXPECT_EQ("96,20 320x160", window_->bounds().ToString());
1047 resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 7), 0);
1048 EXPECT_EQ("96,0 320x160", window_->bounds().ToString());
1050 // And bottom/left should snap too.
1051 resizer->Drag(
1052 CalculateDragPoint(*resizer, 7 - 96, 600 - 160 - 112 - 3 - 7), 0);
1053 EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
1054 resizer->Drag(
1055 CalculateDragPoint(*resizer, -15 - 96, 600 - 160 - 112 - 3 + 15), 0);
1056 EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
1057 // should move past snap points.
1058 resizer->Drag(
1059 CalculateDragPoint(*resizer, -32 - 96, 600 - 160 - 112 - 2 + 32), 0);
1060 EXPECT_EQ("-32,470 320x160", window_->bounds().ToString());
1061 resizer->Drag(
1062 CalculateDragPoint(*resizer, -33 - 96, 600 - 160 - 112 - 2 + 33), 0);
1063 EXPECT_EQ("-33,471 320x160", window_->bounds().ToString());
1065 // No need to test dragging < 0 as we force that to 0.
1068 // Verifies a resize snap when dragging TOPLEFT.
1069 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPLEFT) {
1070 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1071 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1072 window_.get(), gfx::Point(), HTTOPLEFT));
1073 ASSERT_TRUE(resizer.get());
1074 resizer->Drag(CalculateDragPoint(*resizer, -98, -199), 0);
1075 EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
1078 // Verifies a resize snap when dragging TOPRIGHT.
1079 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPRIGHT) {
1080 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1081 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1082 window_.get()));
1083 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1084 window_.get(), gfx::Point(), HTTOPRIGHT));
1085 ASSERT_TRUE(resizer.get());
1086 resizer->Drag(
1087 CalculateDragPoint(*resizer, work_area.right() - 120 - 1, -199), 0);
1088 EXPECT_EQ(100, window_->bounds().x());
1089 EXPECT_EQ(work_area.y(), window_->bounds().y());
1090 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1091 EXPECT_EQ(230, window_->bounds().height());
1094 // Verifies a resize snap when dragging BOTTOMRIGHT.
1095 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMRIGHT) {
1096 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1097 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1098 window_.get()));
1099 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1100 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1101 ASSERT_TRUE(resizer.get());
1102 resizer->Drag(
1103 CalculateDragPoint(*resizer, work_area.right() - 120 - 1,
1104 work_area.bottom() - 220 - 2), 0);
1105 EXPECT_EQ(100, window_->bounds().x());
1106 EXPECT_EQ(200, window_->bounds().y());
1107 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1108 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1111 // Verifies a resize snap when dragging BOTTOMLEFT.
1112 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMLEFT) {
1113 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1114 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1115 window_.get()));
1116 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1117 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1118 ASSERT_TRUE(resizer.get());
1119 resizer->Drag(
1120 CalculateDragPoint(*resizer, -98, work_area.bottom() - 220 - 2), 0);
1121 EXPECT_EQ(0, window_->bounds().x());
1122 EXPECT_EQ(200, window_->bounds().y());
1123 EXPECT_EQ(120, window_->bounds().width());
1124 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1127 // Verifies window sticks to both window and work area.
1128 TEST_F(WorkspaceWindowResizerTest, StickToBothEdgeAndWindow) {
1129 window_->SetBounds(gfx::Rect(10, 10, 20, 50));
1130 window_->Show();
1131 window2_->SetBounds(gfx::Rect(150, 160, 25, 1000));
1132 window2_->Show();
1134 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1135 window_.get(), gfx::Point(10, 10), HTCAPTION));
1136 ASSERT_TRUE(resizer.get());
1138 // Move |window| one pixel to the left of |window2|. Should snap to right.
1139 resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
1140 gfx::Rect expected(130, 160, 20, 50);
1141 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1143 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1144 window_.get()));
1146 // The initial y position of |window_|.
1147 int initial_y = 10;
1148 // The drag position where the window is exactly attached to the bottom.
1149 int attach_y = work_area.bottom() - window_->bounds().height() - initial_y;
1151 // Dragging 10px above should not attach to the bottom.
1152 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y - 10), 0);
1153 expected.set_y(attach_y + initial_y - 10);
1154 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1156 // Stick to the work area.
1157 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y - 1), 0);
1158 expected.set_y(attach_y + initial_y);
1159 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1161 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y), 0);
1162 expected.set_y(attach_y + initial_y);
1163 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1165 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y + 1), 0);
1166 expected.set_y(attach_y + initial_y);
1167 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1169 // Moving down further should move the window.
1170 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y + 18), 0);
1171 expected.set_y(attach_y + initial_y + 18);
1172 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1175 TEST_F(WorkspaceWindowResizerTest, CtrlDragResizeToExactPosition) {
1176 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1177 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1178 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1179 ASSERT_TRUE(resizer.get());
1180 // Resize the right bottom to add 10 in width, 12 in height.
1181 resizer->Drag(CalculateDragPoint(*resizer, 10, 12), ui::EF_CONTROL_DOWN);
1182 // Both bottom and right sides to resize to exact size requested.
1183 EXPECT_EQ("96,112 330x172", window_->bounds().ToString());
1186 // Verifies that a dragged window will restore to its pre-maximized size.
1187 TEST_F(WorkspaceWindowResizerTest, RestoreToPreMaximizeCoordinates) {
1188 window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
1189 wm::WindowState* window_state = wm::GetWindowState(window_.get());
1190 window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1191 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1192 window_.get(), gfx::Point(), HTCAPTION));
1193 ASSERT_TRUE(resizer.get());
1194 // Drag the window to new position by adding (10, 10) to original point,
1195 // the window should get restored.
1196 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
1197 resizer->CompleteDrag();
1198 EXPECT_EQ("10,10 320x160", window_->bounds().ToString());
1199 // The restore rectangle should get cleared as well.
1200 EXPECT_FALSE(window_state->HasRestoreBounds());
1203 // Verifies that a dragged window will restore to its pre-maximized size.
1204 TEST_F(WorkspaceWindowResizerTest, RevertResizeOperation) {
1205 const gfx::Rect initial_bounds(0, 0, 200, 400);
1206 window_->SetBounds(initial_bounds);
1208 wm::WindowState* window_state = wm::GetWindowState(window_.get());
1209 window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1210 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1211 window_.get(), gfx::Point(), HTCAPTION));
1212 ASSERT_TRUE(resizer.get());
1213 // Drag the window to new poistion by adding (180, 16) to original point,
1214 // the window should get restored.
1215 resizer->Drag(CalculateDragPoint(*resizer, 180, 16), 0);
1216 resizer->RevertDrag();
1217 EXPECT_EQ(initial_bounds.ToString(), window_->bounds().ToString());
1218 EXPECT_EQ("96,112 320x160",
1219 window_state->GetRestoreBoundsInScreen().ToString());
1222 // Check that only usable sizes get returned by the resizer.
1223 TEST_F(WorkspaceWindowResizerTest, MagneticallyAttach) {
1224 window_->SetBounds(gfx::Rect(10, 10, 20, 30));
1225 window2_->SetBounds(gfx::Rect(150, 160, 25, 20));
1226 window2_->Show();
1228 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1229 window_.get(), gfx::Point(), HTCAPTION));
1230 ASSERT_TRUE(resizer.get());
1231 // Move |window| one pixel to the left of |window2|. Should snap to right and
1232 // top.
1233 resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
1234 EXPECT_EQ("130,160 20x30", window_->bounds().ToString());
1236 // Move |window| one pixel to the right of |window2|. Should snap to left and
1237 // top.
1238 resizer->Drag(CalculateDragPoint(*resizer, 164, 145), 0);
1239 EXPECT_EQ("175,160 20x30", window_->bounds().ToString());
1241 // Move |window| one pixel above |window2|. Should snap to top and left.
1242 resizer->Drag(CalculateDragPoint(*resizer, 142, 119), 0);
1243 EXPECT_EQ("150,130 20x30", window_->bounds().ToString());
1245 // Move |window| one pixel above the bottom of |window2|. Should snap to
1246 // bottom and left.
1247 resizer->Drag(CalculateDragPoint(*resizer, 142, 169), 0);
1248 EXPECT_EQ("150,180 20x30", window_->bounds().ToString());
1251 // The following variants verify magnetic snapping during resize when dragging a
1252 // particular edge.
1253 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOP) {
1254 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1255 window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
1256 window2_->Show();
1258 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1259 window_.get(), gfx::Point(), HTTOP));
1260 ASSERT_TRUE(resizer.get());
1261 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1262 EXPECT_EQ("100,199 20x31", window_->bounds().ToString());
1265 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPLEFT) {
1266 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1267 window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
1268 window2_->Show();
1271 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1272 window_.get(), gfx::Point(), HTTOPLEFT));
1273 ASSERT_TRUE(resizer.get());
1274 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1275 EXPECT_EQ("99,199 21x31", window_->bounds().ToString());
1276 resizer->RevertDrag();
1280 window2_->SetBounds(gfx::Rect(88, 201, 10, 20));
1281 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1282 window_.get(), gfx::Point(), HTTOPLEFT));
1283 ASSERT_TRUE(resizer.get());
1284 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1285 EXPECT_EQ("98,201 22x29", window_->bounds().ToString());
1286 resizer->RevertDrag();
1290 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPRIGHT) {
1291 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1292 window2_->Show();
1295 window2_->SetBounds(gfx::Rect(111, 179, 10, 20));
1296 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1297 window_.get(), gfx::Point(), HTTOPRIGHT));
1298 ASSERT_TRUE(resizer.get());
1299 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1300 EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
1301 resizer->RevertDrag();
1305 window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
1306 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1307 window_.get(), gfx::Point(), HTTOPRIGHT));
1308 ASSERT_TRUE(resizer.get());
1309 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1310 EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
1311 resizer->RevertDrag();
1315 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_RIGHT) {
1316 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1317 window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
1318 window2_->Show();
1320 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1321 window_.get(), gfx::Point(), HTRIGHT));
1322 ASSERT_TRUE(resizer.get());
1323 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1324 EXPECT_EQ("100,200 21x30", window_->bounds().ToString());
1327 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMRIGHT) {
1328 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1329 window2_->Show();
1332 window2_->SetBounds(gfx::Rect(122, 212, 10, 20));
1333 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1334 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1335 ASSERT_TRUE(resizer.get());
1336 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1337 EXPECT_EQ("100,200 22x32", window_->bounds().ToString());
1338 resizer->RevertDrag();
1342 window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1343 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1344 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1345 ASSERT_TRUE(resizer.get());
1346 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1347 EXPECT_EQ("100,200 21x33", window_->bounds().ToString());
1348 resizer->RevertDrag();
1352 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOM) {
1353 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1354 window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1355 window2_->Show();
1357 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1358 window_.get(), gfx::Point(), HTBOTTOM));
1359 ASSERT_TRUE(resizer.get());
1360 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1361 EXPECT_EQ("100,200 20x33", window_->bounds().ToString());
1364 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMLEFT) {
1365 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1366 window2_->Show();
1369 window2_->SetBounds(gfx::Rect(99, 231, 10, 20));
1370 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1371 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1372 ASSERT_TRUE(resizer.get());
1373 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1374 EXPECT_EQ("99,200 21x31", window_->bounds().ToString());
1375 resizer->RevertDrag();
1379 window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1380 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1381 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1382 ASSERT_TRUE(resizer.get());
1383 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1384 EXPECT_EQ("99,200 21x29", window_->bounds().ToString());
1385 resizer->RevertDrag();
1389 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_LEFT) {
1390 window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1391 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1392 window2_->Show();
1394 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1395 window_.get(), gfx::Point(), HTLEFT));
1396 ASSERT_TRUE(resizer.get());
1397 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1398 EXPECT_EQ("99,200 21x30", window_->bounds().ToString());
1401 // Test that the user user moved window flag is getting properly set.
1402 TEST_F(WorkspaceWindowResizerTest, CheckUserWindowManagedFlags) {
1403 window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
1405 std::vector<aura::Window*> no_attached_windows;
1406 // Check that an abort doesn't change anything.
1408 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1409 window_.get(), gfx::Point(), HTCAPTION));
1410 ASSERT_TRUE(resizer.get());
1411 // Move it 100 to the bottom.
1412 resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
1413 EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
1414 resizer->RevertDrag();
1416 EXPECT_FALSE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
1419 // Check that a completed move / size does change the user coordinates.
1421 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1422 window_.get(), gfx::Point(), HTCAPTION));
1423 ASSERT_TRUE(resizer.get());
1424 // Move it 100 to the bottom.
1425 resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
1426 EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
1427 resizer->CompleteDrag();
1428 EXPECT_TRUE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
1432 // Test that a window with a specified max size doesn't exceed it when dragged.
1433 TEST_F(WorkspaceWindowResizerTest, TestMaxSizeEnforced) {
1434 window_->SetBounds(gfx::Rect(0, 0, 400, 300));
1435 delegate_.set_max_size(gfx::Size(401, 301));
1437 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1438 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1439 resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
1440 EXPECT_EQ(401, window_->bounds().width());
1441 EXPECT_EQ(301, window_->bounds().height());
1444 // Test that a window with a specified max width doesn't restrict its height.
1445 TEST_F(WorkspaceWindowResizerTest, TestPartialMaxSizeEnforced) {
1446 window_->SetBounds(gfx::Rect(0, 0, 400, 300));
1447 delegate_.set_max_size(gfx::Size(401, 0));
1449 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1450 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1451 resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
1452 EXPECT_EQ(401, window_->bounds().width());
1453 EXPECT_EQ(302, window_->bounds().height());
1456 // Test that a window with a specified max size can't be snapped.
1457 TEST_F(WorkspaceWindowResizerTest, PhantomSnapMaxSize) {
1459 // With max size not set we get a phantom window controller for dragging off
1460 // the right hand side.
1461 // Make the window wider than maximum docked width.
1462 window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1464 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1465 window_.get(), gfx::Point(), HTCAPTION));
1466 EXPECT_FALSE(snap_phantom_window_controller());
1467 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1468 EXPECT_TRUE(snap_phantom_window_controller());
1469 resizer->RevertDrag();
1472 // With max size defined, we get no phantom window for snapping but we still
1473 // get a phantom window (docking guide).
1474 window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1475 delegate_.set_max_size(gfx::Size(400, 200));
1477 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1478 window_.get(), gfx::Point(), HTCAPTION));
1479 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1480 if (switches::UseDockedWindows())
1481 EXPECT_TRUE(snap_phantom_window_controller());
1482 else
1483 EXPECT_FALSE(snap_phantom_window_controller());
1484 resizer->RevertDrag();
1487 // With max size defined, we get no phantom window for snapping.
1488 window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1489 delegate_.set_max_size(gfx::Size(400, 200));
1490 // With min size defined, we get no phantom window for docking.
1491 delegate_.set_min_size(gfx::Size(400, 200));
1493 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1494 window_.get(), gfx::Point(), HTCAPTION));
1495 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1496 EXPECT_FALSE(snap_phantom_window_controller());
1497 resizer->RevertDrag();
1501 TEST_F(WorkspaceWindowResizerTest, DontRewardRightmostWindowForOverflows) {
1502 UpdateDisplay("600x800");
1503 aura::Window* root = Shell::GetPrimaryRootWindow();
1504 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1506 // Four 100x100 windows flush against eachother, starting at 100,100.
1507 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1508 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1509 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1510 window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
1511 delegate2_.set_max_size(gfx::Size(101, 0));
1513 std::vector<aura::Window*> windows;
1514 windows.push_back(window2_.get());
1515 windows.push_back(window3_.get());
1516 windows.push_back(window4_.get());
1517 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1518 window_.get(), gfx::Point(), HTRIGHT,
1519 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1520 ASSERT_TRUE(resizer.get());
1521 // Move it 51 to the left, which should contract w1 and expand w2-4.
1522 // w2 will hit its max size straight away, and in doing so will leave extra
1523 // pixels that a naive implementation may award to the rightmost window. A
1524 // fair implementation will give 25 pixels to each of the other windows.
1525 resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
1526 EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
1527 EXPECT_EQ("149,100 101x100", window2_->bounds().ToString());
1528 EXPECT_EQ("250,100 125x100", window3_->bounds().ToString());
1529 EXPECT_EQ("375,100 125x100", window4_->bounds().ToString());
1532 TEST_F(WorkspaceWindowResizerTest, DontExceedMaxWidth) {
1533 UpdateDisplay("600x800");
1534 aura::Window* root = Shell::GetPrimaryRootWindow();
1535 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1537 // Four 100x100 windows flush against eachother, starting at 100,100.
1538 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1539 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1540 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1541 window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
1542 delegate2_.set_max_size(gfx::Size(101, 0));
1543 delegate3_.set_max_size(gfx::Size(101, 0));
1545 std::vector<aura::Window*> windows;
1546 windows.push_back(window2_.get());
1547 windows.push_back(window3_.get());
1548 windows.push_back(window4_.get());
1549 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1550 window_.get(), gfx::Point(), HTRIGHT,
1551 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1552 ASSERT_TRUE(resizer.get());
1553 // Move it 52 to the left, which should contract w1 and expand w2-4.
1554 resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
1555 EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
1556 EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
1557 EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
1558 EXPECT_EQ("350,100 150x100", window4_->bounds().ToString());
1561 TEST_F(WorkspaceWindowResizerTest, DontExceedMaxHeight) {
1562 UpdateDisplay("600x800");
1563 aura::Window* root = Shell::GetPrimaryRootWindow();
1564 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1566 // Four 100x100 windows flush against eachother, starting at 100,100.
1567 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1568 window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
1569 window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
1570 window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
1571 delegate2_.set_max_size(gfx::Size(0, 101));
1572 delegate3_.set_max_size(gfx::Size(0, 101));
1574 std::vector<aura::Window*> windows;
1575 windows.push_back(window2_.get());
1576 windows.push_back(window3_.get());
1577 windows.push_back(window4_.get());
1578 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1579 window_.get(), gfx::Point(), HTBOTTOM,
1580 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1581 ASSERT_TRUE(resizer.get());
1582 // Move it 52 up, which should contract w1 and expand w2-4.
1583 resizer->Drag(CalculateDragPoint(*resizer, 0, -52), 0);
1584 EXPECT_EQ("100,100 100x48", window_->bounds().ToString());
1585 EXPECT_EQ("100,148 100x101", window2_->bounds().ToString());
1586 EXPECT_EQ("100,249 100x101", window3_->bounds().ToString());
1587 EXPECT_EQ("100,350 100x150", window4_->bounds().ToString());
1590 #if defined(OS_WIN)
1591 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1592 #define MAYBE_DontExceedMinHeight DISABLED_DontExceedMinHeight
1593 #else
1594 #define MAYBE_DontExceedMinHeight DontExceedMinHeight
1595 #endif
1597 TEST_F(WorkspaceWindowResizerTest, MAYBE_DontExceedMinHeight) {
1598 UpdateDisplay("600x500");
1599 aura::Window* root = Shell::GetPrimaryRootWindow();
1600 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1602 // Four 100x100 windows flush against eachother, starting at 100,100.
1603 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1604 window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
1605 window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
1606 window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
1607 delegate2_.set_min_size(gfx::Size(0, 99));
1608 delegate3_.set_min_size(gfx::Size(0, 99));
1610 std::vector<aura::Window*> windows;
1611 windows.push_back(window2_.get());
1612 windows.push_back(window3_.get());
1613 windows.push_back(window4_.get());
1614 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1615 window_.get(), gfx::Point(), HTBOTTOM,
1616 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1617 ASSERT_TRUE(resizer.get());
1618 // Move it 52 down, which should expand w1 and contract w2-4.
1619 resizer->Drag(CalculateDragPoint(*resizer, 0, 52), 0);
1620 EXPECT_EQ("100,100 100x152", window_->bounds().ToString());
1621 EXPECT_EQ("100,252 100x99", window2_->bounds().ToString());
1622 EXPECT_EQ("100,351 100x99", window3_->bounds().ToString());
1623 EXPECT_EQ("100,450 100x50", window4_->bounds().ToString());
1626 TEST_F(WorkspaceWindowResizerTest, DontExpandRightmostPastMaxWidth) {
1627 UpdateDisplay("600x800");
1628 aura::Window* root = Shell::GetPrimaryRootWindow();
1629 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1631 // Three 100x100 windows flush against eachother, starting at 100,100.
1632 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1633 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1634 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1635 delegate3_.set_max_size(gfx::Size(101, 0));
1637 std::vector<aura::Window*> windows;
1638 windows.push_back(window2_.get());
1639 windows.push_back(window3_.get());
1640 windows.push_back(window4_.get());
1641 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1642 window_.get(), gfx::Point(), HTRIGHT,
1643 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1644 ASSERT_TRUE(resizer.get());
1645 // Move it 51 to the left, which should contract w1 and expand w2-3.
1646 resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
1647 EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
1648 EXPECT_EQ("149,100 150x100", window2_->bounds().ToString());
1649 EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
1652 TEST_F(WorkspaceWindowResizerTest, MoveAttachedWhenGrownToMaxSize) {
1653 UpdateDisplay("600x800");
1654 aura::Window* root = Shell::GetPrimaryRootWindow();
1655 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1657 // Three 100x100 windows flush against eachother, starting at 100,100.
1658 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1659 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1660 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1661 delegate2_.set_max_size(gfx::Size(101, 0));
1662 delegate3_.set_max_size(gfx::Size(101, 0));
1664 std::vector<aura::Window*> windows;
1665 windows.push_back(window2_.get());
1666 windows.push_back(window3_.get());
1667 windows.push_back(window4_.get());
1668 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1669 window_.get(), gfx::Point(), HTRIGHT,
1670 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1671 ASSERT_TRUE(resizer.get());
1672 // Move it 52 to the left, which should contract w1 and expand and move w2-3.
1673 resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
1674 EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
1675 EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
1676 EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
1679 #if defined(OS_WIN)
1680 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1681 #define MAYBE_MainWindowHonoursMaxWidth DISABLED_MainWindowHonoursMaxWidth
1682 #else
1683 #define MAYBE_MainWindowHonoursMaxWidth MainWindowHonoursMaxWidth
1684 #endif
1686 TEST_F(WorkspaceWindowResizerTest, MAYBE_MainWindowHonoursMaxWidth) {
1687 UpdateDisplay("400x800");
1688 aura::Window* root = Shell::GetPrimaryRootWindow();
1689 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1691 // Three 100x100 windows flush against eachother, starting at 100,100.
1692 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1693 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1694 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1695 delegate_.set_max_size(gfx::Size(102, 0));
1697 std::vector<aura::Window*> windows;
1698 windows.push_back(window2_.get());
1699 windows.push_back(window3_.get());
1700 windows.push_back(window4_.get());
1701 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1702 window_.get(), gfx::Point(), HTRIGHT,
1703 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1704 ASSERT_TRUE(resizer.get());
1705 // Move it 50 to the right, which should expand w1 and contract w2-3, as they
1706 // won't fit in the root window in their original sizes.
1707 resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
1708 EXPECT_EQ("100,100 102x100", window_->bounds().ToString());
1709 EXPECT_EQ("202,100 99x100", window2_->bounds().ToString());
1710 EXPECT_EQ("301,100 99x100", window3_->bounds().ToString());
1713 TEST_F(WorkspaceWindowResizerTest, MainWindowHonoursMinWidth) {
1714 UpdateDisplay("400x800");
1715 aura::Window* root = Shell::GetPrimaryRootWindow();
1716 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1718 // Three 100x100 windows flush against eachother, starting at 100,100.
1719 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1720 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1721 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1722 delegate_.set_min_size(gfx::Size(98, 0));
1724 std::vector<aura::Window*> windows;
1725 windows.push_back(window2_.get());
1726 windows.push_back(window3_.get());
1727 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1728 window_.get(), gfx::Point(), HTRIGHT,
1729 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1730 ASSERT_TRUE(resizer.get());
1731 // Move it 50 to the left, which should contract w1 and expand w2-3.
1732 resizer->Drag(CalculateDragPoint(*resizer, -50, 0), 0);
1733 EXPECT_EQ("100,100 98x100", window_->bounds().ToString());
1734 EXPECT_EQ("198,100 101x100", window2_->bounds().ToString());
1735 EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
1738 // The following variants test that windows are resized correctly to the edges
1739 // of the screen using touch, when touch point is off of the window border.
1740 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_RIGHT) {
1741 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1743 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTRIGHT);
1744 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1745 touch_resize_window_->bounds().ToString());
1747 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1748 touch_resize_window_.get());
1750 // Drag out of the right border a bit and check if the border is aligned with
1751 // the touch point.
1752 generator.GestureScrollSequence(gfx::Point(715, kRootHeight / 2),
1753 gfx::Point(725, kRootHeight / 2),
1754 base::TimeDelta::FromMilliseconds(10),
1756 EXPECT_EQ(gfx::Rect(100, 100, 625, kRootHeight - 200).ToString(),
1757 touch_resize_window_->bounds().ToString());
1758 // Drag more, but stop before being snapped to the edge.
1759 generator.GestureScrollSequence(gfx::Point(725, kRootHeight / 2),
1760 gfx::Point(760, kRootHeight / 2),
1761 base::TimeDelta::FromMilliseconds(10),
1763 EXPECT_EQ(gfx::Rect(100, 100, 660, kRootHeight - 200).ToString(),
1764 touch_resize_window_->bounds().ToString());
1765 // Drag even more to snap to the edge.
1766 generator.GestureScrollSequence(gfx::Point(760, kRootHeight / 2),
1767 gfx::Point(775, kRootHeight / 2),
1768 base::TimeDelta::FromMilliseconds(10),
1770 EXPECT_EQ(gfx::Rect(100, 100, 700, kRootHeight - 200).ToString(),
1771 touch_resize_window_->bounds().ToString());
1774 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_LEFT) {
1775 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1777 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTLEFT);
1778 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1779 touch_resize_window_->bounds().ToString());
1781 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1782 touch_resize_window_.get());
1784 // Drag out of the left border a bit and check if the border is aligned with
1785 // the touch point.
1786 generator.GestureScrollSequence(gfx::Point(85, kRootHeight / 2),
1787 gfx::Point(75, kRootHeight / 2),
1788 base::TimeDelta::FromMilliseconds(10),
1790 EXPECT_EQ(gfx::Rect(75, 100, 625, kRootHeight - 200).ToString(),
1791 touch_resize_window_->bounds().ToString());
1792 // Drag more, but stop before being snapped to the edge.
1793 generator.GestureScrollSequence(gfx::Point(75, kRootHeight / 2),
1794 gfx::Point(40, kRootHeight / 2),
1795 base::TimeDelta::FromMilliseconds(10),
1797 EXPECT_EQ(gfx::Rect(40, 100, 660, kRootHeight - 200).ToString(),
1798 touch_resize_window_->bounds().ToString());
1799 // Drag even more to snap to the edge.
1800 generator.GestureScrollSequence(gfx::Point(40, kRootHeight / 2),
1801 gfx::Point(25, kRootHeight / 2),
1802 base::TimeDelta::FromMilliseconds(10),
1804 EXPECT_EQ(gfx::Rect(0, 100, 700, kRootHeight - 200).ToString(),
1805 touch_resize_window_->bounds().ToString());
1808 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_TOP) {
1809 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1811 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTTOP);
1812 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1813 touch_resize_window_->bounds().ToString());
1815 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1816 touch_resize_window_.get());
1818 // Drag out of the top border a bit and check if the border is aligned with
1819 // the touch point.
1820 generator.GestureScrollSequence(gfx::Point(400, 85),
1821 gfx::Point(400, 75),
1822 base::TimeDelta::FromMilliseconds(10),
1824 EXPECT_EQ(gfx::Rect(100, 75, 600, kRootHeight - 175).ToString(),
1825 touch_resize_window_->bounds().ToString());
1826 // Drag more, but stop before being snapped to the edge.
1827 generator.GestureScrollSequence(gfx::Point(400, 75),
1828 gfx::Point(400, 40),
1829 base::TimeDelta::FromMilliseconds(10),
1831 EXPECT_EQ(gfx::Rect(100, 40, 600, kRootHeight - 140).ToString(),
1832 touch_resize_window_->bounds().ToString());
1833 // Drag even more to snap to the edge.
1834 generator.GestureScrollSequence(gfx::Point(400, 40),
1835 gfx::Point(400, 25),
1836 base::TimeDelta::FromMilliseconds(10),
1838 EXPECT_EQ(gfx::Rect(100, 0, 600, kRootHeight - 100).ToString(),
1839 touch_resize_window_->bounds().ToString());
1842 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
1843 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1845 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTBOTTOM);
1846 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1847 touch_resize_window_->bounds().ToString());
1849 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1850 touch_resize_window_.get());
1852 // Drag out of the bottom border a bit and check if the border is aligned with
1853 // the touch point.
1854 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 85),
1855 gfx::Point(400, kRootHeight - 75),
1856 base::TimeDelta::FromMilliseconds(10),
1858 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 175).ToString(),
1859 touch_resize_window_->bounds().ToString());
1860 // Drag more, but stop before being snapped to the edge.
1861 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 75),
1862 gfx::Point(400, kRootHeight - 40),
1863 base::TimeDelta::FromMilliseconds(10),
1865 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 140).ToString(),
1866 touch_resize_window_->bounds().ToString());
1867 // Drag even more to snap to the edge.
1868 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 40),
1869 gfx::Point(400, kRootHeight - 25),
1870 base::TimeDelta::FromMilliseconds(10),
1872 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 100).ToString(),
1873 touch_resize_window_->bounds().ToString());
1876 } // namespace ash