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/workspace/phantom_window_controller.h"
19 #include "ash/wm/workspace/snap_sizer.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/root_window.h"
26 #include "ui/aura/test/event_generator.h"
27 #include "ui/aura/test/test_window_delegate.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"
38 const int kRootHeight = 600;
40 // A simple window delegate that returns the specified min size.
41 class TestWindowDelegate : public aura::test::TestWindowDelegate {
43 TestWindowDelegate() {
45 virtual ~TestWindowDelegate() {}
47 void set_min_size(const gfx::Size& size) {
51 void set_max_size(const gfx::Size& size) {
56 // Overridden from aura::Test::TestWindowDelegate:
57 virtual gfx::Size GetMinimumSize() const OVERRIDE {
61 virtual gfx::Size GetMaximumSize() const OVERRIDE {
68 DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
73 class WorkspaceWindowResizerTest : public test::AshTestBase {
75 WorkspaceWindowResizerTest() : workspace_resizer_(NULL) {}
76 virtual ~WorkspaceWindowResizerTest() {}
78 virtual void SetUp() OVERRIDE {
80 UpdateDisplay(base::StringPrintf("800x%d", kRootHeight));
81 // Ignore the touch slop region.
82 ui::GestureConfiguration::set_max_touch_move_in_pixels_for_click(0);
84 aura::Window* root = Shell::GetPrimaryRootWindow();
85 gfx::Rect root_bounds(root->bounds());
87 // RootWindow and Display can't resize on Windows Ash.
88 // http://crbug.com/165962
89 EXPECT_EQ(kRootHeight, root_bounds.height());
91 EXPECT_EQ(800, root_bounds.width());
92 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
93 window_.reset(new aura::Window(&delegate_));
94 window_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
95 window_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
96 ParentWindowInPrimaryRootWindow(window_.get());
99 window2_.reset(new aura::Window(&delegate2_));
100 window2_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
101 window2_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
102 ParentWindowInPrimaryRootWindow(window2_.get());
105 window3_.reset(new aura::Window(&delegate3_));
106 window3_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
107 window3_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
108 ParentWindowInPrimaryRootWindow(window3_.get());
111 window4_.reset(new aura::Window(&delegate4_));
112 window4_->SetType(ui::wm::WINDOW_TYPE_NORMAL);
113 window4_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
114 ParentWindowInPrimaryRootWindow(window4_.get());
118 virtual void TearDown() OVERRIDE {
123 touch_resize_window_.reset();
124 AshTestBase::TearDown();
127 // Returns a string identifying the z-order of each of the known child windows
128 // of |parent|. The returned string constains the id of the known windows and
129 // is ordered from topmost to bottomost windows.
130 std::string WindowOrderAsString(aura::Window* parent) const {
132 const aura::Window::Windows& windows = parent->children();
133 for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
134 i != windows.rend(); ++i) {
135 if (*i == window_ || *i == window2_ || *i == window3_) {
138 result += base::IntToString((*i)->id());
145 WindowResizer* CreateResizerForTest(
146 aura::Window* window,
147 const gfx::Point& point_in_parent,
148 int window_component) {
149 WindowResizer* resizer = CreateWindowResizer(
153 aura::client::WINDOW_MOVE_SOURCE_MOUSE).release();
154 workspace_resizer_ = WorkspaceWindowResizer::instance_;
157 WorkspaceWindowResizer* CreateWorkspaceResizerForTest(
158 aura::Window* window,
159 const gfx::Point& point_in_parent,
160 int window_component,
161 aura::client::WindowMoveSource source,
162 const std::vector<aura::Window*>& attached_windows) {
163 wm::WindowState* window_state = wm::GetWindowState(window);
164 window_state->CreateDragDetails(
165 window, point_in_parent, window_component, source);
166 return WorkspaceWindowResizer::Create(window_state, attached_windows);
169 PhantomWindowController* snap_phantom_window_controller() const {
170 return workspace_resizer_->snap_phantom_window_controller_.get();
173 gfx::Point CalculateDragPoint(const WindowResizer& resizer,
176 gfx::Point location = resizer.GetInitialLocation();
177 location.set_x(location.x() + delta_x);
178 location.set_y(location.y() + delta_y);
182 std::vector<aura::Window*> empty_windows() const {
183 return std::vector<aura::Window*>();
186 internal::ShelfLayoutManager* shelf_layout_manager() {
187 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
190 void InitTouchResizeWindow(const gfx::Rect& bounds, int window_component) {
191 touch_resize_delegate_.set_window_component(window_component);
192 touch_resize_window_.reset(
193 CreateTestWindowInShellWithDelegate(&touch_resize_delegate_, 0,
197 TestWindowDelegate delegate_;
198 TestWindowDelegate delegate2_;
199 TestWindowDelegate delegate3_;
200 TestWindowDelegate delegate4_;
201 scoped_ptr<aura::Window> window_;
202 scoped_ptr<aura::Window> window2_;
203 scoped_ptr<aura::Window> window3_;
204 scoped_ptr<aura::Window> window4_;
206 TestWindowDelegate touch_resize_delegate_;
207 scoped_ptr<aura::Window> touch_resize_window_;
208 WorkspaceWindowResizer* workspace_resizer_;
211 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
214 class WorkspaceWindowResizerTestSticky : public WorkspaceWindowResizerTest {
216 WorkspaceWindowResizerTestSticky() {}
217 virtual ~WorkspaceWindowResizerTestSticky() {}
219 virtual void SetUp() OVERRIDE {
220 CommandLine::ForCurrentProcess()->AppendSwitch(
221 ash::switches::kAshEnableStickyEdges);
222 WorkspaceWindowResizerTest::SetUp();
226 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTestSticky);
229 // Assertions around attached window resize dragging from the right with 2
231 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_2) {
232 window_->SetBounds(gfx::Rect(0, 300, 400, 300));
233 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
235 std::vector<aura::Window*> windows;
236 windows.push_back(window2_.get());
237 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
238 window_.get(), gfx::Point(), HTRIGHT,
239 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
240 ASSERT_TRUE(resizer.get());
241 // Move it 100 to the right, which should expand w1 and push w2.
242 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
243 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
244 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
246 // Push off the screen, w2 should be resized to its min.
247 delegate2_.set_min_size(gfx::Size(20, 20));
248 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
249 EXPECT_EQ("0,300 780x300", window_->bounds().ToString());
250 EXPECT_EQ("780,200 20x200", window2_->bounds().ToString());
252 // Move back to 100 and verify w2 gets its original size.
253 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
254 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
255 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
257 // Revert and make sure everything moves back.
258 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
259 resizer->RevertDrag();
260 EXPECT_EQ("0,300 400x300", window_->bounds().ToString());
261 EXPECT_EQ("400,200 100x200", window2_->bounds().ToString());
264 // Assertions around collapsing and expanding.
265 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_Compress) {
266 window_->SetBounds(gfx::Rect( 0, 300, 400, 300));
267 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
269 std::vector<aura::Window*> windows;
270 windows.push_back(window2_.get());
271 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
272 window_.get(), gfx::Point(), HTRIGHT,
273 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
274 ASSERT_TRUE(resizer.get());
275 // Move it 100 to the left, which should expand w2 and collapse w1.
276 resizer->Drag(CalculateDragPoint(*resizer, -100, 10), 0);
277 EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
278 EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
280 // Collapse all the way to w1's min.
281 delegate_.set_min_size(gfx::Size(20, 20));
282 resizer->Drag(CalculateDragPoint(*resizer, -800, 20), 0);
283 EXPECT_EQ("0,300 20x300", window_->bounds().ToString());
284 EXPECT_EQ("20,200 480x200", window2_->bounds().ToString());
286 // Move 100 to the left.
287 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
288 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
289 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
292 resizer->Drag(CalculateDragPoint(*resizer, -100, 20), 0);
293 EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
294 EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
297 // Assertions around attached window resize dragging from the right with 3
299 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3) {
300 window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
301 window2_->SetBounds(gfx::Rect(300, 300, 150, 200));
302 window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
303 delegate2_.set_min_size(gfx::Size(52, 50));
304 delegate3_.set_min_size(gfx::Size(38, 50));
306 std::vector<aura::Window*> windows;
307 windows.push_back(window2_.get());
308 windows.push_back(window3_.get());
309 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
310 window_.get(), gfx::Point(), HTRIGHT,
311 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
312 ASSERT_TRUE(resizer.get());
313 // Move it 100 to the right, which should expand w1 and push w2 and w3.
314 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
315 EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
316 EXPECT_EQ("400,300 150x200", window2_->bounds().ToString());
317 EXPECT_EQ("550,300 100x200", window3_->bounds().ToString());
319 // Move it 300, things should compress.
320 resizer->Drag(CalculateDragPoint(*resizer, 300, -10), 0);
321 EXPECT_EQ("100,300 500x300", window_->bounds().ToString());
322 EXPECT_EQ("600,300 120x200", window2_->bounds().ToString());
323 EXPECT_EQ("720,300 80x200", window3_->bounds().ToString());
325 // Move it so much the last two end up at their min.
326 resizer->Drag(CalculateDragPoint(*resizer, 800, 50), 0);
327 EXPECT_EQ("100,300 610x300", window_->bounds().ToString());
328 EXPECT_EQ("710,300 52x200", window2_->bounds().ToString());
329 EXPECT_EQ("762,300 38x200", window3_->bounds().ToString());
331 // Revert and make sure everything moves back.
332 resizer->RevertDrag();
333 EXPECT_EQ("100,300 200x300", window_->bounds().ToString());
334 EXPECT_EQ("300,300 150x200", window2_->bounds().ToString());
335 EXPECT_EQ("450,300 100x200", window3_->bounds().ToString());
338 // Assertions around attached window resizing (collapsing and expanding) with
340 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3_Compress) {
341 window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
342 window2_->SetBounds(gfx::Rect(300, 300, 200, 200));
343 window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
344 delegate2_.set_min_size(gfx::Size(52, 50));
345 delegate3_.set_min_size(gfx::Size(38, 50));
347 std::vector<aura::Window*> windows;
348 windows.push_back(window2_.get());
349 windows.push_back(window3_.get());
350 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
351 window_.get(), gfx::Point(), HTRIGHT,
352 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
353 ASSERT_TRUE(resizer.get());
354 // Move it -100 to the right, which should collapse w1 and expand w2 and w3.
355 resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
356 EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
357 EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
358 EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
360 // Move it 100 to the right.
361 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
362 EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
363 EXPECT_EQ("400,300 200x200", window2_->bounds().ToString());
364 EXPECT_EQ("600,300 100x200", window3_->bounds().ToString());
366 // 100 to the left again.
367 resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
368 EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
369 EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
370 EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
373 // Assertions around collapsing and expanding from the bottom.
374 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_Compress) {
375 window_->SetBounds(gfx::Rect( 0, 100, 400, 300));
376 window2_->SetBounds(gfx::Rect(400, 400, 100, 200));
378 std::vector<aura::Window*> windows;
379 windows.push_back(window2_.get());
380 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
381 window_.get(), gfx::Point(), HTBOTTOM,
382 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
383 ASSERT_TRUE(resizer.get());
384 // Move it up 100, which should expand w2 and collapse w1.
385 resizer->Drag(CalculateDragPoint(*resizer, 10, -100), 0);
386 EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
387 EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
389 // Collapse all the way to w1's min.
390 delegate_.set_min_size(gfx::Size(20, 20));
391 resizer->Drag(CalculateDragPoint(*resizer, 20, -800), 0);
392 EXPECT_EQ("0,100 400x20", window_->bounds().ToString());
393 EXPECT_EQ("400,120 100x480", window2_->bounds().ToString());
396 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
397 EXPECT_EQ("0,100 400x400", window_->bounds().ToString());
398 EXPECT_EQ("400,500 100x100", window2_->bounds().ToString());
401 resizer->Drag(CalculateDragPoint(*resizer, 20, -100), 0);
402 EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
403 EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
406 // Assertions around attached window resize dragging from the bottom with 2
408 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_2) {
409 window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
410 window2_->SetBounds(gfx::Rect(0, 250, 200, 100));
412 std::vector<aura::Window*> windows;
413 windows.push_back(window2_.get());
414 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
415 window_.get(), gfx::Point(), HTBOTTOM,
416 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
417 ASSERT_TRUE(resizer.get());
418 // Move it 100 to the bottom, which should expand w1 and push w2.
419 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
420 EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
421 EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
423 // Push off the screen, w2 should be resized to its min.
424 delegate2_.set_min_size(gfx::Size(20, 20));
425 resizer->Drag(CalculateDragPoint(*resizer, 50, 820), 0);
426 EXPECT_EQ("0,50 400x530", window_->bounds().ToString());
427 EXPECT_EQ("0,580 200x20", window2_->bounds().ToString());
429 // Move back to 100 and verify w2 gets its original size.
430 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
431 EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
432 EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
434 // Revert and make sure everything moves back.
435 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
436 resizer->RevertDrag();
437 EXPECT_EQ("0,50 400x200", window_->bounds().ToString());
438 EXPECT_EQ("0,250 200x100", window2_->bounds().ToString());
442 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
443 #define MAYBE_AttachedResize_BOTTOM_3 DISABLED_AttachedResize_BOTTOM_3
445 #define MAYBE_AttachedResize_BOTTOM_3 AttachedResize_BOTTOM_3
448 // Assertions around attached window resize dragging from the bottom with 3
450 TEST_F(WorkspaceWindowResizerTest, MAYBE_AttachedResize_BOTTOM_3) {
451 UpdateDisplay("600x800");
452 aura::Window* root = Shell::GetPrimaryRootWindow();
453 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
455 window_->SetBounds(gfx::Rect( 300, 100, 300, 200));
456 window2_->SetBounds(gfx::Rect(300, 300, 200, 150));
457 window3_->SetBounds(gfx::Rect(300, 450, 200, 100));
458 delegate2_.set_min_size(gfx::Size(50, 52));
459 delegate3_.set_min_size(gfx::Size(50, 38));
461 std::vector<aura::Window*> windows;
462 windows.push_back(window2_.get());
463 windows.push_back(window3_.get());
464 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
465 window_.get(), gfx::Point(), HTBOTTOM,
466 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
467 ASSERT_TRUE(resizer.get());
468 // Move it 100 down, which should expand w1 and push w2 and w3.
469 resizer->Drag(CalculateDragPoint(*resizer, -10, 100), 0);
470 EXPECT_EQ("300,100 300x300", window_->bounds().ToString());
471 EXPECT_EQ("300,400 200x150", window2_->bounds().ToString());
472 EXPECT_EQ("300,550 200x100", window3_->bounds().ToString());
474 // Move it 296 things should compress.
475 resizer->Drag(CalculateDragPoint(*resizer, -10, 296), 0);
476 EXPECT_EQ("300,100 300x496", window_->bounds().ToString());
477 EXPECT_EQ("300,596 200x123", window2_->bounds().ToString());
478 EXPECT_EQ("300,719 200x81", window3_->bounds().ToString());
480 // Move it so much everything ends up at its min.
481 resizer->Drag(CalculateDragPoint(*resizer, 50, 798), 0);
482 EXPECT_EQ("300,100 300x610", window_->bounds().ToString());
483 EXPECT_EQ("300,710 200x52", window2_->bounds().ToString());
484 EXPECT_EQ("300,762 200x38", window3_->bounds().ToString());
486 // Revert and make sure everything moves back.
487 resizer->RevertDrag();
488 EXPECT_EQ("300,100 300x200", window_->bounds().ToString());
489 EXPECT_EQ("300,300 200x150", window2_->bounds().ToString());
490 EXPECT_EQ("300,450 200x100", window3_->bounds().ToString());
493 // Assertions around attached window resizing (collapsing and expanding) with
495 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_3_Compress) {
496 window_->SetBounds(gfx::Rect( 0, 0, 200, 200));
497 window2_->SetBounds(gfx::Rect(10, 200, 200, 200));
498 window3_->SetBounds(gfx::Rect(20, 400, 100, 100));
499 delegate2_.set_min_size(gfx::Size(52, 50));
500 delegate3_.set_min_size(gfx::Size(38, 50));
502 std::vector<aura::Window*> windows;
503 windows.push_back(window2_.get());
504 windows.push_back(window3_.get());
505 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
506 window_.get(), gfx::Point(), HTBOTTOM,
507 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
508 ASSERT_TRUE(resizer.get());
509 // Move it 100 up, which should collapse w1 and expand w2 and w3.
510 resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
511 EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
512 EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
513 EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
516 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
517 EXPECT_EQ("0,0 200x300", window_->bounds().ToString());
518 EXPECT_EQ("10,300 200x200", window2_->bounds().ToString());
519 EXPECT_EQ("20,500 100x100", window3_->bounds().ToString());
522 resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
523 EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
524 EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
525 EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
528 // Tests that touch-dragging a window does not lock the mouse cursor
529 // and therefore shows the cursor on a mousemove.
530 TEST_F(WorkspaceWindowResizerTest, MouseMoveWithTouchDrag) {
531 window_->SetBounds(gfx::Rect(0, 300, 400, 300));
532 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
534 Shell* shell = Shell::GetInstance();
535 aura::test::EventGenerator generator(window_->GetRootWindow());
537 // The cursor should not be locked initially.
538 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
540 std::vector<aura::Window*> windows;
541 windows.push_back(window2_.get());
542 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
543 window_.get(), gfx::Point(), HTRIGHT,
544 aura::client::WINDOW_MOVE_SOURCE_TOUCH, windows));
545 ASSERT_TRUE(resizer.get());
547 // Creating a WorkspaceWindowResizer should not lock the cursor.
548 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
550 // The cursor should be hidden after touching the screen and
552 EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
553 generator.PressTouch();
554 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
555 EXPECT_FALSE(shell->cursor_manager()->IsCursorVisible());
556 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
558 // Moving the mouse should show the cursor.
559 generator.MoveMouseBy(1, 1);
560 EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
561 EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
563 resizer->RevertDrag();
566 // Assertions around dragging to the left/right edge of the screen.
567 TEST_F(WorkspaceWindowResizerTest, Edge) {
568 if (!SupportsHostWindowResize())
571 // Resize host window to force insets update.
572 UpdateDisplay("800x700");
573 // TODO(varkha): Insets are reset after every drag because of
574 // http://crbug.com/292238.
575 // Window is wide enough not to get docked right away.
576 window_->SetBounds(gfx::Rect(20, 30, 400, 60));
577 wm::WindowState* window_state = wm::GetWindowState(window_.get());
580 internal::SnapSizer snap_sizer(window_state, gfx::Point(),
581 internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT);
582 gfx::Rect expected_bounds(snap_sizer.target_bounds());
584 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
585 window_.get(), gfx::Point(), HTCAPTION));
586 ASSERT_TRUE(resizer.get());
587 resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
588 resizer->CompleteDrag();
590 EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
591 ASSERT_TRUE(window_state->HasRestoreBounds());
592 EXPECT_EQ("20,30 400x60",
593 window_state->GetRestoreBoundsInScreen().ToString());
595 // Try the same with the right side.
597 internal::SnapSizer snap_sizer(window_state, gfx::Point(),
598 internal::SnapSizer::RIGHT_EDGE, internal::SnapSizer::OTHER_INPUT);
599 gfx::Rect expected_bounds(snap_sizer.target_bounds());
601 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
602 window_.get(), gfx::Point(), HTCAPTION));
603 ASSERT_TRUE(resizer.get());
604 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
605 resizer->CompleteDrag();
606 EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
607 ASSERT_TRUE(window_state->HasRestoreBounds());
608 EXPECT_EQ("20,30 400x60",
609 window_state->GetRestoreBoundsInScreen().ToString());
612 // Test if the restore bounds is correct in multiple displays.
613 if (!SupportsMultipleDisplays())
616 // Restore the window to clear snapped state.
617 window_state->Restore();
619 UpdateDisplay("800x600,500x600");
620 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
621 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
622 // Window is wide enough not to get docked right away.
623 window_->SetBoundsInScreen(gfx::Rect(800, 10, 400, 60),
624 ScreenUtil::GetSecondaryDisplay());
625 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
627 EXPECT_EQ("800,10 400x60", window_->GetBoundsInScreen().ToString());
629 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
630 window_.get(), gfx::Point(), HTCAPTION));
631 ASSERT_TRUE(resizer.get());
632 resizer->Drag(CalculateDragPoint(*resizer, 499, 0), 0);
634 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
635 resizer->CompleteDrag();
636 // With the resolution of 500x600 we will hit in this case the 50% screen
638 // TODO(varkha): Insets are updated because of http://crbug.com/292238
639 EXPECT_EQ("250,0 250x" + base::IntToString(bottom),
640 window_->bounds().ToString());
641 EXPECT_EQ("800,10 400x60",
642 window_state->GetRestoreBoundsInScreen().ToString());
646 // Check that non resizable windows will not get resized.
647 TEST_F(WorkspaceWindowResizerTest, NonResizableWindows) {
648 window_->SetBounds(gfx::Rect(20, 30, 50, 60));
649 window_->SetProperty(aura::client::kCanResizeKey, false);
651 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
652 window_.get(), gfx::Point(), HTCAPTION));
653 ASSERT_TRUE(resizer.get());
654 resizer->Drag(CalculateDragPoint(*resizer, -20, 0), 0);
655 resizer->CompleteDrag();
656 EXPECT_EQ("0,30 50x60", window_->bounds().ToString());
659 TEST_F(WorkspaceWindowResizerTest, CancelSnapPhantom) {
660 if (!SupportsMultipleDisplays())
663 UpdateDisplay("800x600,800x600");
664 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
665 ASSERT_EQ(2U, root_windows.size());
667 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
668 Shell::GetScreen()->GetPrimaryDisplay());
669 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
670 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
672 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
673 window_.get(), gfx::Point(), HTCAPTION));
674 ASSERT_TRUE(resizer.get());
675 EXPECT_FALSE(snap_phantom_window_controller());
677 // The pointer is on the edge but not shared. The snap phantom window
678 // controller should be non-NULL.
679 resizer->Drag(CalculateDragPoint(*resizer, 799, 0), 0);
680 EXPECT_TRUE(snap_phantom_window_controller());
682 // Move the cursor across the edge. Now the snap phantom window controller
683 // should be canceled.
684 resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0);
685 EXPECT_FALSE(snap_phantom_window_controller());
689 // Verifies that dragging a snapped window unsnaps it.
690 TEST_F(WorkspaceWindowResizerTest, DragSnapped) {
691 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window_.get());
693 const gfx::Rect kInitialBounds(100, 100, 100, 100);
694 window_->SetBounds(kInitialBounds);
697 internal::SnapSizer::SnapWindow(window_state, internal::SnapSizer::LEFT_EDGE);
698 EXPECT_EQ(wm::SHOW_TYPE_LEFT_SNAPPED, window_state->window_show_type());
699 gfx::Rect snapped_bounds = window_->bounds();
700 EXPECT_NE(snapped_bounds.ToString(), kInitialBounds.ToString());
701 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
702 kInitialBounds.ToString());
704 // Dragging a side snapped window should unsnap it.
705 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
706 window_.get(), gfx::Point(), HTCAPTION));
707 resizer->Drag(CalculateDragPoint(*resizer, 10, 0), 0);
708 resizer->CompleteDrag();
709 EXPECT_EQ(wm::SHOW_TYPE_NORMAL, window_state->window_show_type());
710 EXPECT_EQ("10,0 100x100", window_->bounds().ToString());
711 EXPECT_FALSE(window_state->HasRestoreBounds());
714 // Verifies the behavior of resizing a side snapped window.
715 TEST_F(WorkspaceWindowResizerTest, ResizeSnapped) {
716 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window_.get());
718 const gfx::Rect kInitialBounds(100, 100, 100, 100);
719 window_->SetBounds(kInitialBounds);
722 internal::SnapSizer::SnapWindow(window_state, internal::SnapSizer::LEFT_EDGE);
723 EXPECT_EQ(wm::SHOW_TYPE_LEFT_SNAPPED, window_state->window_show_type());
724 gfx::Rect snapped_bounds = window_->bounds();
725 EXPECT_NE(snapped_bounds.ToString(), kInitialBounds.ToString());
726 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
727 kInitialBounds.ToString());
730 // 1) Resizing a side snapped window to make it wider should not unsnap the
732 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
733 window_.get(), gfx::Point(), HTRIGHT));
734 resizer->Drag(CalculateDragPoint(*resizer, 10, 0), 0);
735 resizer->CompleteDrag();
736 EXPECT_EQ(wm::SHOW_TYPE_LEFT_SNAPPED, window_state->window_show_type());
737 snapped_bounds.Inset(0, 0, -10, 0);
738 EXPECT_EQ(snapped_bounds.ToString(), window_->bounds().ToString());
739 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
740 kInitialBounds.ToString());
744 // 2) Resizing a side snapped window vertically and then undoing the change
745 // should not unsnap.
746 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
747 window_.get(), gfx::Point(), HTBOTTOM));
748 resizer->Drag(CalculateDragPoint(*resizer, 0, -30), 0);
749 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
750 resizer->CompleteDrag();
751 EXPECT_EQ(wm::SHOW_TYPE_LEFT_SNAPPED, window_state->window_show_type());
752 EXPECT_EQ(snapped_bounds.ToString(), window_->bounds().ToString());
753 EXPECT_EQ(window_state->GetRestoreBoundsInParent().ToString(),
754 kInitialBounds.ToString());
758 // 3) Resizing a side snapped window vertically and then not undoing the
759 // change should unsnap.
760 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
761 window_.get(), gfx::Point(), HTBOTTOM));
762 resizer->Drag(CalculateDragPoint(*resizer, 0, -10), 0);
763 resizer->CompleteDrag();
764 EXPECT_EQ(wm::SHOW_TYPE_NORMAL, window_state->window_show_type());
765 gfx::Rect expected_bounds(snapped_bounds);
766 expected_bounds.Inset(0, 0, 0, 10);
767 EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
768 EXPECT_FALSE(window_state->HasRestoreBounds());
772 // Verifies windows are correctly restacked when reordering multiple windows.
773 TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
774 window_->SetBounds(gfx::Rect( 0, 0, 200, 300));
775 window2_->SetBounds(gfx::Rect(200, 0, 100, 200));
776 window3_->SetBounds(gfx::Rect(300, 0, 100, 100));
779 std::vector<aura::Window*> windows;
780 windows.push_back(window2_.get());
781 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
782 window_.get(), gfx::Point(), HTRIGHT,
783 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
784 ASSERT_TRUE(resizer.get());
785 // Move it 100 to the right, which should expand w1 and push w2 and w3.
786 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
788 // 2 should be topmost since it's initially the highest in the stack.
789 EXPECT_EQ("2 1 3", WindowOrderAsString(window_->parent()));
793 std::vector<aura::Window*> windows;
794 windows.push_back(window3_.get());
795 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
796 window2_.get(), gfx::Point(), HTRIGHT,
797 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
798 ASSERT_TRUE(resizer.get());
799 // Move it 100 to the right, which should expand w1 and push w2 and w3.
800 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
802 // 2 should be topmost since it's initially the highest in the stack.
803 EXPECT_EQ("2 3 1", WindowOrderAsString(window_->parent()));
807 // Makes sure we don't allow dragging below the work area.
808 TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) {
809 Shell::GetInstance()->SetDisplayWorkAreaInsets(
810 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
812 ASSERT_EQ(1, Shell::GetScreen()->GetNumDisplays());
814 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
815 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
816 window_.get(), gfx::Point(), HTCAPTION));
817 ASSERT_TRUE(resizer.get());
818 resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
820 kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
821 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
822 window_->bounds().ToString());
825 // Makes sure we don't allow dragging on the work area with multidisplay.
826 TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
827 if (!SupportsMultipleDisplays())
830 UpdateDisplay("800x600,800x600");
831 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
833 Shell::GetInstance()->SetDisplayWorkAreaInsets(
834 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
836 // Positions the secondary display at the bottom the primary display.
837 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
838 ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 0));
841 window_->SetBounds(gfx::Rect(100, 200, 300, 20));
842 DCHECK_LT(window_->bounds().height(),
843 WorkspaceWindowResizer::kMinOnscreenHeight);
844 // Drag down avoiding dragging along the edge as that would side-snap.
845 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
846 window_.get(), gfx::Point(10, 0), HTCAPTION));
847 ASSERT_TRUE(resizer.get());
848 resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
849 int expected_y = kRootHeight - window_->bounds().height() - 10;
850 // When the mouse cursor is in the primary display, the window cannot move
851 // on non-work area but can get all the way towards the bottom,
852 // restricted only by the window height.
853 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x20",
854 window_->bounds().ToString());
855 // Revert the drag in order to not remember the restore bounds.
856 resizer->RevertDrag();
859 Shell::GetInstance()->SetDisplayWorkAreaInsets(
860 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
862 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
863 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
864 window_.get(), gfx::Point(10, 0), HTCAPTION));
865 ASSERT_TRUE(resizer.get());
866 // Drag down avoiding dragging along the edge as that would side-snap.
867 resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
869 kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
870 // When the mouse cursor is in the primary display, the window cannot move
871 // on non-work area with kMinOnscreenHeight margin.
872 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
873 window_->bounds().ToString());
874 resizer->CompleteDrag();
878 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
879 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
880 window_.get(), window_->bounds().origin(), HTCAPTION));
881 ASSERT_TRUE(resizer.get());
882 // Drag down avoiding getting stuck against the shelf on the bottom screen.
883 resizer->Drag(CalculateDragPoint(*resizer, 0, 500), 0);
884 // The window can move to the secondary display beyond non-work area of
885 // the primary display.
886 EXPECT_EQ("100,700 300x400", window_->bounds().ToString());
887 resizer->CompleteDrag();
891 // Makes sure we don't allow dragging off the top of the work area.
892 TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) {
893 Shell::GetInstance()->SetDisplayWorkAreaInsets(
894 Shell::GetPrimaryRootWindow(), gfx::Insets(10, 0, 0, 0));
896 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
897 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
898 window_.get(), gfx::Point(), HTCAPTION));
899 ASSERT_TRUE(resizer.get());
900 resizer->Drag(CalculateDragPoint(*resizer, 0, -600), 0);
901 EXPECT_EQ("100,10 300x400", window_->bounds().ToString());
904 TEST_F(WorkspaceWindowResizerTest, ResizeBottomOutsideWorkArea) {
905 Shell::GetInstance()->SetDisplayWorkAreaInsets(
906 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
908 window_->SetBounds(gfx::Rect(100, 200, 300, 380));
909 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
910 window_.get(), gfx::Point(), HTTOP));
911 ASSERT_TRUE(resizer.get());
912 resizer->Drag(CalculateDragPoint(*resizer, 8, 0), 0);
913 EXPECT_EQ("100,200 300x380", window_->bounds().ToString());
916 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideLeftWorkArea) {
917 Shell::GetInstance()->SetDisplayWorkAreaInsets(
918 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
919 int left = ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_.get()).x();
920 int pixels_to_left_border = 50;
921 int window_width = 300;
922 int window_x = left - window_width + pixels_to_left_border;
923 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
924 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
925 window_.get(), gfx::Point(pixels_to_left_border, 0), HTRIGHT));
926 ASSERT_TRUE(resizer.get());
927 resizer->Drag(CalculateDragPoint(*resizer, -window_width, 0), 0);
928 EXPECT_EQ(base::IntToString(window_x) + ",100 " +
929 base::IntToString(kMinimumOnScreenArea - window_x) +
930 "x380", window_->bounds().ToString());
933 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
934 Shell::GetInstance()->SetDisplayWorkAreaInsets(
935 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
936 int right = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
937 window_.get()).right();
938 int pixels_to_right_border = 50;
939 int window_width = 300;
940 int window_x = right - pixels_to_right_border;
941 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
942 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
943 window_.get(), gfx::Point(window_x, 0), HTLEFT));
944 ASSERT_TRUE(resizer.get());
945 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
946 EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
948 base::IntToString(window_width - pixels_to_right_border +
949 kMinimumOnScreenArea) +
950 "x380", window_->bounds().ToString());
953 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
954 Shell::GetInstance()->SetDisplayWorkAreaInsets(
955 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
956 int bottom = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
957 window_.get()).bottom();
958 int delta_to_bottom = 50;
960 window_->SetBounds(gfx::Rect(100, bottom - delta_to_bottom, 300, height));
961 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
962 window_.get(), gfx::Point(0, bottom - delta_to_bottom), HTTOP));
963 ASSERT_TRUE(resizer.get());
964 resizer->Drag(CalculateDragPoint(*resizer, 0, bottom), 0);
966 base::IntToString(bottom - kMinimumOnScreenArea) +
968 base::IntToString(height - (delta_to_bottom -
969 kMinimumOnScreenArea)),
970 window_->bounds().ToString());
973 // Verifies that 'outside' check of the resizer take into account the extended
974 // desktop in case of repositions.
975 TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
976 // Only primary display. Changes the window position to fit within the
978 Shell::GetInstance()->SetDisplayWorkAreaInsets(
979 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
980 int right = ScreenUtil::GetDisplayWorkAreaBoundsInParent(
981 window_.get()).right();
982 int pixels_to_right_border = 50;
983 int window_width = 300;
984 int window_x = right - pixels_to_right_border;
985 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
986 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
987 window_.get(), gfx::Point(window_x, 0), HTCAPTION));
988 ASSERT_TRUE(resizer.get());
989 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
990 EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
992 base::IntToString(window_width) +
993 "x380", window_->bounds().ToString());
995 if (!SupportsMultipleDisplays())
998 // With secondary display. Operation itself is same but doesn't change
999 // the position because the window is still within the secondary display.
1000 UpdateDisplay("1000x600,600x400");
1001 Shell::GetInstance()->SetDisplayWorkAreaInsets(
1002 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
1003 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
1004 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
1005 EXPECT_EQ(base::IntToString(window_x + window_width) +
1007 base::IntToString(window_width) +
1008 "x380", window_->bounds().ToString());
1011 // Verifies snapping to edges works.
1012 TEST_F(WorkspaceWindowResizerTest, SnapToEdge) {
1013 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
1014 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1015 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1016 // Click 50px to the right so that the mouse pointer does not leave the
1017 // workspace ensuring sticky behavior.
1018 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1020 window_->bounds().origin() + gfx::Vector2d(50, 0),
1022 ASSERT_TRUE(resizer.get());
1023 // Move to an x-coordinate of 15, which should not snap.
1024 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1025 // An x-coordinate of 7 should snap.
1026 resizer->Drag(CalculateDragPoint(*resizer, 7 - 96, 0), 0);
1027 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1028 // Move to -15, should still snap to 0.
1029 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1030 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1031 // At -32 should move past snap points.
1032 resizer->Drag(CalculateDragPoint(*resizer, -32 - 96, 0), 0);
1033 EXPECT_EQ("-32,112 320x160", window_->bounds().ToString());
1034 resizer->Drag(CalculateDragPoint(*resizer, -33 - 96, 0), 0);
1035 EXPECT_EQ("-33,112 320x160", window_->bounds().ToString());
1037 // Right side should similarly snap.
1038 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
1039 EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
1040 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 7, 0), 0);
1041 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1042 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
1043 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1044 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 32, 0), 0);
1045 EXPECT_EQ("512,112 320x160", window_->bounds().ToString());
1046 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 33, 0), 0);
1047 EXPECT_EQ("513,112 320x160", window_->bounds().ToString());
1049 // And the bottom should snap too.
1050 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 - 7), 0);
1051 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1052 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
1053 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1054 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 32), 0);
1055 EXPECT_EQ("96,470 320x160", window_->bounds().ToString());
1056 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 33), 0);
1057 EXPECT_EQ("96,471 320x160", window_->bounds().ToString());
1059 // And the top should snap too.
1060 resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 20), 0);
1061 EXPECT_EQ("96,20 320x160", window_->bounds().ToString());
1062 resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 7), 0);
1063 EXPECT_EQ("96,0 320x160", window_->bounds().ToString());
1065 // And bottom/left should snap too.
1067 CalculateDragPoint(*resizer, 7 - 96, 600 - 160 - 112 - 3 - 7), 0);
1068 EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
1070 CalculateDragPoint(*resizer, -15 - 96, 600 - 160 - 112 - 3 + 15), 0);
1071 EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
1072 // should move past snap points.
1074 CalculateDragPoint(*resizer, -32 - 96, 600 - 160 - 112 - 2 + 32), 0);
1075 EXPECT_EQ("-32,470 320x160", window_->bounds().ToString());
1077 CalculateDragPoint(*resizer, -33 - 96, 600 - 160 - 112 - 2 + 33), 0);
1078 EXPECT_EQ("-33,471 320x160", window_->bounds().ToString());
1080 // No need to test dragging < 0 as we force that to 0.
1083 // Verifies a resize snap when dragging TOPLEFT.
1084 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPLEFT) {
1085 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1086 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1087 window_.get(), gfx::Point(), HTTOPLEFT));
1088 ASSERT_TRUE(resizer.get());
1089 resizer->Drag(CalculateDragPoint(*resizer, -98, -199), 0);
1090 EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
1093 // Verifies a resize snap when dragging TOPRIGHT.
1094 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPRIGHT) {
1095 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1096 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1098 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1099 window_.get(), gfx::Point(), HTTOPRIGHT));
1100 ASSERT_TRUE(resizer.get());
1102 CalculateDragPoint(*resizer, work_area.right() - 120 - 1, -199), 0);
1103 EXPECT_EQ(100, window_->bounds().x());
1104 EXPECT_EQ(work_area.y(), window_->bounds().y());
1105 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1106 EXPECT_EQ(230, window_->bounds().height());
1109 // Verifies a resize snap when dragging BOTTOMRIGHT.
1110 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMRIGHT) {
1111 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1112 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1114 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1115 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1116 ASSERT_TRUE(resizer.get());
1118 CalculateDragPoint(*resizer, work_area.right() - 120 - 1,
1119 work_area.bottom() - 220 - 2), 0);
1120 EXPECT_EQ(100, window_->bounds().x());
1121 EXPECT_EQ(200, window_->bounds().y());
1122 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1123 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1126 // Verifies a resize snap when dragging BOTTOMLEFT.
1127 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMLEFT) {
1128 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1129 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1131 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1132 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1133 ASSERT_TRUE(resizer.get());
1135 CalculateDragPoint(*resizer, -98, work_area.bottom() - 220 - 2), 0);
1136 EXPECT_EQ(0, window_->bounds().x());
1137 EXPECT_EQ(200, window_->bounds().y());
1138 EXPECT_EQ(120, window_->bounds().width());
1139 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1142 // Verifies sticking to edges works.
1143 TEST_F(WorkspaceWindowResizerTestSticky, StickToEdge) {
1144 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
1145 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1146 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1147 // Click 50px to the right so that the mouse pointer does not leave the
1148 // workspace ensuring sticky behavior.
1149 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1151 window_->bounds().origin() + gfx::Vector2d(50, 0),
1153 ASSERT_TRUE(resizer.get());
1154 // Move to an x-coordinate of 15, which should not stick.
1155 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1156 // Move to -15, should still stick to 0.
1157 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1158 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1159 // At -100 should move past edge.
1160 resizer->Drag(CalculateDragPoint(*resizer, -100 - 96, 0), 0);
1161 EXPECT_EQ("-100,112 320x160", window_->bounds().ToString());
1162 resizer->Drag(CalculateDragPoint(*resizer, -101 - 96, 0), 0);
1163 EXPECT_EQ("-101,112 320x160", window_->bounds().ToString());
1165 // Right side should similarly stick.
1166 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
1167 EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
1168 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
1169 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1170 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 100, 0), 0);
1171 EXPECT_EQ("580,112 320x160", window_->bounds().ToString());
1172 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 101, 0), 0);
1173 EXPECT_EQ("581,112 320x160", window_->bounds().ToString());
1175 // And the bottom should stick too.
1176 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
1177 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1178 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 100), 0);
1179 EXPECT_EQ("96,538 320x160", window_->bounds().ToString());
1180 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 101), 0);
1181 EXPECT_EQ("96,539 320x160", window_->bounds().ToString());
1183 // No need to test dragging < 0 as we force that to 0.
1186 // Verifies not sticking to edges when a mouse pointer is outside of work area.
1187 TEST_F(WorkspaceWindowResizerTestSticky, NoStickToEdgeWhenOutside) {
1188 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
1189 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1190 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1191 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1192 window_.get(), gfx::Point(), HTCAPTION));
1193 ASSERT_TRUE(resizer.get());
1194 // Move to an x-coordinate of 15, which should not stick.
1195 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1196 // Move to -15, should still stick to 0.
1197 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1198 EXPECT_EQ("-15,112 320x160", window_->bounds().ToString());
1201 // Verifies window sticks to both window and work area.
1202 TEST_F(WorkspaceWindowResizerTest, StickToBothEdgeAndWindow) {
1203 window_->SetBounds(gfx::Rect(10, 10, 20, 50));
1205 window2_->SetBounds(gfx::Rect(150, 160, 25, 1000));
1208 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1209 window_.get(), gfx::Point(10, 10), HTCAPTION));
1210 ASSERT_TRUE(resizer.get());
1212 // Move |window| one pixel to the left of |window2|. Should snap to right.
1213 resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
1214 gfx::Rect expected(130, 160, 20, 50);
1215 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1217 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1220 // The initial y position of |window_|.
1222 // The drag position where the window is exactly attached to the bottom.
1223 int attach_y = work_area.bottom() - window_->bounds().height() - initial_y;
1225 // Dragging 10px above should not attach to the bottom.
1226 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y - 10), 0);
1227 expected.set_y(attach_y + initial_y - 10);
1228 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1230 // Stick to the work area.
1231 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y - 1), 0);
1232 expected.set_y(attach_y + initial_y);
1233 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1235 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y), 0);
1236 expected.set_y(attach_y + initial_y);
1237 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1239 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y + 1), 0);
1240 expected.set_y(attach_y + initial_y);
1241 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1243 // Moving down further should move the window.
1244 resizer->Drag(CalculateDragPoint(*resizer, 119, attach_y + 18), 0);
1245 expected.set_y(attach_y + initial_y + 18);
1246 EXPECT_EQ(expected.ToString(), window_->bounds().ToString());
1249 // Verifies a resize sticks when dragging TOPLEFT.
1250 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPLEFT) {
1251 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1252 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1253 window_.get(), gfx::Point(), HTTOPLEFT));
1254 ASSERT_TRUE(resizer.get());
1255 resizer->Drag(CalculateDragPoint(*resizer, -15 - 100, -15 -200), 0);
1256 EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
1259 // Verifies a resize sticks when dragging TOPRIGHT.
1260 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPRIGHT) {
1261 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1262 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1264 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1265 window_.get(), gfx::Point(), HTTOPRIGHT));
1266 ASSERT_TRUE(resizer.get());
1267 resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 + 20,
1269 EXPECT_EQ(100, window_->bounds().x());
1270 EXPECT_EQ(work_area.y(), window_->bounds().y());
1271 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1272 EXPECT_EQ(230, window_->bounds().height());
1275 // Verifies a resize snap when dragging BOTTOMRIGHT.
1276 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMRIGHT) {
1277 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1278 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1280 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1281 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1282 ASSERT_TRUE(resizer.get());
1283 resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 - 20 + 15,
1284 work_area.bottom() - 200 - 30 + 15), 0);
1285 EXPECT_EQ(100, window_->bounds().x());
1286 EXPECT_EQ(200, window_->bounds().y());
1287 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1288 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1291 // Verifies a resize snap when dragging BOTTOMLEFT.
1292 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMLEFT) {
1293 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1294 gfx::Rect work_area(ScreenUtil::GetDisplayWorkAreaBoundsInParent(
1296 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1297 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1298 ASSERT_TRUE(resizer.get());
1299 resizer->Drag(CalculateDragPoint(*resizer, -15 - 100,
1300 work_area.bottom() - 200 - 30 + 15), 0);
1301 EXPECT_EQ(0, window_->bounds().x());
1302 EXPECT_EQ(200, window_->bounds().y());
1303 EXPECT_EQ(120, window_->bounds().width());
1304 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1307 TEST_F(WorkspaceWindowResizerTest, CtrlDragResizeToExactPosition) {
1308 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1309 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1310 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1311 ASSERT_TRUE(resizer.get());
1312 // Resize the right bottom to add 10 in width, 12 in height.
1313 resizer->Drag(CalculateDragPoint(*resizer, 10, 12), ui::EF_CONTROL_DOWN);
1314 // Both bottom and right sides to resize to exact size requested.
1315 EXPECT_EQ("96,112 330x172", window_->bounds().ToString());
1318 // Verifies that a dragged window will restore to its pre-maximized size.
1319 TEST_F(WorkspaceWindowResizerTest, RestoreToPreMaximizeCoordinates) {
1320 window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
1321 wm::WindowState* window_state = wm::GetWindowState(window_.get());
1322 window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1323 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1324 window_.get(), gfx::Point(), HTCAPTION));
1325 ASSERT_TRUE(resizer.get());
1326 // Drag the window to new position by adding (10, 10) to original point,
1327 // the window should get restored.
1328 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
1329 resizer->CompleteDrag();
1330 EXPECT_EQ("10,10 320x160", window_->bounds().ToString());
1331 // The restore rectangle should get cleared as well.
1332 EXPECT_FALSE(window_state->HasRestoreBounds());
1335 // Verifies that a dragged window will restore to its pre-maximized size.
1336 TEST_F(WorkspaceWindowResizerTest, RevertResizeOperation) {
1337 const gfx::Rect initial_bounds(0, 0, 200, 400);
1338 window_->SetBounds(initial_bounds);
1340 wm::WindowState* window_state = wm::GetWindowState(window_.get());
1341 window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1342 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1343 window_.get(), gfx::Point(), HTCAPTION));
1344 ASSERT_TRUE(resizer.get());
1345 // Drag the window to new poistion by adding (180, 16) to original point,
1346 // the window should get restored.
1347 resizer->Drag(CalculateDragPoint(*resizer, 180, 16), 0);
1348 resizer->RevertDrag();
1349 EXPECT_EQ(initial_bounds.ToString(), window_->bounds().ToString());
1350 EXPECT_EQ("96,112 320x160",
1351 window_state->GetRestoreBoundsInScreen().ToString());
1354 // Check that only usable sizes get returned by the resizer.
1355 TEST_F(WorkspaceWindowResizerTest, MagneticallyAttach) {
1356 window_->SetBounds(gfx::Rect(10, 10, 20, 30));
1357 window2_->SetBounds(gfx::Rect(150, 160, 25, 20));
1360 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1361 window_.get(), gfx::Point(), HTCAPTION));
1362 ASSERT_TRUE(resizer.get());
1363 // Move |window| one pixel to the left of |window2|. Should snap to right and
1365 resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
1366 EXPECT_EQ("130,160 20x30", window_->bounds().ToString());
1368 // Move |window| one pixel to the right of |window2|. Should snap to left and
1370 resizer->Drag(CalculateDragPoint(*resizer, 164, 145), 0);
1371 EXPECT_EQ("175,160 20x30", window_->bounds().ToString());
1373 // Move |window| one pixel above |window2|. Should snap to top and left.
1374 resizer->Drag(CalculateDragPoint(*resizer, 142, 119), 0);
1375 EXPECT_EQ("150,130 20x30", window_->bounds().ToString());
1377 // Move |window| one pixel above the bottom of |window2|. Should snap to
1379 resizer->Drag(CalculateDragPoint(*resizer, 142, 169), 0);
1380 EXPECT_EQ("150,180 20x30", window_->bounds().ToString());
1383 // The following variants verify magnetic snapping during resize when dragging a
1385 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOP) {
1386 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1387 window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
1390 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1391 window_.get(), gfx::Point(), HTTOP));
1392 ASSERT_TRUE(resizer.get());
1393 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1394 EXPECT_EQ("100,199 20x31", window_->bounds().ToString());
1397 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPLEFT) {
1398 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1399 window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
1403 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1404 window_.get(), gfx::Point(), HTTOPLEFT));
1405 ASSERT_TRUE(resizer.get());
1406 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1407 EXPECT_EQ("99,199 21x31", window_->bounds().ToString());
1408 resizer->RevertDrag();
1412 window2_->SetBounds(gfx::Rect(88, 201, 10, 20));
1413 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1414 window_.get(), gfx::Point(), HTTOPLEFT));
1415 ASSERT_TRUE(resizer.get());
1416 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1417 EXPECT_EQ("98,201 22x29", window_->bounds().ToString());
1418 resizer->RevertDrag();
1422 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPRIGHT) {
1423 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1427 window2_->SetBounds(gfx::Rect(111, 179, 10, 20));
1428 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1429 window_.get(), gfx::Point(), HTTOPRIGHT));
1430 ASSERT_TRUE(resizer.get());
1431 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1432 EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
1433 resizer->RevertDrag();
1437 window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
1438 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1439 window_.get(), gfx::Point(), HTTOPRIGHT));
1440 ASSERT_TRUE(resizer.get());
1441 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1442 EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
1443 resizer->RevertDrag();
1447 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_RIGHT) {
1448 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1449 window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
1452 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1453 window_.get(), gfx::Point(), HTRIGHT));
1454 ASSERT_TRUE(resizer.get());
1455 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1456 EXPECT_EQ("100,200 21x30", window_->bounds().ToString());
1459 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMRIGHT) {
1460 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1464 window2_->SetBounds(gfx::Rect(122, 212, 10, 20));
1465 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1466 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1467 ASSERT_TRUE(resizer.get());
1468 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1469 EXPECT_EQ("100,200 22x32", window_->bounds().ToString());
1470 resizer->RevertDrag();
1474 window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1475 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1476 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1477 ASSERT_TRUE(resizer.get());
1478 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1479 EXPECT_EQ("100,200 21x33", window_->bounds().ToString());
1480 resizer->RevertDrag();
1484 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOM) {
1485 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1486 window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1489 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1490 window_.get(), gfx::Point(), HTBOTTOM));
1491 ASSERT_TRUE(resizer.get());
1492 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1493 EXPECT_EQ("100,200 20x33", window_->bounds().ToString());
1496 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMLEFT) {
1497 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1501 window2_->SetBounds(gfx::Rect(99, 231, 10, 20));
1502 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1503 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1504 ASSERT_TRUE(resizer.get());
1505 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1506 EXPECT_EQ("99,200 21x31", window_->bounds().ToString());
1507 resizer->RevertDrag();
1511 window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1512 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1513 window_.get(), gfx::Point(), HTBOTTOMLEFT));
1514 ASSERT_TRUE(resizer.get());
1515 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1516 EXPECT_EQ("99,200 21x29", window_->bounds().ToString());
1517 resizer->RevertDrag();
1521 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_LEFT) {
1522 window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1523 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1526 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1527 window_.get(), gfx::Point(), HTLEFT));
1528 ASSERT_TRUE(resizer.get());
1529 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1530 EXPECT_EQ("99,200 21x30", window_->bounds().ToString());
1533 // Test that the user user moved window flag is getting properly set.
1534 TEST_F(WorkspaceWindowResizerTest, CheckUserWindowManagedFlags) {
1535 window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
1537 std::vector<aura::Window*> no_attached_windows;
1538 // Check that an abort doesn't change anything.
1540 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1541 window_.get(), gfx::Point(), HTCAPTION));
1542 ASSERT_TRUE(resizer.get());
1543 // Move it 100 to the bottom.
1544 resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
1545 EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
1546 resizer->RevertDrag();
1548 EXPECT_FALSE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
1551 // Check that a completed move / size does change the user coordinates.
1553 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1554 window_.get(), gfx::Point(), HTCAPTION));
1555 ASSERT_TRUE(resizer.get());
1556 // Move it 100 to the bottom.
1557 resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
1558 EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
1559 resizer->CompleteDrag();
1560 EXPECT_TRUE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
1564 // Test that a window with a specified max size doesn't exceed it when dragged.
1565 TEST_F(WorkspaceWindowResizerTest, TestMaxSizeEnforced) {
1566 window_->SetBounds(gfx::Rect(0, 0, 400, 300));
1567 delegate_.set_max_size(gfx::Size(401, 301));
1569 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1570 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1571 resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
1572 EXPECT_EQ(401, window_->bounds().width());
1573 EXPECT_EQ(301, window_->bounds().height());
1576 // Test that a window with a specified max width doesn't restrict its height.
1577 TEST_F(WorkspaceWindowResizerTest, TestPartialMaxSizeEnforced) {
1578 window_->SetBounds(gfx::Rect(0, 0, 400, 300));
1579 delegate_.set_max_size(gfx::Size(401, 0));
1581 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1582 window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1583 resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
1584 EXPECT_EQ(401, window_->bounds().width());
1585 EXPECT_EQ(302, window_->bounds().height());
1588 // Test that a window with a specified max size can't be snapped.
1589 TEST_F(WorkspaceWindowResizerTest, PhantomSnapMaxSize) {
1591 // With max size not set we get a phantom window controller for dragging off
1592 // the right hand side.
1593 // Make the window wider than maximum docked width.
1594 window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1596 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1597 window_.get(), gfx::Point(), HTCAPTION));
1598 EXPECT_FALSE(snap_phantom_window_controller());
1599 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1600 EXPECT_TRUE(snap_phantom_window_controller());
1601 resizer->RevertDrag();
1604 // With max size defined, we get no phantom window for snapping but we still
1605 // get a phantom window (docking guide).
1606 window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1607 delegate_.set_max_size(gfx::Size(400, 200));
1609 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1610 window_.get(), gfx::Point(), HTCAPTION));
1611 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1612 if (switches::UseDockedWindows())
1613 EXPECT_TRUE(snap_phantom_window_controller());
1615 EXPECT_FALSE(snap_phantom_window_controller());
1616 resizer->RevertDrag();
1619 // With max size defined, we get no phantom window for snapping.
1620 window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1621 delegate_.set_max_size(gfx::Size(400, 200));
1622 // With min size defined, we get no phantom window for docking.
1623 delegate_.set_min_size(gfx::Size(400, 200));
1625 scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1626 window_.get(), gfx::Point(), HTCAPTION));
1627 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1628 EXPECT_FALSE(snap_phantom_window_controller());
1629 resizer->RevertDrag();
1633 TEST_F(WorkspaceWindowResizerTest, DontRewardRightmostWindowForOverflows) {
1634 UpdateDisplay("600x800");
1635 aura::Window* root = Shell::GetPrimaryRootWindow();
1636 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1638 // Four 100x100 windows flush against eachother, starting at 100,100.
1639 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1640 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1641 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1642 window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
1643 delegate2_.set_max_size(gfx::Size(101, 0));
1645 std::vector<aura::Window*> windows;
1646 windows.push_back(window2_.get());
1647 windows.push_back(window3_.get());
1648 windows.push_back(window4_.get());
1649 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1650 window_.get(), gfx::Point(), HTRIGHT,
1651 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1652 ASSERT_TRUE(resizer.get());
1653 // Move it 51 to the left, which should contract w1 and expand w2-4.
1654 // w2 will hit its max size straight away, and in doing so will leave extra
1655 // pixels that a naive implementation may award to the rightmost window. A
1656 // fair implementation will give 25 pixels to each of the other windows.
1657 resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
1658 EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
1659 EXPECT_EQ("149,100 101x100", window2_->bounds().ToString());
1660 EXPECT_EQ("250,100 125x100", window3_->bounds().ToString());
1661 EXPECT_EQ("375,100 125x100", window4_->bounds().ToString());
1664 TEST_F(WorkspaceWindowResizerTest, DontExceedMaxWidth) {
1665 UpdateDisplay("600x800");
1666 aura::Window* root = Shell::GetPrimaryRootWindow();
1667 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1669 // Four 100x100 windows flush against eachother, starting at 100,100.
1670 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1671 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1672 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1673 window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
1674 delegate2_.set_max_size(gfx::Size(101, 0));
1675 delegate3_.set_max_size(gfx::Size(101, 0));
1677 std::vector<aura::Window*> windows;
1678 windows.push_back(window2_.get());
1679 windows.push_back(window3_.get());
1680 windows.push_back(window4_.get());
1681 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1682 window_.get(), gfx::Point(), HTRIGHT,
1683 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1684 ASSERT_TRUE(resizer.get());
1685 // Move it 52 to the left, which should contract w1 and expand w2-4.
1686 resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
1687 EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
1688 EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
1689 EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
1690 EXPECT_EQ("350,100 150x100", window4_->bounds().ToString());
1693 TEST_F(WorkspaceWindowResizerTest, DontExceedMaxHeight) {
1694 UpdateDisplay("600x800");
1695 aura::Window* root = Shell::GetPrimaryRootWindow();
1696 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1698 // Four 100x100 windows flush against eachother, starting at 100,100.
1699 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1700 window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
1701 window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
1702 window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
1703 delegate2_.set_max_size(gfx::Size(0, 101));
1704 delegate3_.set_max_size(gfx::Size(0, 101));
1706 std::vector<aura::Window*> windows;
1707 windows.push_back(window2_.get());
1708 windows.push_back(window3_.get());
1709 windows.push_back(window4_.get());
1710 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1711 window_.get(), gfx::Point(), HTBOTTOM,
1712 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1713 ASSERT_TRUE(resizer.get());
1714 // Move it 52 up, which should contract w1 and expand w2-4.
1715 resizer->Drag(CalculateDragPoint(*resizer, 0, -52), 0);
1716 EXPECT_EQ("100,100 100x48", window_->bounds().ToString());
1717 EXPECT_EQ("100,148 100x101", window2_->bounds().ToString());
1718 EXPECT_EQ("100,249 100x101", window3_->bounds().ToString());
1719 EXPECT_EQ("100,350 100x150", window4_->bounds().ToString());
1723 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1724 #define MAYBE_DontExceedMinHeight DISABLED_DontExceedMinHeight
1726 #define MAYBE_DontExceedMinHeight DontExceedMinHeight
1729 TEST_F(WorkspaceWindowResizerTest, MAYBE_DontExceedMinHeight) {
1730 UpdateDisplay("600x500");
1731 aura::Window* root = Shell::GetPrimaryRootWindow();
1732 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1734 // Four 100x100 windows flush against eachother, starting at 100,100.
1735 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1736 window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
1737 window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
1738 window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
1739 delegate2_.set_min_size(gfx::Size(0, 99));
1740 delegate3_.set_min_size(gfx::Size(0, 99));
1742 std::vector<aura::Window*> windows;
1743 windows.push_back(window2_.get());
1744 windows.push_back(window3_.get());
1745 windows.push_back(window4_.get());
1746 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1747 window_.get(), gfx::Point(), HTBOTTOM,
1748 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1749 ASSERT_TRUE(resizer.get());
1750 // Move it 52 down, which should expand w1 and contract w2-4.
1751 resizer->Drag(CalculateDragPoint(*resizer, 0, 52), 0);
1752 EXPECT_EQ("100,100 100x152", window_->bounds().ToString());
1753 EXPECT_EQ("100,252 100x99", window2_->bounds().ToString());
1754 EXPECT_EQ("100,351 100x99", window3_->bounds().ToString());
1755 EXPECT_EQ("100,450 100x50", window4_->bounds().ToString());
1758 TEST_F(WorkspaceWindowResizerTest, DontExpandRightmostPastMaxWidth) {
1759 UpdateDisplay("600x800");
1760 aura::Window* root = Shell::GetPrimaryRootWindow();
1761 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1763 // Three 100x100 windows flush against eachother, starting at 100,100.
1764 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1765 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1766 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1767 delegate3_.set_max_size(gfx::Size(101, 0));
1769 std::vector<aura::Window*> windows;
1770 windows.push_back(window2_.get());
1771 windows.push_back(window3_.get());
1772 windows.push_back(window4_.get());
1773 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1774 window_.get(), gfx::Point(), HTRIGHT,
1775 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1776 ASSERT_TRUE(resizer.get());
1777 // Move it 51 to the left, which should contract w1 and expand w2-3.
1778 resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
1779 EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
1780 EXPECT_EQ("149,100 150x100", window2_->bounds().ToString());
1781 EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
1784 TEST_F(WorkspaceWindowResizerTest, MoveAttachedWhenGrownToMaxSize) {
1785 UpdateDisplay("600x800");
1786 aura::Window* root = Shell::GetPrimaryRootWindow();
1787 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1789 // Three 100x100 windows flush against eachother, starting at 100,100.
1790 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1791 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1792 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1793 delegate2_.set_max_size(gfx::Size(101, 0));
1794 delegate3_.set_max_size(gfx::Size(101, 0));
1796 std::vector<aura::Window*> windows;
1797 windows.push_back(window2_.get());
1798 windows.push_back(window3_.get());
1799 windows.push_back(window4_.get());
1800 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1801 window_.get(), gfx::Point(), HTRIGHT,
1802 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1803 ASSERT_TRUE(resizer.get());
1804 // Move it 52 to the left, which should contract w1 and expand and move w2-3.
1805 resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
1806 EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
1807 EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
1808 EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
1812 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1813 #define MAYBE_MainWindowHonoursMaxWidth DISABLED_MainWindowHonoursMaxWidth
1815 #define MAYBE_MainWindowHonoursMaxWidth MainWindowHonoursMaxWidth
1818 TEST_F(WorkspaceWindowResizerTest, MAYBE_MainWindowHonoursMaxWidth) {
1819 UpdateDisplay("400x800");
1820 aura::Window* root = Shell::GetPrimaryRootWindow();
1821 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1823 // Three 100x100 windows flush against eachother, starting at 100,100.
1824 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1825 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1826 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1827 delegate_.set_max_size(gfx::Size(102, 0));
1829 std::vector<aura::Window*> windows;
1830 windows.push_back(window2_.get());
1831 windows.push_back(window3_.get());
1832 windows.push_back(window4_.get());
1833 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1834 window_.get(), gfx::Point(), HTRIGHT,
1835 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1836 ASSERT_TRUE(resizer.get());
1837 // Move it 50 to the right, which should expand w1 and contract w2-3, as they
1838 // won't fit in the root window in their original sizes.
1839 resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
1840 EXPECT_EQ("100,100 102x100", window_->bounds().ToString());
1841 EXPECT_EQ("202,100 99x100", window2_->bounds().ToString());
1842 EXPECT_EQ("301,100 99x100", window3_->bounds().ToString());
1845 TEST_F(WorkspaceWindowResizerTest, MainWindowHonoursMinWidth) {
1846 UpdateDisplay("400x800");
1847 aura::Window* root = Shell::GetPrimaryRootWindow();
1848 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1850 // Three 100x100 windows flush against eachother, starting at 100,100.
1851 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1852 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1853 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1854 delegate_.set_min_size(gfx::Size(98, 0));
1856 std::vector<aura::Window*> windows;
1857 windows.push_back(window2_.get());
1858 windows.push_back(window3_.get());
1859 scoped_ptr<WorkspaceWindowResizer> resizer(CreateWorkspaceResizerForTest(
1860 window_.get(), gfx::Point(), HTRIGHT,
1861 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1862 ASSERT_TRUE(resizer.get());
1863 // Move it 50 to the left, which should contract w1 and expand w2-3.
1864 resizer->Drag(CalculateDragPoint(*resizer, -50, 0), 0);
1865 EXPECT_EQ("100,100 98x100", window_->bounds().ToString());
1866 EXPECT_EQ("198,100 101x100", window2_->bounds().ToString());
1867 EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
1870 // The following variants test that windows are resized correctly to the edges
1871 // of the screen using touch, when touch point is off of the window border.
1872 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_RIGHT) {
1873 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1875 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTRIGHT);
1876 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1877 touch_resize_window_->bounds().ToString());
1879 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1880 touch_resize_window_.get());
1882 // Drag out of the right border a bit and check if the border is aligned with
1884 generator.GestureScrollSequence(gfx::Point(715, kRootHeight / 2),
1885 gfx::Point(725, kRootHeight / 2),
1886 base::TimeDelta::FromMilliseconds(10),
1888 EXPECT_EQ(gfx::Rect(100, 100, 625, kRootHeight - 200).ToString(),
1889 touch_resize_window_->bounds().ToString());
1890 // Drag more, but stop before being snapped to the edge.
1891 generator.GestureScrollSequence(gfx::Point(725, kRootHeight / 2),
1892 gfx::Point(760, kRootHeight / 2),
1893 base::TimeDelta::FromMilliseconds(10),
1895 EXPECT_EQ(gfx::Rect(100, 100, 660, kRootHeight - 200).ToString(),
1896 touch_resize_window_->bounds().ToString());
1897 // Drag even more to snap to the edge.
1898 generator.GestureScrollSequence(gfx::Point(760, kRootHeight / 2),
1899 gfx::Point(775, kRootHeight / 2),
1900 base::TimeDelta::FromMilliseconds(10),
1902 EXPECT_EQ(gfx::Rect(100, 100, 700, kRootHeight - 200).ToString(),
1903 touch_resize_window_->bounds().ToString());
1906 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_LEFT) {
1907 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1909 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTLEFT);
1910 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1911 touch_resize_window_->bounds().ToString());
1913 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1914 touch_resize_window_.get());
1916 // Drag out of the left border a bit and check if the border is aligned with
1918 generator.GestureScrollSequence(gfx::Point(85, kRootHeight / 2),
1919 gfx::Point(75, kRootHeight / 2),
1920 base::TimeDelta::FromMilliseconds(10),
1922 EXPECT_EQ(gfx::Rect(75, 100, 625, kRootHeight - 200).ToString(),
1923 touch_resize_window_->bounds().ToString());
1924 // Drag more, but stop before being snapped to the edge.
1925 generator.GestureScrollSequence(gfx::Point(75, kRootHeight / 2),
1926 gfx::Point(40, kRootHeight / 2),
1927 base::TimeDelta::FromMilliseconds(10),
1929 EXPECT_EQ(gfx::Rect(40, 100, 660, kRootHeight - 200).ToString(),
1930 touch_resize_window_->bounds().ToString());
1931 // Drag even more to snap to the edge.
1932 generator.GestureScrollSequence(gfx::Point(40, kRootHeight / 2),
1933 gfx::Point(25, kRootHeight / 2),
1934 base::TimeDelta::FromMilliseconds(10),
1936 EXPECT_EQ(gfx::Rect(0, 100, 700, kRootHeight - 200).ToString(),
1937 touch_resize_window_->bounds().ToString());
1940 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_TOP) {
1941 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1943 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTTOP);
1944 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1945 touch_resize_window_->bounds().ToString());
1947 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1948 touch_resize_window_.get());
1950 // Drag out of the top border a bit and check if the border is aligned with
1952 generator.GestureScrollSequence(gfx::Point(400, 85),
1953 gfx::Point(400, 75),
1954 base::TimeDelta::FromMilliseconds(10),
1956 EXPECT_EQ(gfx::Rect(100, 75, 600, kRootHeight - 175).ToString(),
1957 touch_resize_window_->bounds().ToString());
1958 // Drag more, but stop before being snapped to the edge.
1959 generator.GestureScrollSequence(gfx::Point(400, 75),
1960 gfx::Point(400, 40),
1961 base::TimeDelta::FromMilliseconds(10),
1963 EXPECT_EQ(gfx::Rect(100, 40, 600, kRootHeight - 140).ToString(),
1964 touch_resize_window_->bounds().ToString());
1965 // Drag even more to snap to the edge.
1966 generator.GestureScrollSequence(gfx::Point(400, 40),
1967 gfx::Point(400, 25),
1968 base::TimeDelta::FromMilliseconds(10),
1970 EXPECT_EQ(gfx::Rect(100, 0, 600, kRootHeight - 100).ToString(),
1971 touch_resize_window_->bounds().ToString());
1974 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
1975 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1977 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTBOTTOM);
1978 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1979 touch_resize_window_->bounds().ToString());
1981 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1982 touch_resize_window_.get());
1984 // Drag out of the bottom border a bit and check if the border is aligned with
1986 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 85),
1987 gfx::Point(400, kRootHeight - 75),
1988 base::TimeDelta::FromMilliseconds(10),
1990 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 175).ToString(),
1991 touch_resize_window_->bounds().ToString());
1992 // Drag more, but stop before being snapped to the edge.
1993 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 75),
1994 gfx::Point(400, kRootHeight - 40),
1995 base::TimeDelta::FromMilliseconds(10),
1997 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 140).ToString(),
1998 touch_resize_window_->bounds().ToString());
1999 // Drag even more to snap to the edge.
2000 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 40),
2001 gfx::Point(400, kRootHeight - 25),
2002 base::TimeDelta::FromMilliseconds(10),
2004 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 100).ToString(),
2005 touch_resize_window_->bounds().ToString());
2008 } // namespace internal