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_ash.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/gfx/insets.h"
30 #include "ui/gfx/screen.h"
31 #include "ui/views/widget/widget.h"
35 // Class to provide access to SlideAnimation internals for testing.
36 // TODO: this should be next to SlideAnimation, not here.
37 class SlideAnimation::TestApi {
39 explicit TestApi(SlideAnimation* animation) : animation_(animation) {}
41 void SetStartTime(base::TimeTicks ticks) {
42 animation_->SetStartTime(ticks);
45 void Step(base::TimeTicks ticks) {
46 animation_->Step(ticks);
49 void RunTillComplete() {
50 SetStartTime(base::TimeTicks());
51 Step(base::TimeTicks() +
52 base::TimeDelta::FromMilliseconds(animation_->GetSlideDuration()));
53 EXPECT_EQ(1.0, animation_->GetCurrentValue());
57 SlideAnimation* animation_;
59 DISALLOW_COPY_AND_ASSIGN(TestApi);
68 const int kRootHeight = 600;
70 // A simple window delegate that returns the specified min size.
71 class TestWindowDelegate : public aura::test::TestWindowDelegate {
73 TestWindowDelegate() {
75 virtual ~TestWindowDelegate() {}
77 void set_min_size(const gfx::Size& size) {
81 void set_max_size(const gfx::Size& size) {
86 // Overridden from aura::Test::TestWindowDelegate:
87 virtual gfx::Size GetMinimumSize() const OVERRIDE {
91 virtual gfx::Size GetMaximumSize() const OVERRIDE {
98 DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
101 class WorkspaceWindowResizerTest : public test::AshTestBase {
103 WorkspaceWindowResizerTest() {}
104 virtual ~WorkspaceWindowResizerTest() {}
106 virtual void SetUp() OVERRIDE {
107 AshTestBase::SetUp();
108 UpdateDisplay(base::StringPrintf("800x%d", kRootHeight));
110 aura::Window* root = Shell::GetPrimaryRootWindow();
111 gfx::Rect root_bounds(root->bounds());
113 // RootWindow and Display can't resize on Windows Ash.
114 // http://crbug.com/165962
115 EXPECT_EQ(kRootHeight, root_bounds.height());
117 EXPECT_EQ(800, root_bounds.width());
118 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
119 window_.reset(new aura::Window(&delegate_));
120 window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
121 window_->Init(ui::LAYER_NOT_DRAWN);
122 ParentWindowInPrimaryRootWindow(window_.get());
125 window2_.reset(new aura::Window(&delegate2_));
126 window2_->SetType(aura::client::WINDOW_TYPE_NORMAL);
127 window2_->Init(ui::LAYER_NOT_DRAWN);
128 ParentWindowInPrimaryRootWindow(window2_.get());
131 window3_.reset(new aura::Window(&delegate3_));
132 window3_->SetType(aura::client::WINDOW_TYPE_NORMAL);
133 window3_->Init(ui::LAYER_NOT_DRAWN);
134 ParentWindowInPrimaryRootWindow(window3_.get());
137 window4_.reset(new aura::Window(&delegate4_));
138 window4_->SetType(aura::client::WINDOW_TYPE_NORMAL);
139 window4_->Init(ui::LAYER_NOT_DRAWN);
140 ParentWindowInPrimaryRootWindow(window4_.get());
144 virtual void TearDown() OVERRIDE {
149 touch_resize_window_.reset();
150 AshTestBase::TearDown();
153 // Returns a string identifying the z-order of each of the known child windows
154 // of |parent|. The returned string constains the id of the known windows and
155 // is ordered from topmost to bottomost windows.
156 std::string WindowOrderAsString(aura::Window* parent) const {
158 const aura::Window::Windows& windows = parent->children();
159 for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
160 i != windows.rend(); ++i) {
161 if (*i == window_ || *i == window2_ || *i == window3_) {
164 result += base::IntToString((*i)->id());
171 gfx::Point CalculateDragPoint(const WorkspaceWindowResizer& resizer,
174 gfx::Point location = resizer.GetInitialLocation();
175 location.set_x(location.x() + delta_x);
176 location.set_y(location.y() + delta_y);
180 std::vector<aura::Window*> empty_windows() const {
181 return std::vector<aura::Window*>();
184 internal::ShelfLayoutManager* shelf_layout_manager() {
185 return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
188 void InitTouchResizeWindow(const gfx::Rect& bounds, int window_component) {
189 touch_resize_delegate_.set_window_component(window_component);
190 touch_resize_window_.reset(
191 CreateTestWindowInShellWithDelegate(&touch_resize_delegate_, 0,
193 gfx::Insets mouse_outer_insets(-ash::kResizeOutsideBoundsSize,
194 -ash::kResizeOutsideBoundsSize,
195 -ash::kResizeOutsideBoundsSize,
196 -ash::kResizeOutsideBoundsSize);
197 gfx::Insets touch_outer_insets = mouse_outer_insets.Scale(
198 ash::kResizeOutsideBoundsScaleForTouch);
199 touch_resize_window_->SetHitTestBoundsOverrideOuter(mouse_outer_insets,
203 // Simulate running the animation.
204 void RunAnimationTillComplete(gfx::SlideAnimation* animation) {
205 gfx::SlideAnimation::TestApi test_api(animation);
206 test_api.RunTillComplete();
209 TestWindowDelegate delegate_;
210 TestWindowDelegate delegate2_;
211 TestWindowDelegate delegate3_;
212 TestWindowDelegate delegate4_;
213 scoped_ptr<aura::Window> window_;
214 scoped_ptr<aura::Window> window2_;
215 scoped_ptr<aura::Window> window3_;
216 scoped_ptr<aura::Window> window4_;
218 TestWindowDelegate touch_resize_delegate_;
219 scoped_ptr<aura::Window> touch_resize_window_;
222 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
225 class WorkspaceWindowResizerTestSticky : public WorkspaceWindowResizerTest {
227 WorkspaceWindowResizerTestSticky() {}
228 virtual ~WorkspaceWindowResizerTestSticky() {}
230 virtual void SetUp() OVERRIDE {
231 CommandLine::ForCurrentProcess()->AppendSwitch(
232 ash::switches::kAshEnableStickyEdges);
233 WorkspaceWindowResizerTest::SetUp();
237 DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTestSticky);
242 // Assertions around attached window resize dragging from the right with 2
244 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_2) {
245 window_->SetBounds(gfx::Rect(0, 300, 400, 300));
246 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
248 std::vector<aura::Window*> windows;
249 windows.push_back(window2_.get());
250 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
251 window_.get(), gfx::Point(), HTRIGHT,
252 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
253 ASSERT_TRUE(resizer.get());
254 // Move it 100 to the right, which should expand w1 and push w2.
255 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
256 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
257 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
259 // Push off the screen, w2 should be resized to its min.
260 delegate2_.set_min_size(gfx::Size(20, 20));
261 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
262 EXPECT_EQ("0,300 780x300", window_->bounds().ToString());
263 EXPECT_EQ("780,200 20x200", window2_->bounds().ToString());
265 // Move back to 100 and verify w2 gets its original size.
266 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
267 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
268 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
270 // Revert and make sure everything moves back.
271 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
272 resizer->RevertDrag();
273 EXPECT_EQ("0,300 400x300", window_->bounds().ToString());
274 EXPECT_EQ("400,200 100x200", window2_->bounds().ToString());
277 // Assertions around collapsing and expanding.
278 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_Compress) {
279 window_->SetBounds(gfx::Rect( 0, 300, 400, 300));
280 window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
282 std::vector<aura::Window*> windows;
283 windows.push_back(window2_.get());
284 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
285 window_.get(), gfx::Point(), HTRIGHT,
286 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
287 ASSERT_TRUE(resizer.get());
288 // Move it 100 to the left, which should expand w2 and collapse w1.
289 resizer->Drag(CalculateDragPoint(*resizer, -100, 10), 0);
290 EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
291 EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
293 // Collapse all the way to w1's min.
294 delegate_.set_min_size(gfx::Size(20, 20));
295 resizer->Drag(CalculateDragPoint(*resizer, -800, 20), 0);
296 EXPECT_EQ("0,300 20x300", window_->bounds().ToString());
297 EXPECT_EQ("20,200 480x200", window2_->bounds().ToString());
299 // Move 100 to the left.
300 resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
301 EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
302 EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
305 resizer->Drag(CalculateDragPoint(*resizer, -100, 20), 0);
306 EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
307 EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
310 // Assertions around attached window resize dragging from the right with 3
312 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3) {
313 window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
314 window2_->SetBounds(gfx::Rect(300, 300, 150, 200));
315 window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
316 delegate2_.set_min_size(gfx::Size(52, 50));
317 delegate3_.set_min_size(gfx::Size(38, 50));
319 std::vector<aura::Window*> windows;
320 windows.push_back(window2_.get());
321 windows.push_back(window3_.get());
322 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
323 window_.get(), gfx::Point(), HTRIGHT,
324 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
325 ASSERT_TRUE(resizer.get());
326 // Move it 100 to the right, which should expand w1 and push w2 and w3.
327 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
328 EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
329 EXPECT_EQ("400,300 150x200", window2_->bounds().ToString());
330 EXPECT_EQ("550,300 100x200", window3_->bounds().ToString());
332 // Move it 300, things should compress.
333 resizer->Drag(CalculateDragPoint(*resizer, 300, -10), 0);
334 EXPECT_EQ("100,300 500x300", window_->bounds().ToString());
335 EXPECT_EQ("600,300 120x200", window2_->bounds().ToString());
336 EXPECT_EQ("720,300 80x200", window3_->bounds().ToString());
338 // Move it so much the last two end up at their min.
339 resizer->Drag(CalculateDragPoint(*resizer, 800, 50), 0);
340 EXPECT_EQ("100,300 610x300", window_->bounds().ToString());
341 EXPECT_EQ("710,300 52x200", window2_->bounds().ToString());
342 EXPECT_EQ("762,300 38x200", window3_->bounds().ToString());
344 // Revert and make sure everything moves back.
345 resizer->RevertDrag();
346 EXPECT_EQ("100,300 200x300", window_->bounds().ToString());
347 EXPECT_EQ("300,300 150x200", window2_->bounds().ToString());
348 EXPECT_EQ("450,300 100x200", window3_->bounds().ToString());
351 // Assertions around attached window resizing (collapsing and expanding) with
353 TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3_Compress) {
354 window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
355 window2_->SetBounds(gfx::Rect(300, 300, 200, 200));
356 window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
357 delegate2_.set_min_size(gfx::Size(52, 50));
358 delegate3_.set_min_size(gfx::Size(38, 50));
360 std::vector<aura::Window*> windows;
361 windows.push_back(window2_.get());
362 windows.push_back(window3_.get());
363 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
364 window_.get(), gfx::Point(), HTRIGHT,
365 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
366 ASSERT_TRUE(resizer.get());
367 // Move it -100 to the right, which should collapse w1 and expand w2 and w3.
368 resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
369 EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
370 EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
371 EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
373 // Move it 100 to the right.
374 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
375 EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
376 EXPECT_EQ("400,300 200x200", window2_->bounds().ToString());
377 EXPECT_EQ("600,300 100x200", window3_->bounds().ToString());
379 // 100 to the left again.
380 resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
381 EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
382 EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
383 EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
386 // Assertions around collapsing and expanding from the bottom.
387 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_Compress) {
388 window_->SetBounds(gfx::Rect( 0, 100, 400, 300));
389 window2_->SetBounds(gfx::Rect(400, 400, 100, 200));
391 std::vector<aura::Window*> windows;
392 windows.push_back(window2_.get());
393 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
394 window_.get(), gfx::Point(), HTBOTTOM,
395 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
396 ASSERT_TRUE(resizer.get());
397 // Move it up 100, which should expand w2 and collapse w1.
398 resizer->Drag(CalculateDragPoint(*resizer, 10, -100), 0);
399 EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
400 EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
402 // Collapse all the way to w1's min.
403 delegate_.set_min_size(gfx::Size(20, 20));
404 resizer->Drag(CalculateDragPoint(*resizer, 20, -800), 0);
405 EXPECT_EQ("0,100 400x20", window_->bounds().ToString());
406 EXPECT_EQ("400,120 100x480", window2_->bounds().ToString());
409 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
410 EXPECT_EQ("0,100 400x400", window_->bounds().ToString());
411 EXPECT_EQ("400,500 100x100", window2_->bounds().ToString());
414 resizer->Drag(CalculateDragPoint(*resizer, 20, -100), 0);
415 EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
416 EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
419 // Assertions around attached window resize dragging from the bottom with 2
421 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_2) {
422 window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
423 window2_->SetBounds(gfx::Rect(0, 250, 200, 100));
425 std::vector<aura::Window*> windows;
426 windows.push_back(window2_.get());
427 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
428 window_.get(), gfx::Point(), HTBOTTOM,
429 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
430 ASSERT_TRUE(resizer.get());
431 // Move it 100 to the bottom, which should expand w1 and push w2.
432 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
433 EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
434 EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
436 // Push off the screen, w2 should be resized to its min.
437 delegate2_.set_min_size(gfx::Size(20, 20));
438 resizer->Drag(CalculateDragPoint(*resizer, 50, 820), 0);
439 EXPECT_EQ("0,50 400x530", window_->bounds().ToString());
440 EXPECT_EQ("0,580 200x20", window2_->bounds().ToString());
442 // Move back to 100 and verify w2 gets its original size.
443 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
444 EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
445 EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
447 // Revert and make sure everything moves back.
448 resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
449 resizer->RevertDrag();
450 EXPECT_EQ("0,50 400x200", window_->bounds().ToString());
451 EXPECT_EQ("0,250 200x100", window2_->bounds().ToString());
455 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
456 #define MAYBE_AttachedResize_BOTTOM_3 DISABLED_AttachedResize_BOTTOM_3
458 #define MAYBE_AttachedResize_BOTTOM_3 AttachedResize_BOTTOM_3
461 // Assertions around attached window resize dragging from the bottom with 3
463 TEST_F(WorkspaceWindowResizerTest, MAYBE_AttachedResize_BOTTOM_3) {
464 UpdateDisplay("600x800");
465 aura::Window* root = Shell::GetPrimaryRootWindow();
466 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
468 window_->SetBounds(gfx::Rect( 300, 100, 300, 200));
469 window2_->SetBounds(gfx::Rect(300, 300, 200, 150));
470 window3_->SetBounds(gfx::Rect(300, 450, 200, 100));
471 delegate2_.set_min_size(gfx::Size(50, 52));
472 delegate3_.set_min_size(gfx::Size(50, 38));
474 std::vector<aura::Window*> windows;
475 windows.push_back(window2_.get());
476 windows.push_back(window3_.get());
477 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
478 window_.get(), gfx::Point(), HTBOTTOM,
479 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
480 ASSERT_TRUE(resizer.get());
481 // Move it 100 down, which should expand w1 and push w2 and w3.
482 resizer->Drag(CalculateDragPoint(*resizer, -10, 100), 0);
483 EXPECT_EQ("300,100 300x300", window_->bounds().ToString());
484 EXPECT_EQ("300,400 200x150", window2_->bounds().ToString());
485 EXPECT_EQ("300,550 200x100", window3_->bounds().ToString());
487 // Move it 296 things should compress.
488 resizer->Drag(CalculateDragPoint(*resizer, -10, 296), 0);
489 EXPECT_EQ("300,100 300x496", window_->bounds().ToString());
490 EXPECT_EQ("300,596 200x123", window2_->bounds().ToString());
491 EXPECT_EQ("300,719 200x81", window3_->bounds().ToString());
493 // Move it so much everything ends up at its min.
494 resizer->Drag(CalculateDragPoint(*resizer, 50, 798), 0);
495 EXPECT_EQ("300,100 300x610", window_->bounds().ToString());
496 EXPECT_EQ("300,710 200x52", window2_->bounds().ToString());
497 EXPECT_EQ("300,762 200x38", window3_->bounds().ToString());
499 // Revert and make sure everything moves back.
500 resizer->RevertDrag();
501 EXPECT_EQ("300,100 300x200", window_->bounds().ToString());
502 EXPECT_EQ("300,300 200x150", window2_->bounds().ToString());
503 EXPECT_EQ("300,450 200x100", window3_->bounds().ToString());
506 // Assertions around attached window resizing (collapsing and expanding) with
508 TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_3_Compress) {
509 window_->SetBounds(gfx::Rect( 0, 0, 200, 200));
510 window2_->SetBounds(gfx::Rect(10, 200, 200, 200));
511 window3_->SetBounds(gfx::Rect(20, 400, 100, 100));
512 delegate2_.set_min_size(gfx::Size(52, 50));
513 delegate3_.set_min_size(gfx::Size(38, 50));
515 std::vector<aura::Window*> windows;
516 windows.push_back(window2_.get());
517 windows.push_back(window3_.get());
518 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
519 window_.get(), gfx::Point(), HTBOTTOM,
520 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
521 ASSERT_TRUE(resizer.get());
522 // Move it 100 up, which should collapse w1 and expand w2 and w3.
523 resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
524 EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
525 EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
526 EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
529 resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
530 EXPECT_EQ("0,0 200x300", window_->bounds().ToString());
531 EXPECT_EQ("10,300 200x200", window2_->bounds().ToString());
532 EXPECT_EQ("20,500 100x100", window3_->bounds().ToString());
535 resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
536 EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
537 EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
538 EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
542 // Assertions around dragging to the left/right edge of the screen.
543 TEST_F(WorkspaceWindowResizerTest, Edge) {
545 ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
546 window_->SetBounds(gfx::Rect(20, 30, 50, 60));
547 wm::WindowState* window_state = wm::GetWindowState(window_.get());
550 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
551 window_.get(), gfx::Point(), HTCAPTION,
552 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
553 ASSERT_TRUE(resizer.get());
554 resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
555 resizer->CompleteDrag(0);
556 EXPECT_EQ("0,0 720x" + base::IntToString(bottom),
557 window_->bounds().ToString());
558 ASSERT_TRUE(window_state->HasRestoreBounds());
559 EXPECT_EQ("20,30 50x60",
560 window_state->GetRestoreBoundsInScreen().ToString());
562 // Try the same with the right side.
564 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
565 window_.get(), gfx::Point(), HTCAPTION,
566 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
567 ASSERT_TRUE(resizer.get());
568 resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
569 resizer->CompleteDrag(0);
570 EXPECT_EQ("80,0 720x" + base::IntToString(bottom),
571 window_->bounds().ToString());
572 ASSERT_TRUE(window_state->HasRestoreBounds());
573 EXPECT_EQ("20,30 50x60",
574 window_state->GetRestoreBoundsInScreen().ToString());
577 // Test if the restore bounds is correct in multiple displays.
578 window_state->ClearRestoreBounds();
580 if (!SupportsMultipleDisplays())
583 UpdateDisplay("800x600,200x600");
584 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
585 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
586 window_->SetBoundsInScreen(gfx::Rect(800, 10, 50, 60),
587 ScreenAsh::GetSecondaryDisplay());
588 EXPECT_EQ(root_windows[1], window_->GetRootWindow());
591 ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
592 EXPECT_EQ("800,10 50x60", window_->GetBoundsInScreen().ToString());
594 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
595 window_.get(), gfx::Point(), HTCAPTION,
596 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
597 ASSERT_TRUE(resizer.get());
599 resizer->Drag(CalculateDragPoint(*resizer, 199, 00), 0);
600 resizer->CompleteDrag(0);
601 // With the resolution of 200x600 we will hit in this case the 50% screen
603 EXPECT_EQ("100,0 100x" + base::IntToString(bottom),
604 window_->bounds().ToString());
605 EXPECT_EQ("800,10 50x60",
606 window_state->GetRestoreBoundsInScreen().ToString());
610 // Check that non resizable windows will not get resized.
611 TEST_F(WorkspaceWindowResizerTest, NonResizableWindows) {
612 window_->SetBounds(gfx::Rect(20, 30, 50, 60));
613 window_->SetProperty(aura::client::kCanResizeKey, false);
615 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
616 window_.get(), gfx::Point(), HTCAPTION,
617 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
618 ASSERT_TRUE(resizer.get());
619 resizer->Drag(CalculateDragPoint(*resizer, -20, 0), 0);
620 resizer->CompleteDrag(0);
621 EXPECT_EQ("0,30 50x60", window_->bounds().ToString());
624 TEST_F(WorkspaceWindowResizerTest, CancelSnapPhantom) {
625 if (!SupportsMultipleDisplays())
628 UpdateDisplay("800x600,800x600");
629 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
630 ASSERT_EQ(2U, root_windows.size());
632 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
633 Shell::GetScreen()->GetPrimaryDisplay());
634 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
635 EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
637 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
638 window_.get(), gfx::Point(), HTCAPTION,
639 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
640 ASSERT_TRUE(resizer.get());
641 EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
643 // The pointer is on the edge but not shared. The snap phantom window
644 // controller should be non-NULL.
645 resizer->Drag(CalculateDragPoint(*resizer, 799, 0), 0);
646 EXPECT_TRUE(resizer->snap_phantom_window_controller_.get());
648 // Move the cursor across the edge. Now the snap phantom window controller
649 // should be canceled.
650 resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0);
651 EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
655 // Verifies windows are correctly restacked when reordering multiple windows.
656 TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
657 window_->SetBounds(gfx::Rect( 0, 0, 200, 300));
658 window2_->SetBounds(gfx::Rect(200, 0, 100, 200));
659 window3_->SetBounds(gfx::Rect(300, 0, 100, 100));
662 std::vector<aura::Window*> windows;
663 windows.push_back(window2_.get());
664 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
665 window_.get(), gfx::Point(), HTRIGHT,
666 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
667 ASSERT_TRUE(resizer.get());
668 // Move it 100 to the right, which should expand w1 and push w2 and w3.
669 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
671 // 2 should be topmost since it's initially the highest in the stack.
672 EXPECT_EQ("2 1 3", WindowOrderAsString(window_->parent()));
676 std::vector<aura::Window*> windows;
677 windows.push_back(window3_.get());
678 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
679 window2_.get(), gfx::Point(), HTRIGHT,
680 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
681 ASSERT_TRUE(resizer.get());
682 // Move it 100 to the right, which should expand w1 and push w2 and w3.
683 resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
685 // 2 should be topmost since it's initially the highest in the stack.
686 EXPECT_EQ("2 3 1", WindowOrderAsString(window_->parent()));
690 // Makes sure we don't allow dragging below the work area.
691 TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) {
692 Shell::GetInstance()->SetDisplayWorkAreaInsets(
693 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
695 ASSERT_EQ(1, Shell::GetScreen()->GetNumDisplays());
697 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
698 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
699 window_.get(), gfx::Point(), HTCAPTION,
700 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
701 ASSERT_TRUE(resizer.get());
702 resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
704 kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
705 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
706 window_->bounds().ToString());
709 // Makes sure we don't allow dragging on the work area with multidisplay.
710 TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
711 if (!SupportsMultipleDisplays())
714 UpdateDisplay("800x600,800x600");
715 ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
717 Shell::GetInstance()->SetDisplayWorkAreaInsets(
718 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
720 // Positions the secondary display at the bottom the primary display.
721 Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
722 ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 0));
725 window_->SetBounds(gfx::Rect(100, 200, 300, 20));
726 DCHECK_LT(window_->bounds().height(),
727 WorkspaceWindowResizer::kMinOnscreenHeight);
728 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
729 window_.get(), gfx::Point(), HTCAPTION,
730 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
731 ASSERT_TRUE(resizer.get());
732 resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
733 int expected_y = kRootHeight - window_->bounds().height() - 10;
734 // When the mouse cursor is in the primary display, the window cannot move
735 // on non-work area but can get all the way towards the bottom,
736 // restricted only by the window height.
737 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x20",
738 window_->bounds().ToString());
742 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
743 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
744 window_.get(), gfx::Point(), HTCAPTION,
745 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
746 ASSERT_TRUE(resizer.get());
747 resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
749 kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
750 // When the mouse cursor is in the primary display, the window cannot move
751 // on non-work area with kMinOnscreenHeight margin.
752 EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
753 window_->bounds().ToString());
757 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
758 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
759 window_.get(), gfx::Point(), HTCAPTION,
760 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
761 ASSERT_TRUE(resizer.get());
762 resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
763 // The window can move to the secondary display beyond non-work area of
764 // the primary display.
765 EXPECT_EQ("100,800 300x400", window_->bounds().ToString());
769 // Makes sure we don't allow dragging off the top of the work area.
770 TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) {
771 Shell::GetInstance()->SetDisplayWorkAreaInsets(
772 Shell::GetPrimaryRootWindow(), gfx::Insets(10, 0, 0, 0));
774 window_->SetBounds(gfx::Rect(100, 200, 300, 400));
775 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
776 window_.get(), gfx::Point(), HTCAPTION,
777 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
778 ASSERT_TRUE(resizer.get());
779 resizer->Drag(CalculateDragPoint(*resizer, 0, -600), 0);
780 EXPECT_EQ("100,10 300x400", window_->bounds().ToString());
783 TEST_F(WorkspaceWindowResizerTest, ResizeBottomOutsideWorkArea) {
784 Shell::GetInstance()->SetDisplayWorkAreaInsets(
785 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
787 window_->SetBounds(gfx::Rect(100, 200, 300, 380));
788 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
789 window_.get(), gfx::Point(), HTTOP,
790 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
791 ASSERT_TRUE(resizer.get());
792 resizer->Drag(CalculateDragPoint(*resizer, 8, 0), 0);
793 EXPECT_EQ("100,200 300x380", window_->bounds().ToString());
796 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideLeftWorkArea) {
797 Shell::GetInstance()->SetDisplayWorkAreaInsets(
798 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
799 int left = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).x();
800 int pixels_to_left_border = 50;
801 int window_width = 300;
802 int window_x = left - window_width + pixels_to_left_border;
803 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
804 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
805 window_.get(), gfx::Point(pixels_to_left_border, 0), HTRIGHT,
806 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
807 ASSERT_TRUE(resizer.get());
808 resizer->Drag(CalculateDragPoint(*resizer, -window_width, 0), 0);
809 EXPECT_EQ(base::IntToString(window_x) + ",100 " +
810 base::IntToString(kMinimumOnScreenArea - window_x) +
811 "x380", window_->bounds().ToString());
814 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
815 Shell::GetInstance()->SetDisplayWorkAreaInsets(
816 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
817 int right = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
818 window_.get()).right();
819 int pixels_to_right_border = 50;
820 int window_width = 300;
821 int window_x = right - pixels_to_right_border;
822 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
823 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
824 window_.get(), gfx::Point(window_x, 0), HTLEFT,
825 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
826 ASSERT_TRUE(resizer.get());
827 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
828 EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
830 base::IntToString(window_width - pixels_to_right_border +
831 kMinimumOnScreenArea) +
832 "x380", window_->bounds().ToString());
835 TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
836 Shell::GetInstance()->SetDisplayWorkAreaInsets(
837 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
838 int bottom = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
839 window_.get()).bottom();
840 int delta_to_bottom = 50;
842 window_->SetBounds(gfx::Rect(100, bottom - delta_to_bottom, 300, height));
843 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
844 window_.get(), gfx::Point(0, bottom - delta_to_bottom), HTTOP,
845 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
846 ASSERT_TRUE(resizer.get());
847 resizer->Drag(CalculateDragPoint(*resizer, 0, bottom), 0);
849 base::IntToString(bottom - kMinimumOnScreenArea) +
851 base::IntToString(height - (delta_to_bottom -
852 kMinimumOnScreenArea)),
853 window_->bounds().ToString());
856 // Verifies that 'outside' check of the resizer take into account the extended
857 // desktop in case of repositions.
858 TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
859 // Only primary display. Changes the window position to fit within the
861 Shell::GetInstance()->SetDisplayWorkAreaInsets(
862 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
863 int right = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
864 window_.get()).right();
865 int pixels_to_right_border = 50;
866 int window_width = 300;
867 int window_x = right - pixels_to_right_border;
868 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
869 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
870 window_.get(), gfx::Point(window_x, 0), HTCAPTION,
871 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
872 ASSERT_TRUE(resizer.get());
873 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
874 EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
876 base::IntToString(window_width) +
877 "x380", window_->bounds().ToString());
879 if (!SupportsMultipleDisplays())
882 // With secondary display. Operation itself is same but doesn't change
883 // the position because the window is still within the secondary display.
884 UpdateDisplay("1000x600,600x400");
885 Shell::GetInstance()->SetDisplayWorkAreaInsets(
886 Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
887 window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
888 resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
889 EXPECT_EQ(base::IntToString(window_x + window_width) +
891 base::IntToString(window_width) +
892 "x380", window_->bounds().ToString());
895 // Verifies snapping to edges works.
896 TEST_F(WorkspaceWindowResizerTest, SnapToEdge) {
897 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
898 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
899 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
900 // Click 50px to the right so that the mouse pointer does not leave the
901 // workspace ensuring sticky behavior.
902 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
904 window_->bounds().origin() + gfx::Vector2d(50, 0),
906 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
907 ASSERT_TRUE(resizer.get());
908 // Move to an x-coordinate of 15, which should not snap.
909 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
910 // An x-coordinate of 7 should snap.
911 resizer->Drag(CalculateDragPoint(*resizer, 7 - 96, 0), 0);
912 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
913 // Move to -15, should still snap to 0.
914 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
915 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
916 // At -32 should move past snap points.
917 resizer->Drag(CalculateDragPoint(*resizer, -32 - 96, 0), 0);
918 EXPECT_EQ("-32,112 320x160", window_->bounds().ToString());
919 resizer->Drag(CalculateDragPoint(*resizer, -33 - 96, 0), 0);
920 EXPECT_EQ("-33,112 320x160", window_->bounds().ToString());
922 // Right side should similarly snap.
923 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
924 EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
925 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 7, 0), 0);
926 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
927 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
928 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
929 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 32, 0), 0);
930 EXPECT_EQ("512,112 320x160", window_->bounds().ToString());
931 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 33, 0), 0);
932 EXPECT_EQ("513,112 320x160", window_->bounds().ToString());
934 // And the bottom should snap too.
935 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 - 7), 0);
936 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
937 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
938 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
939 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 32), 0);
940 EXPECT_EQ("96,470 320x160", window_->bounds().ToString());
941 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 33), 0);
942 EXPECT_EQ("96,471 320x160", window_->bounds().ToString());
944 // And the top should snap too.
945 resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 20), 0);
946 EXPECT_EQ("96,20 320x160", window_->bounds().ToString());
947 resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 7), 0);
948 EXPECT_EQ("96,0 320x160", window_->bounds().ToString());
950 // And bottom/left should snap too.
952 CalculateDragPoint(*resizer, 7 - 96, 600 - 160 - 112 - 3 - 7), 0);
953 EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
955 CalculateDragPoint(*resizer, -15 - 96, 600 - 160 - 112 - 3 + 15), 0);
956 EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
957 // should move past snap points.
959 CalculateDragPoint(*resizer, -32 - 96, 600 - 160 - 112 - 2 + 32), 0);
960 EXPECT_EQ("-32,470 320x160", window_->bounds().ToString());
962 CalculateDragPoint(*resizer, -33 - 96, 600 - 160 - 112 - 2 + 33), 0);
963 EXPECT_EQ("-33,471 320x160", window_->bounds().ToString());
965 // No need to test dragging < 0 as we force that to 0.
968 // Verifies a resize snap when dragging TOPLEFT.
969 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPLEFT) {
970 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
971 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
972 window_.get(), gfx::Point(), HTTOPLEFT,
973 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
974 ASSERT_TRUE(resizer.get());
975 resizer->Drag(CalculateDragPoint(*resizer, -98, -199), 0);
976 EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
979 // Verifies a resize snap when dragging TOPRIGHT.
980 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPRIGHT) {
981 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
982 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
984 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
985 window_.get(), gfx::Point(), HTTOPRIGHT,
986 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
987 ASSERT_TRUE(resizer.get());
989 CalculateDragPoint(*resizer, work_area.right() - 120 - 1, -199), 0);
990 EXPECT_EQ(100, window_->bounds().x());
991 EXPECT_EQ(work_area.y(), window_->bounds().y());
992 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
993 EXPECT_EQ(230, window_->bounds().height());
996 // Verifies a resize snap when dragging BOTTOMRIGHT.
997 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMRIGHT) {
998 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
999 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1001 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1002 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1003 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1004 ASSERT_TRUE(resizer.get());
1006 CalculateDragPoint(*resizer, work_area.right() - 120 - 1,
1007 work_area.bottom() - 220 - 2), 0);
1008 EXPECT_EQ(100, window_->bounds().x());
1009 EXPECT_EQ(200, window_->bounds().y());
1010 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1011 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1014 // Verifies a resize snap when dragging BOTTOMLEFT.
1015 TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMLEFT) {
1016 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1017 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1019 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1020 window_.get(), gfx::Point(), HTBOTTOMLEFT,
1021 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1022 ASSERT_TRUE(resizer.get());
1024 CalculateDragPoint(*resizer, -98, work_area.bottom() - 220 - 2), 0);
1025 EXPECT_EQ(0, window_->bounds().x());
1026 EXPECT_EQ(200, window_->bounds().y());
1027 EXPECT_EQ(120, window_->bounds().width());
1028 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1031 // Verifies sticking to edges works.
1032 TEST_F(WorkspaceWindowResizerTestSticky, StickToEdge) {
1033 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
1034 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1035 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1036 // Click 50px to the right so that the mouse pointer does not leave the
1037 // workspace ensuring sticky behavior.
1038 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1040 window_->bounds().origin() + gfx::Vector2d(50, 0),
1042 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1043 ASSERT_TRUE(resizer.get());
1044 // Move to an x-coordinate of 15, which should not stick.
1045 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1046 // Move to -15, should still stick to 0.
1047 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1048 EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1049 // At -100 should move past edge.
1050 resizer->Drag(CalculateDragPoint(*resizer, -100 - 96, 0), 0);
1051 EXPECT_EQ("-100,112 320x160", window_->bounds().ToString());
1052 resizer->Drag(CalculateDragPoint(*resizer, -101 - 96, 0), 0);
1053 EXPECT_EQ("-101,112 320x160", window_->bounds().ToString());
1055 // Right side should similarly stick.
1056 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
1057 EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
1058 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
1059 EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1060 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 100, 0), 0);
1061 EXPECT_EQ("580,112 320x160", window_->bounds().ToString());
1062 resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 101, 0), 0);
1063 EXPECT_EQ("581,112 320x160", window_->bounds().ToString());
1065 // And the bottom should stick too.
1066 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
1067 EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1068 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 100), 0);
1069 EXPECT_EQ("96,538 320x160", window_->bounds().ToString());
1070 resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 101), 0);
1071 EXPECT_EQ("96,539 320x160", window_->bounds().ToString());
1073 // No need to test dragging < 0 as we force that to 0.
1076 // Verifies not sticking to edges when a mouse pointer is outside of work area.
1077 TEST_F(WorkspaceWindowResizerTestSticky, NoStickToEdgeWhenOutside) {
1078 Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
1079 SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1080 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1081 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1082 window_.get(), gfx::Point(), HTCAPTION,
1083 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1084 ASSERT_TRUE(resizer.get());
1085 // Move to an x-coordinate of 15, which should not stick.
1086 resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1087 // Move to -15, should still stick to 0.
1088 resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1089 EXPECT_EQ("-15,112 320x160", window_->bounds().ToString());
1092 // Verifies a resize sticks when dragging TOPLEFT.
1093 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPLEFT) {
1094 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1095 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1096 window_.get(), gfx::Point(), HTTOPLEFT,
1097 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1098 ASSERT_TRUE(resizer.get());
1099 resizer->Drag(CalculateDragPoint(*resizer, -15 - 100, -15 -200), 0);
1100 EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
1103 // Verifies a resize sticks when dragging TOPRIGHT.
1104 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPRIGHT) {
1105 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1106 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1108 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1109 window_.get(), gfx::Point(), HTTOPRIGHT,
1110 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1111 ASSERT_TRUE(resizer.get());
1112 resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 + 20,
1114 EXPECT_EQ(100, window_->bounds().x());
1115 EXPECT_EQ(work_area.y(), window_->bounds().y());
1116 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1117 EXPECT_EQ(230, window_->bounds().height());
1120 // Verifies a resize snap when dragging BOTTOMRIGHT.
1121 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMRIGHT) {
1122 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1123 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1125 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1126 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1127 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1128 ASSERT_TRUE(resizer.get());
1129 resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 - 20 + 15,
1130 work_area.bottom() - 200 - 30 + 15), 0);
1131 EXPECT_EQ(100, window_->bounds().x());
1132 EXPECT_EQ(200, window_->bounds().y());
1133 EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1134 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1137 // Verifies a resize snap when dragging BOTTOMLEFT.
1138 TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMLEFT) {
1139 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1140 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1142 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1143 window_.get(), gfx::Point(), HTBOTTOMLEFT,
1144 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1145 ASSERT_TRUE(resizer.get());
1146 resizer->Drag(CalculateDragPoint(*resizer, -15 - 100,
1147 work_area.bottom() - 200 - 30 + 15), 0);
1148 EXPECT_EQ(0, window_->bounds().x());
1149 EXPECT_EQ(200, window_->bounds().y());
1150 EXPECT_EQ(120, window_->bounds().width());
1151 EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1154 TEST_F(WorkspaceWindowResizerTest, CtrlDragResizeToExactPosition) {
1155 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1156 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1157 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1158 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1159 ASSERT_TRUE(resizer.get());
1160 // Resize the right bottom to add 10 in width, 12 in height.
1161 resizer->Drag(CalculateDragPoint(*resizer, 10, 12), ui::EF_CONTROL_DOWN);
1162 // Both bottom and right sides to resize to exact size requested.
1163 EXPECT_EQ("96,112 330x172", window_->bounds().ToString());
1166 TEST_F(WorkspaceWindowResizerTest, CtrlCompleteDragMoveToExactPosition) {
1167 window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1168 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1169 window_.get(), gfx::Point(), HTCAPTION,
1170 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1171 ASSERT_TRUE(resizer.get());
1172 // Ctrl + drag the window to new poistion by adding (10, 12) to its origin,
1173 // the window should move to the exact position.
1174 resizer->Drag(CalculateDragPoint(*resizer, 10, 12), 0);
1175 resizer->CompleteDrag(ui::EF_CONTROL_DOWN);
1176 EXPECT_EQ("106,124 320x160", window_->bounds().ToString());
1179 // Verifies that a dragged window will restore to its pre-maximized size.
1180 TEST_F(WorkspaceWindowResizerTest, RestoreToPreMaximizeCoordinates) {
1181 window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
1182 wm::WindowState* window_state = wm::GetWindowState(window_.get());
1183 window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1184 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1185 window_.get(), gfx::Point(), HTCAPTION,
1186 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1187 ASSERT_TRUE(resizer.get());
1188 // Drag the window to new position by adding (10, 10) to original point,
1189 // the window should get restored.
1190 resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
1191 resizer->CompleteDrag(0);
1192 EXPECT_EQ("10,10 320x160", window_->bounds().ToString());
1193 // The restore rectangle should get cleared as well.
1194 EXPECT_FALSE(window_state->HasRestoreBounds());
1197 // Verifies that a dragged window will restore to its pre-maximized size.
1198 TEST_F(WorkspaceWindowResizerTest, RevertResizeOperation) {
1199 const gfx::Rect initial_bounds(0, 0, 200, 400);
1200 window_->SetBounds(initial_bounds);
1202 wm::WindowState* window_state = wm::GetWindowState(window_.get());
1203 window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1204 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1205 window_.get(), gfx::Point(), HTCAPTION,
1206 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1207 ASSERT_TRUE(resizer.get());
1208 // Drag the window to new poistion by adding (180, 16) to original point,
1209 // the window should get restored.
1210 resizer->Drag(CalculateDragPoint(*resizer, 180, 16), 0);
1211 resizer->RevertDrag();
1212 EXPECT_EQ(initial_bounds.ToString(), window_->bounds().ToString());
1213 EXPECT_EQ("96,112 320x160",
1214 window_state->GetRestoreBoundsInScreen().ToString());
1217 // Check that only usable sizes get returned by the resizer.
1218 TEST_F(WorkspaceWindowResizerTest, MagneticallyAttach) {
1219 window_->SetBounds(gfx::Rect(10, 10, 20, 30));
1220 window2_->SetBounds(gfx::Rect(150, 160, 25, 20));
1223 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1224 window_.get(), gfx::Point(), HTCAPTION,
1225 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1226 ASSERT_TRUE(resizer.get());
1227 // Move |window| one pixel to the left of |window2|. Should snap to right and
1229 resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
1230 EXPECT_EQ("130,160 20x30", window_->bounds().ToString());
1232 // Move |window| one pixel to the right of |window2|. Should snap to left and
1234 resizer->Drag(CalculateDragPoint(*resizer, 164, 145), 0);
1235 EXPECT_EQ("175,160 20x30", window_->bounds().ToString());
1237 // Move |window| one pixel above |window2|. Should snap to top and left.
1238 resizer->Drag(CalculateDragPoint(*resizer, 142, 119), 0);
1239 EXPECT_EQ("150,130 20x30", window_->bounds().ToString());
1241 // Move |window| one pixel above the bottom of |window2|. Should snap to
1243 resizer->Drag(CalculateDragPoint(*resizer, 142, 169), 0);
1244 EXPECT_EQ("150,180 20x30", window_->bounds().ToString());
1247 // The following variants verify magnetic snapping during resize when dragging a
1249 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOP) {
1250 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1251 window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
1254 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1255 window_.get(), gfx::Point(), HTTOP,
1256 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1257 ASSERT_TRUE(resizer.get());
1258 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1259 EXPECT_EQ("100,199 20x31", window_->bounds().ToString());
1262 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPLEFT) {
1263 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1264 window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
1268 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1269 window_.get(), gfx::Point(), HTTOPLEFT,
1270 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1271 ASSERT_TRUE(resizer.get());
1272 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1273 EXPECT_EQ("99,199 21x31", window_->bounds().ToString());
1274 resizer->RevertDrag();
1278 window2_->SetBounds(gfx::Rect(88, 201, 10, 20));
1279 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1280 window_.get(), gfx::Point(), HTTOPLEFT,
1281 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1282 ASSERT_TRUE(resizer.get());
1283 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1284 EXPECT_EQ("98,201 22x29", window_->bounds().ToString());
1285 resizer->RevertDrag();
1289 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPRIGHT) {
1290 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1294 window2_->SetBounds(gfx::Rect(111, 179, 10, 20));
1295 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1296 window_.get(), gfx::Point(), HTTOPRIGHT,
1297 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
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<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1307 window_.get(), gfx::Point(), HTTOPRIGHT,
1308 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1309 ASSERT_TRUE(resizer.get());
1310 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1311 EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
1312 resizer->RevertDrag();
1316 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_RIGHT) {
1317 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1318 window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
1321 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1322 window_.get(), gfx::Point(), HTRIGHT,
1323 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1324 ASSERT_TRUE(resizer.get());
1325 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1326 EXPECT_EQ("100,200 21x30", window_->bounds().ToString());
1329 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMRIGHT) {
1330 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1334 window2_->SetBounds(gfx::Rect(122, 212, 10, 20));
1335 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1336 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1337 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1338 ASSERT_TRUE(resizer.get());
1339 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1340 EXPECT_EQ("100,200 22x32", window_->bounds().ToString());
1341 resizer->RevertDrag();
1345 window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1346 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1347 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1348 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1349 ASSERT_TRUE(resizer.get());
1350 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1351 EXPECT_EQ("100,200 21x33", window_->bounds().ToString());
1352 resizer->RevertDrag();
1356 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOM) {
1357 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1358 window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1361 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1362 window_.get(), gfx::Point(), HTBOTTOM,
1363 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1364 ASSERT_TRUE(resizer.get());
1365 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1366 EXPECT_EQ("100,200 20x33", window_->bounds().ToString());
1369 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMLEFT) {
1370 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1374 window2_->SetBounds(gfx::Rect(99, 231, 10, 20));
1375 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1376 window_.get(), gfx::Point(), HTBOTTOMLEFT,
1377 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1378 ASSERT_TRUE(resizer.get());
1379 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1380 EXPECT_EQ("99,200 21x31", window_->bounds().ToString());
1381 resizer->RevertDrag();
1385 window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1386 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1387 window_.get(), gfx::Point(), HTBOTTOMLEFT,
1388 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1389 ASSERT_TRUE(resizer.get());
1390 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1391 EXPECT_EQ("99,200 21x29", window_->bounds().ToString());
1392 resizer->RevertDrag();
1396 TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_LEFT) {
1397 window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1398 window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1401 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1402 window_.get(), gfx::Point(), HTLEFT,
1403 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1404 ASSERT_TRUE(resizer.get());
1405 resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
1406 EXPECT_EQ("99,200 21x30", window_->bounds().ToString());
1409 // Test that the user user moved window flag is getting properly set.
1410 TEST_F(WorkspaceWindowResizerTest, CheckUserWindowMangedFlags) {
1411 window_->SetBounds(gfx::Rect( 0, 50, 400, 200));
1413 std::vector<aura::Window*> no_attached_windows;
1414 // Check that an abort doesn't change anything.
1416 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1417 window_.get(), gfx::Point(), HTCAPTION,
1418 aura::client::WINDOW_MOVE_SOURCE_MOUSE, no_attached_windows));
1419 ASSERT_TRUE(resizer.get());
1420 // Move it 100 to the bottom.
1421 resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
1422 EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
1423 resizer->RevertDrag();
1425 EXPECT_FALSE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
1428 // Check that a completed move / size does change the user coordinates.
1430 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1431 window_.get(), gfx::Point(), HTCAPTION,
1432 aura::client::WINDOW_MOVE_SOURCE_MOUSE, no_attached_windows));
1433 ASSERT_TRUE(resizer.get());
1434 // Move it 100 to the bottom.
1435 resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
1436 EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
1437 resizer->CompleteDrag(0);
1438 EXPECT_TRUE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
1442 // Test that a window with a specified max size doesn't exceed it when dragged.
1443 TEST_F(WorkspaceWindowResizerTest, TestMaxSizeEnforced) {
1444 window_->SetBounds(gfx::Rect(0, 0, 400, 300));
1445 delegate_.set_max_size(gfx::Size(401, 301));
1447 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1448 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1449 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1450 resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
1451 EXPECT_EQ(401, window_->bounds().width());
1452 EXPECT_EQ(301, window_->bounds().height());
1455 // Test that a window with a specified max width doesn't restrict its height.
1456 TEST_F(WorkspaceWindowResizerTest, TestPartialMaxSizeEnforced) {
1457 window_->SetBounds(gfx::Rect(0, 0, 400, 300));
1458 delegate_.set_max_size(gfx::Size(401, 0));
1460 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1461 window_.get(), gfx::Point(), HTBOTTOMRIGHT,
1462 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1463 resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
1464 EXPECT_EQ(401, window_->bounds().width());
1465 EXPECT_EQ(302, window_->bounds().height());
1468 // Test that a window with a specified max size can't be snapped.
1469 TEST_F(WorkspaceWindowResizerTest, PhantomSnapMaxSize) {
1471 // With max size not set we get a phantom window controller for dragging off
1472 // the right hand side.
1473 window_->SetBounds(gfx::Rect(0, 0, 300, 200));
1475 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1476 window_.get(), gfx::Point(), HTCAPTION,
1477 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1478 EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
1479 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1480 EXPECT_TRUE(resizer->snap_phantom_window_controller_.get());
1483 // With max size defined, we get no phantom window.
1484 window_->SetBounds(gfx::Rect(0, 0, 300, 200));
1485 delegate_.set_max_size(gfx::Size(300, 200));
1487 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1488 window_.get(), gfx::Point(), HTCAPTION,
1489 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1490 resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1491 EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
1495 TEST_F(WorkspaceWindowResizerTest, DontRewardRightmostWindowForOverflows) {
1496 UpdateDisplay("600x800");
1497 aura::Window* root = Shell::GetPrimaryRootWindow();
1498 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1500 // Four 100x100 windows flush against eachother, starting at 100,100.
1501 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1502 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1503 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1504 window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
1505 delegate2_.set_max_size(gfx::Size(101, 0));
1507 std::vector<aura::Window*> windows;
1508 windows.push_back(window2_.get());
1509 windows.push_back(window3_.get());
1510 windows.push_back(window4_.get());
1511 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1512 window_.get(), gfx::Point(), HTRIGHT,
1513 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1514 ASSERT_TRUE(resizer.get());
1515 // Move it 51 to the left, which should contract w1 and expand w2-4.
1516 // w2 will hit its max size straight away, and in doing so will leave extra
1517 // pixels that a naive implementation may award to the rightmost window. A
1518 // fair implementation will give 25 pixels to each of the other windows.
1519 resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
1520 EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
1521 EXPECT_EQ("149,100 101x100", window2_->bounds().ToString());
1522 EXPECT_EQ("250,100 125x100", window3_->bounds().ToString());
1523 EXPECT_EQ("375,100 125x100", window4_->bounds().ToString());
1526 TEST_F(WorkspaceWindowResizerTest, DontExceedMaxWidth) {
1527 UpdateDisplay("600x800");
1528 aura::Window* root = Shell::GetPrimaryRootWindow();
1529 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1531 // Four 100x100 windows flush against eachother, starting at 100,100.
1532 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1533 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1534 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1535 window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
1536 delegate2_.set_max_size(gfx::Size(101, 0));
1537 delegate3_.set_max_size(gfx::Size(101, 0));
1539 std::vector<aura::Window*> windows;
1540 windows.push_back(window2_.get());
1541 windows.push_back(window3_.get());
1542 windows.push_back(window4_.get());
1543 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1544 window_.get(), gfx::Point(), HTRIGHT,
1545 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1546 ASSERT_TRUE(resizer.get());
1547 // Move it 52 to the left, which should contract w1 and expand w2-4.
1548 resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
1549 EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
1550 EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
1551 EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
1552 EXPECT_EQ("350,100 150x100", window4_->bounds().ToString());
1555 TEST_F(WorkspaceWindowResizerTest, DontExceedMaxHeight) {
1556 UpdateDisplay("600x800");
1557 aura::Window* root = Shell::GetPrimaryRootWindow();
1558 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1560 // Four 100x100 windows flush against eachother, starting at 100,100.
1561 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1562 window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
1563 window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
1564 window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
1565 delegate2_.set_max_size(gfx::Size(0, 101));
1566 delegate3_.set_max_size(gfx::Size(0, 101));
1568 std::vector<aura::Window*> windows;
1569 windows.push_back(window2_.get());
1570 windows.push_back(window3_.get());
1571 windows.push_back(window4_.get());
1572 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1573 window_.get(), gfx::Point(), HTBOTTOM,
1574 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1575 ASSERT_TRUE(resizer.get());
1576 // Move it 52 up, which should contract w1 and expand w2-4.
1577 resizer->Drag(CalculateDragPoint(*resizer, 0, -52), 0);
1578 EXPECT_EQ("100,100 100x48", window_->bounds().ToString());
1579 EXPECT_EQ("100,148 100x101", window2_->bounds().ToString());
1580 EXPECT_EQ("100,249 100x101", window3_->bounds().ToString());
1581 EXPECT_EQ("100,350 100x150", window4_->bounds().ToString());
1585 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1586 #define MAYBE_DontExceedMinHeight DISABLED_DontExceedMinHeight
1588 #define MAYBE_DontExceedMinHeight DontExceedMinHeight
1591 TEST_F(WorkspaceWindowResizerTest, MAYBE_DontExceedMinHeight) {
1592 UpdateDisplay("600x500");
1593 aura::Window* root = Shell::GetPrimaryRootWindow();
1594 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1596 // Four 100x100 windows flush against eachother, starting at 100,100.
1597 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1598 window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
1599 window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
1600 window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
1601 delegate2_.set_min_size(gfx::Size(0, 99));
1602 delegate3_.set_min_size(gfx::Size(0, 99));
1604 std::vector<aura::Window*> windows;
1605 windows.push_back(window2_.get());
1606 windows.push_back(window3_.get());
1607 windows.push_back(window4_.get());
1608 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1609 window_.get(), gfx::Point(), HTBOTTOM,
1610 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1611 ASSERT_TRUE(resizer.get());
1612 // Move it 52 down, which should expand w1 and contract w2-4.
1613 resizer->Drag(CalculateDragPoint(*resizer, 0, 52), 0);
1614 EXPECT_EQ("100,100 100x152", window_->bounds().ToString());
1615 EXPECT_EQ("100,252 100x99", window2_->bounds().ToString());
1616 EXPECT_EQ("100,351 100x99", window3_->bounds().ToString());
1617 EXPECT_EQ("100,450 100x50", window4_->bounds().ToString());
1620 TEST_F(WorkspaceWindowResizerTest, DontExpandRightmostPastMaxWidth) {
1621 UpdateDisplay("600x800");
1622 aura::Window* root = Shell::GetPrimaryRootWindow();
1623 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1625 // Three 100x100 windows flush against eachother, starting at 100,100.
1626 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1627 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1628 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1629 delegate3_.set_max_size(gfx::Size(101, 0));
1631 std::vector<aura::Window*> windows;
1632 windows.push_back(window2_.get());
1633 windows.push_back(window3_.get());
1634 windows.push_back(window4_.get());
1635 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1636 window_.get(), gfx::Point(), HTRIGHT,
1637 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1638 ASSERT_TRUE(resizer.get());
1639 // Move it 51 to the left, which should contract w1 and expand w2-3.
1640 resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
1641 EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
1642 EXPECT_EQ("149,100 150x100", window2_->bounds().ToString());
1643 EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
1646 TEST_F(WorkspaceWindowResizerTest, MoveAttachedWhenGrownToMaxSize) {
1647 UpdateDisplay("600x800");
1648 aura::Window* root = Shell::GetPrimaryRootWindow();
1649 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1651 // Three 100x100 windows flush against eachother, starting at 100,100.
1652 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1653 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1654 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1655 delegate2_.set_max_size(gfx::Size(101, 0));
1656 delegate3_.set_max_size(gfx::Size(101, 0));
1658 std::vector<aura::Window*> windows;
1659 windows.push_back(window2_.get());
1660 windows.push_back(window3_.get());
1661 windows.push_back(window4_.get());
1662 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1663 window_.get(), gfx::Point(), HTRIGHT,
1664 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1665 ASSERT_TRUE(resizer.get());
1666 // Move it 52 to the left, which should contract w1 and expand and move w2-3.
1667 resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
1668 EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
1669 EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
1670 EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
1674 // RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
1675 #define MAYBE_MainWindowHonoursMaxWidth DISABLED_MainWindowHonoursMaxWidth
1677 #define MAYBE_MainWindowHonoursMaxWidth MainWindowHonoursMaxWidth
1680 TEST_F(WorkspaceWindowResizerTest, MAYBE_MainWindowHonoursMaxWidth) {
1681 UpdateDisplay("400x800");
1682 aura::Window* root = Shell::GetPrimaryRootWindow();
1683 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1685 // Three 100x100 windows flush against eachother, starting at 100,100.
1686 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1687 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1688 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1689 delegate_.set_max_size(gfx::Size(102, 0));
1691 std::vector<aura::Window*> windows;
1692 windows.push_back(window2_.get());
1693 windows.push_back(window3_.get());
1694 windows.push_back(window4_.get());
1695 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1696 window_.get(), gfx::Point(), HTRIGHT,
1697 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1698 ASSERT_TRUE(resizer.get());
1699 // Move it 50 to the right, which should expand w1 and contract w2-3, as they
1700 // won't fit in the root window in their original sizes.
1701 resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
1702 EXPECT_EQ("100,100 102x100", window_->bounds().ToString());
1703 EXPECT_EQ("202,100 99x100", window2_->bounds().ToString());
1704 EXPECT_EQ("301,100 99x100", window3_->bounds().ToString());
1707 TEST_F(WorkspaceWindowResizerTest, MainWindowHonoursMinWidth) {
1708 UpdateDisplay("400x800");
1709 aura::Window* root = Shell::GetPrimaryRootWindow();
1710 Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1712 // Three 100x100 windows flush against eachother, starting at 100,100.
1713 window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
1714 window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
1715 window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
1716 delegate_.set_min_size(gfx::Size(98, 0));
1718 std::vector<aura::Window*> windows;
1719 windows.push_back(window2_.get());
1720 windows.push_back(window3_.get());
1721 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1722 window_.get(), gfx::Point(), HTRIGHT,
1723 aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
1724 ASSERT_TRUE(resizer.get());
1725 // Move it 50 to the left, which should contract w1 and expand w2-3.
1726 resizer->Drag(CalculateDragPoint(*resizer, -50, 0), 0);
1727 EXPECT_EQ("100,100 98x100", window_->bounds().ToString());
1728 EXPECT_EQ("198,100 101x100", window2_->bounds().ToString());
1729 EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
1732 // The following variants test that windows are resized correctly to the edges
1733 // of the screen using touch, when touch point is off of the window border.
1734 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_RIGHT) {
1735 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1737 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTRIGHT);
1738 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1739 touch_resize_window_->bounds().ToString());
1741 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1742 touch_resize_window_.get());
1744 // Drag out of the right border a bit and check if the border is aligned with
1746 generator.GestureScrollSequence(gfx::Point(715, kRootHeight / 2),
1747 gfx::Point(725, kRootHeight / 2),
1748 base::TimeDelta::FromMilliseconds(10),
1750 EXPECT_EQ(gfx::Rect(100, 100, 625, kRootHeight - 200).ToString(),
1751 touch_resize_window_->bounds().ToString());
1752 // Drag more, but stop before being snapped to the edge.
1753 generator.GestureScrollSequence(gfx::Point(725, kRootHeight / 2),
1754 gfx::Point(760, kRootHeight / 2),
1755 base::TimeDelta::FromMilliseconds(10),
1757 EXPECT_EQ(gfx::Rect(100, 100, 660, kRootHeight - 200).ToString(),
1758 touch_resize_window_->bounds().ToString());
1759 // Drag even more to snap to the edge.
1760 generator.GestureScrollSequence(gfx::Point(760, kRootHeight / 2),
1761 gfx::Point(775, kRootHeight / 2),
1762 base::TimeDelta::FromMilliseconds(10),
1764 EXPECT_EQ(gfx::Rect(100, 100, 700, kRootHeight - 200).ToString(),
1765 touch_resize_window_->bounds().ToString());
1768 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_LEFT) {
1769 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1771 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTLEFT);
1772 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1773 touch_resize_window_->bounds().ToString());
1775 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1776 touch_resize_window_.get());
1778 // Drag out of the left border a bit and check if the border is aligned with
1780 generator.GestureScrollSequence(gfx::Point(85, kRootHeight / 2),
1781 gfx::Point(75, kRootHeight / 2),
1782 base::TimeDelta::FromMilliseconds(10),
1784 EXPECT_EQ(gfx::Rect(75, 100, 625, kRootHeight - 200).ToString(),
1785 touch_resize_window_->bounds().ToString());
1786 // Drag more, but stop before being snapped to the edge.
1787 generator.GestureScrollSequence(gfx::Point(75, kRootHeight / 2),
1788 gfx::Point(40, kRootHeight / 2),
1789 base::TimeDelta::FromMilliseconds(10),
1791 EXPECT_EQ(gfx::Rect(40, 100, 660, kRootHeight - 200).ToString(),
1792 touch_resize_window_->bounds().ToString());
1793 // Drag even more to snap to the edge.
1794 generator.GestureScrollSequence(gfx::Point(40, kRootHeight / 2),
1795 gfx::Point(25, kRootHeight / 2),
1796 base::TimeDelta::FromMilliseconds(10),
1798 EXPECT_EQ(gfx::Rect(0, 100, 700, kRootHeight - 200).ToString(),
1799 touch_resize_window_->bounds().ToString());
1802 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_TOP) {
1803 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1805 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTTOP);
1806 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1807 touch_resize_window_->bounds().ToString());
1809 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1810 touch_resize_window_.get());
1812 // Drag out of the top border a bit and check if the border is aligned with
1814 generator.GestureScrollSequence(gfx::Point(400, 85),
1815 gfx::Point(400, 75),
1816 base::TimeDelta::FromMilliseconds(10),
1818 EXPECT_EQ(gfx::Rect(100, 75, 600, kRootHeight - 175).ToString(),
1819 touch_resize_window_->bounds().ToString());
1820 // Drag more, but stop before being snapped to the edge.
1821 generator.GestureScrollSequence(gfx::Point(400, 75),
1822 gfx::Point(400, 40),
1823 base::TimeDelta::FromMilliseconds(10),
1825 EXPECT_EQ(gfx::Rect(100, 40, 600, kRootHeight - 140).ToString(),
1826 touch_resize_window_->bounds().ToString());
1827 // Drag even more to snap to the edge.
1828 generator.GestureScrollSequence(gfx::Point(400, 40),
1829 gfx::Point(400, 25),
1830 base::TimeDelta::FromMilliseconds(10),
1832 EXPECT_EQ(gfx::Rect(100, 0, 600, kRootHeight - 100).ToString(),
1833 touch_resize_window_->bounds().ToString());
1836 TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
1837 shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
1839 InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTBOTTOM);
1840 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
1841 touch_resize_window_->bounds().ToString());
1843 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
1844 touch_resize_window_.get());
1846 // Drag out of the bottom border a bit and check if the border is aligned with
1848 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 85),
1849 gfx::Point(400, kRootHeight - 75),
1850 base::TimeDelta::FromMilliseconds(10),
1852 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 175).ToString(),
1853 touch_resize_window_->bounds().ToString());
1854 // Drag more, but stop before being snapped to the edge.
1855 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 75),
1856 gfx::Point(400, kRootHeight - 40),
1857 base::TimeDelta::FromMilliseconds(10),
1859 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 140).ToString(),
1860 touch_resize_window_->bounds().ToString());
1861 // Drag even more to snap to the edge.
1862 generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 40),
1863 gfx::Point(400, kRootHeight - 25),
1864 base::TimeDelta::FromMilliseconds(10),
1866 EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 100).ToString(),
1867 touch_resize_window_->bounds().ToString());
1870 TEST_F(WorkspaceWindowResizerTest, PhantomWindowShow) {
1871 if (!SupportsMultipleDisplays())
1874 UpdateDisplay("500x400,500x400");
1875 window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
1876 Shell::GetScreen()->GetPrimaryDisplay());
1877 Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
1878 EXPECT_EQ(root_windows[0], window_->GetRootWindow());
1880 scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
1881 window_.get(), gfx::Point(0,0), HTCAPTION,
1882 aura::client::WINDOW_MOVE_SOURCE_MOUSE, empty_windows()));
1883 ASSERT_TRUE(resizer.get());
1884 EXPECT_FALSE(resizer->snap_phantom_window_controller_.get());
1886 // The pointer is on the edge but not shared. The snap phantom window
1887 // controller should be non-NULL.
1888 resizer->Drag(CalculateDragPoint(*resizer, -1, 0), 0);
1889 EXPECT_TRUE(resizer->snap_phantom_window_controller_.get());
1890 PhantomWindowController* phantom_controller(
1891 resizer->snap_phantom_window_controller_.get());
1893 // phantom widget only in the left screen.
1894 phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
1895 EXPECT_TRUE(phantom_controller->phantom_widget_);
1896 EXPECT_FALSE(phantom_controller->phantom_widget_start_);
1899 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1901 // Move phantom widget into the right screen. Test that 2 widgets got created.
1902 phantom_controller->Show(gfx::Rect(600, 100, 50, 60));
1903 EXPECT_TRUE(phantom_controller->phantom_widget_);
1904 EXPECT_TRUE(phantom_controller->phantom_widget_start_);
1907 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1910 phantom_controller->phantom_widget_start_->GetNativeWindow()->
1912 RunAnimationTillComplete(phantom_controller->animation_.get());
1914 // Move phantom widget only in the right screen. Start widget should close.
1915 phantom_controller->Show(gfx::Rect(700, 100, 50, 60));
1916 EXPECT_TRUE(phantom_controller->phantom_widget_);
1917 EXPECT_FALSE(phantom_controller->phantom_widget_start_);
1920 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1921 RunAnimationTillComplete(phantom_controller->animation_.get());
1923 // Move phantom widget into the left screen. Start widget should open.
1924 phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
1925 EXPECT_TRUE(phantom_controller->phantom_widget_);
1926 EXPECT_TRUE(phantom_controller->phantom_widget_start_);
1929 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1932 phantom_controller->phantom_widget_start_->GetNativeWindow()->
1934 RunAnimationTillComplete(phantom_controller->animation_.get());
1936 // Move phantom widget while in the left screen. Start widget should close.
1937 phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
1938 EXPECT_TRUE(phantom_controller->phantom_widget_);
1939 EXPECT_FALSE(phantom_controller->phantom_widget_start_);
1942 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1943 RunAnimationTillComplete(phantom_controller->animation_.get());
1945 // Move phantom widget spanning both screens with most of the window in the
1946 // right screen. Two widgets are created.
1947 phantom_controller->Show(gfx::Rect(495, 100, 50, 60));
1948 EXPECT_TRUE(phantom_controller->phantom_widget_);
1949 EXPECT_TRUE(phantom_controller->phantom_widget_start_);
1952 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1955 phantom_controller->phantom_widget_start_->GetNativeWindow()->
1957 RunAnimationTillComplete(phantom_controller->animation_.get());
1959 // Move phantom widget back into the left screen. Phantom widgets should swap.
1960 phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
1961 EXPECT_TRUE(phantom_controller->phantom_widget_);
1962 EXPECT_TRUE(phantom_controller->phantom_widget_start_);
1965 phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
1968 phantom_controller->phantom_widget_start_->GetNativeWindow()->
1970 RunAnimationTillComplete(phantom_controller->animation_.get());
1972 // Hide phantom controller. Both widgets should close.
1973 phantom_controller->Hide();
1974 EXPECT_FALSE(phantom_controller->phantom_widget_);
1975 EXPECT_FALSE(phantom_controller->phantom_widget_start_);
1978 } // namespace internal