workspace_window_resizer_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/workspace/workspace_window_resizer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ash/ash_constants.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/ash_switches.h"
98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ash/display/display_manager.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/root_window_controller.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/screen_ash.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell_window_ids.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/test/ash_test_base.h"
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/workspace/phantom_window_controller.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/workspace/snap_sizer.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/workspace_controller.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h"
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/aura/test/event_generator.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/insets.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace gfx {
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Class to provide access to SlideAnimation internals for testing.
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// TODO: this should be next to SlideAnimation, not here.
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class SlideAnimation::TestApi {
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit TestApi(SlideAnimation* animation) : animation_(animation) {}
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void SetStartTime(base::TimeTicks ticks) {
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    animation_->SetStartTime(ticks);
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void Step(base::TimeTicks ticks) {
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    animation_->Step(ticks);
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void RunTillComplete() {
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    SetStartTime(base::TimeTicks());
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Step(base::TimeTicks() +
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         base::TimeDelta::FromMilliseconds(animation_->GetSlideDuration()));
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    EXPECT_EQ(1.0, animation_->GetCurrentValue());
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SlideAnimation* animation_;
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestApi);
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kRootHeight = 600;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple window delegate that returns the specified min size.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestWindowDelegate : public aura::test::TestWindowDelegate {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestWindowDelegate() {}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_min_size(const gfx::Size& size) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    min_size_ = size;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_max_size(const gfx::Size& size) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    max_size_ = size;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from aura::Test::TestWindowDelegate:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual gfx::Size GetMinimumSize() const OVERRIDE {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return min_size_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual gfx::Size GetMaximumSize() const OVERRIDE {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return max_size_;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size min_size_;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Size max_size_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WorkspaceWindowResizerTest : public test::AshTestBase {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WorkspaceWindowResizerTest() : workspace_resizer_(NULL) {}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WorkspaceWindowResizerTest() {}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AshTestBase::SetUp();
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateDisplay(base::StringPrintf("800x%d", kRootHeight));
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* root = Shell::GetPrimaryRootWindow();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect root_bounds(root->bounds());
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // RootWindow and Display can't resize on Windows Ash.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // http://crbug.com/165962
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kRootHeight, root_bounds.height());
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(800, root_bounds.width());
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_.reset(new aura::Window(&delegate_));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->SetType(aura::client::WINDOW_TYPE_NORMAL);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->Init(ui::LAYER_NOT_DRAWN);
1241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ParentWindowInPrimaryRootWindow(window_.get());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->set_id(1);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_.reset(new aura::Window(&delegate2_));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetType(aura::client::WINDOW_TYPE_NORMAL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->Init(ui::LAYER_NOT_DRAWN);
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ParentWindowInPrimaryRootWindow(window2_.get());
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->set_id(2);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window3_.reset(new aura::Window(&delegate3_));
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window3_->SetType(aura::client::WINDOW_TYPE_NORMAL);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window3_->Init(ui::LAYER_NOT_DRAWN);
1361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ParentWindowInPrimaryRootWindow(window3_.get());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window3_->set_id(3);
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window4_.reset(new aura::Window(&delegate4_));
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window4_->SetType(aura::client::WINDOW_TYPE_NORMAL);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window4_->Init(ui::LAYER_NOT_DRAWN);
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    ParentWindowInPrimaryRootWindow(window4_.get());
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window4_->set_id(4);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_.reset();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_.reset();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window3_.reset();
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    window4_.reset();
1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    touch_resize_window_.reset();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AshTestBase::TearDown();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a string identifying the z-order of each of the known child windows
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of |parent|.  The returned string constains the id of the known windows and
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is ordered from topmost to bottomost windows.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string WindowOrderAsString(aura::Window* parent) const {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string result;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const aura::Window::Windows& windows = parent->children();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (aura::Window::Windows::const_reverse_iterator i = windows.rbegin();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         i != windows.rend(); ++i) {
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if (*i == window_ || *i == window2_ || *i == window3_) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!result.empty())
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          result += " ";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        result += base::IntToString((*i)->id());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WindowResizer* CreateResizerForTest(
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      aura::Window* window,
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const gfx::Point& point_in_parent,
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      int window_component) {
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    WindowResizer* resizer = CreateWindowResizer(
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window,
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        point_in_parent,
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_component,
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        aura::client::WINDOW_MOVE_SOURCE_MOUSE).release();
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    workspace_resizer_ = WorkspaceWindowResizer::instance_;
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return resizer;
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PhantomWindowController* snap_phantom_window_controller() const {
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return workspace_resizer_->snap_phantom_window_controller_.get();
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point CalculateDragPoint(const WindowResizer& resizer,
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int delta_x,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int delta_y) const {
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    gfx::Point location = resizer.GetInitialLocation();
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location.set_x(location.x() + delta_x);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    location.set_y(location.y() + delta_y);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return location;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> empty_windows() const {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::vector<aura::Window*>();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::ShelfLayoutManager* shelf_layout_manager() {
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void InitTouchResizeWindow(const gfx::Rect& bounds, int window_component) {
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    touch_resize_delegate_.set_window_component(window_component);
2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    touch_resize_window_.reset(
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        CreateTestWindowInShellWithDelegate(&touch_resize_delegate_, 0,
2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                            bounds));
2128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    gfx::Insets mouse_outer_insets(-ash::kResizeOutsideBoundsSize,
2138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                   -ash::kResizeOutsideBoundsSize,
2148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                   -ash::kResizeOutsideBoundsSize,
2158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                   -ash::kResizeOutsideBoundsSize);
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gfx::Insets touch_outer_insets = mouse_outer_insets.Scale(
2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ash::kResizeOutsideBoundsScaleForTouch);
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    touch_resize_window_->SetHitTestBoundsOverrideOuter(mouse_outer_insets,
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                        touch_outer_insets);
2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Simulate running the animation.
223d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void RunAnimationTillComplete(gfx::SlideAnimation* animation) {
224d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    gfx::SlideAnimation::TestApi test_api(animation);
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    test_api.RunTillComplete();
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate delegate_;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate delegate2_;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate delegate3_;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestWindowDelegate delegate4_;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window_;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window2_;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window3_;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window4_;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TestWindowDelegate touch_resize_delegate_;
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<aura::Window> touch_resize_window_;
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WorkspaceWindowResizer* workspace_resizer_;
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTest);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class WorkspaceWindowResizerTestSticky : public WorkspaceWindowResizerTest {
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  WorkspaceWindowResizerTestSticky() {}
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~WorkspaceWindowResizerTestSticky() {}
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ash::switches::kAshEnableStickyEdges);
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    WorkspaceWindowResizerTest::SetUp();
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(WorkspaceWindowResizerTestSticky);
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around attached window resize dragging from the right with 2
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// windows.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_2) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(0, 300, 400, 300));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 to the right, which should expand w1 and push w2.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Push off the screen, w2 should be resized to its min.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2_.set_min_size(gfx::Size(20, 20));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 780x300", window_->bounds().ToString());
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("780,200 20x200", window2_->bounds().ToString());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move back to 100 and verify w2 gets its original size.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revert and make sure everything moves back.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->RevertDrag();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 400x300", window_->bounds().ToString());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,200 100x200", window2_->bounds().ToString());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around collapsing and expanding.
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_Compress) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(   0, 300, 400, 300));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
3037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 to the left, which should expand w2 and collapse w1.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -100, 10), 0);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collapse all the way to w1's min.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_.set_min_size(gfx::Size(20, 20));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -800, 20), 0);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 20x300", window_->bounds().ToString());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,200 480x200", window2_->bounds().ToString());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move 100 to the left.
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 500x300", window_->bounds().ToString());
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("500,200 100x200", window2_->bounds().ToString());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Back to -100.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -100, 20), 0);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,300 300x300", window_->bounds().ToString());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,200 200x200", window2_->bounds().ToString());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around attached window resize dragging from the right with 3
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// windows.
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3) {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(300, 300, 150, 200));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2_.set_min_size(gfx::Size(52, 50));
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate3_.set_min_size(gfx::Size(38, 50));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window3_.get());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 to the right, which should expand w1 and push w2 and w3.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,300 150x200", window2_->bounds().ToString());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("550,300 100x200", window3_->bounds().ToString());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 300, things should compress.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 300, -10), 0);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 500x300", window_->bounds().ToString());
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("600,300 120x200", window2_->bounds().ToString());
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("720,300 80x200", window3_->bounds().ToString());
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it so much the last two end up at their min.
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800, 50), 0);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 610x300", window_->bounds().ToString());
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("710,300 52x200", window2_->bounds().ToString());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("762,300 38x200", window3_->bounds().ToString());
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revert and make sure everything moves back.
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->RevertDrag();
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 200x300", window_->bounds().ToString());
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,300 150x200", window2_->bounds().ToString());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("450,300 100x200", window3_->bounds().ToString());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around attached window resizing (collapsing and expanding) with
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3 windows.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_RIGHT_3_Compress) {
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 300, 200, 300));
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(300, 300, 200, 200));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window3_->SetBounds(gfx::Rect(450, 300, 100, 200));
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2_.set_min_size(gfx::Size(52, 50));
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate3_.set_min_size(gfx::Size(38, 50));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window3_.get());
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
3827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it -100 to the right, which should collapse w1 and expand w2 and w3.
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 to the right.
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 300x300", window_->bounds().ToString());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,300 200x200", window2_->bounds().ToString());
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("600,300 100x200", window3_->bounds().ToString());
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 100 to the left again.
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -100, -10), 0);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,300 100x300", window_->bounds().ToString());
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("200,300 266x200", window2_->bounds().ToString());
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("466,300 134x200", window3_->bounds().ToString());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around collapsing and expanding from the bottom.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_Compress) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(   0, 100, 400, 300));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(400, 400, 100, 200));
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM,
4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it up 100, which should expand w2 and collapse w1.
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, -100), 0);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collapse all the way to w1's min.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_.set_min_size(gfx::Size(20, 20));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 20, -800), 0);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,100 400x20", window_->bounds().ToString());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,120 100x480", window2_->bounds().ToString());
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move 100 down.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,100 400x400", window_->bounds().ToString());
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,500 100x100", window2_->bounds().ToString());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Back to -100.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 20, -100), 0);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,100 400x200", window_->bounds().ToString());
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("400,300 100x300", window2_->bounds().ToString());
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around attached window resize dragging from the bottom with 2
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// windows.
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_2) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect( 0,  50, 400, 200));
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(0, 250, 200, 100));
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
4467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM,
4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 to the bottom, which should expand w1 and push w2.
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Push off the screen, w2 should be resized to its min.
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2_.set_min_size(gfx::Size(20, 20));
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 50, 820), 0);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,50 400x530", window_->bounds().ToString());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,580 200x20", window2_->bounds().ToString());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move back to 100 and verify w2 gets its original size.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,50 400x300", window_->bounds().ToString());
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,350 200x100", window2_->bounds().ToString());
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revert and make sure everything moves back.
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800, 20), 0);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->RevertDrag();
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,50 400x200", window_->bounds().ToString());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,250 200x100", window2_->bounds().ToString());
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_AttachedResize_BOTTOM_3 DISABLED_AttachedResize_BOTTOM_3
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_AttachedResize_BOTTOM_3 AttachedResize_BOTTOM_3
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Assertions around attached window resize dragging from the bottom with 3
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// windows.
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MAYBE_AttachedResize_BOTTOM_3) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x800");
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect( 300, 100, 300, 200));
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(300, 300, 200, 150));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 450, 200, 100));
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2_.set_min_size(gfx::Size(50, 52));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate3_.set_min_size(gfx::Size(50, 38));
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window3_.get());
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM,
4977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 100 down, which should expand w1 and push w2 and w3.
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -10, 100), 0);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,100 300x300", window_->bounds().ToString());
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,400 200x150", window2_->bounds().ToString());
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,550 200x100", window3_->bounds().ToString());
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 296 things should compress.
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -10, 296), 0);
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,100 300x496", window_->bounds().ToString());
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("300,596 200x123", window2_->bounds().ToString());
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("300,719 200x81", window3_->bounds().ToString());
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it so much everything ends up at its min.
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 50, 798), 0);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,100 300x610", window_->bounds().ToString());
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,710 200x52", window2_->bounds().ToString());
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,762 200x38", window3_->bounds().ToString());
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Revert and make sure everything moves back.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->RevertDrag();
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,100 300x200", window_->bounds().ToString());
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,300 200x150", window2_->bounds().ToString());
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("300,450 200x100", window3_->bounds().ToString());
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around attached window resizing (collapsing and expanding) with
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3 windows.
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, AttachedResize_BOTTOM_3_Compress) {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(  0,   0, 200, 200));
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(10, 200, 200, 200));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window3_->SetBounds(gfx::Rect(20, 400, 100, 100));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate2_.set_min_size(gfx::Size(52, 50));
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate3_.set_min_size(gfx::Size(38, 50));
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> windows;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window2_.get());
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  windows.push_back(window3_.get());
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM,
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 up, which should collapse w1 and expand w2 and w3.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move it 100 down.
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 100), 0);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 200x300", window_->bounds().ToString());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,300 200x200", window2_->bounds().ToString());
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,500 100x100", window3_->bounds().ToString());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 100 up again.
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -10, -100), 0);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 200x100", window_->bounds().ToString());
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,100 200x266", window2_->bounds().ToString());
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("20,366 100x134", window3_->bounds().ToString());
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests that touch-dragging a window does not lock the mouse cursor
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// and therefore shows the cursor on a mousemove.
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MouseMoveWithTouchDrag) {
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window_->SetBounds(gfx::Rect(0, 300, 400, 300));
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(400, 200, 100, 200));
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Shell* shell = Shell::GetInstance();
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::test::EventGenerator generator(window_->GetRootWindow());
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The cursor should not be locked initially.
569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
570f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::vector<aura::Window*> windows;
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  windows.push_back(window2_.get());
573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_TOUCH, windows));
576f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
577f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Creating a WorkspaceWindowResizer should not lock the cursor.
579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The cursor should be hidden after touching the screen and
582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // starting a drag.
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.PressTouch();
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 100, 10), 0);
586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(shell->cursor_manager()->IsCursorVisible());
587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
588f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Moving the mouse should show the cursor.
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.MoveMouseBy(1, 1);
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(shell->cursor_manager()->IsCursorVisible());
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(shell->cursor_manager()->IsCursorLocked());
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  resizer->RevertDrag();
595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertions around dragging to the left/right edge of the screen.
5987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, Edge) {
599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // TODO(varkha): Insets are reset after every drag because of
600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // http://crbug.com/292238.
601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Window is wide enough not to get docked right away.
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window_->SetBounds(gfx::Rect(20, 30, 400, 60));
60368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window_.get());
60468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    internal::SnapSizer snap_sizer(window_state, gfx::Point(),
607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        internal::SnapSizer::LEFT_EDGE, internal::SnapSizer::OTHER_INPUT);
608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Rect expected_bounds(snap_sizer.target_bounds());
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
611f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 10), 0);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->CompleteDrag(0);
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_TRUE(window_state->HasRestoreBounds());
618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ("20,30 400x60",
61968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              window_state->GetRestoreBoundsInScreen().ToString());
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try the same with the right side.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    internal::SnapSizer snap_sizer(window_state, gfx::Point(),
624f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        internal::SnapSizer::RIGHT_EDGE, internal::SnapSizer::OTHER_INPUT);
625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Rect expected_bounds(snap_sizer.target_bounds());
626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 800, 10), 0);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->CompleteDrag(0);
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(expected_bounds.ToString(), window_->bounds().ToString());
63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ASSERT_TRUE(window_state->HasRestoreBounds());
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ("20,30 400x60",
63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              window_state->GetRestoreBoundsInScreen().ToString());
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test if the restore bounds is correct in multiple displays.
63968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->ClearRestoreBounds();
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!SupportsMultipleDisplays())
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
644f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  UpdateDisplay("800x600,500x600");
645f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
647f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Window is wide enough not to get docked right away.
648f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  window_->SetBoundsInScreen(gfx::Rect(800, 10, 400, 60),
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ScreenAsh::GetSecondaryDisplay());
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(root_windows[1], window_->GetRootWindow());
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
652f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ("800,10 400x60", window_->GetBoundsInScreen().ToString());
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
654f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
657f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 499, 00), 0);
658f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    int bottom =
659f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).bottom();
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->CompleteDrag(0);
661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // With the resolution of 500x600 we will hit in this case the 50% screen
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // size setting.
663f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // TODO(varkha): Insets are updated because of http://crbug.com/292238
664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ("250,0 250x" + base::IntToString(bottom),
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              window_->bounds().ToString());
666f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ("800,10 400x60",
66768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)              window_state->GetRestoreBoundsInScreen().ToString());
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Check that non resizable windows will not get resized.
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, NonResizableWindows) {
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect(20, 30, 50, 60));
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetProperty(aura::client::kCanResizeKey, false);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -20, 0), 0);
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->CompleteDrag(0);
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("0,30 50x60", window_->bounds().ToString());
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, CancelSnapPhantom) {
6857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!SupportsMultipleDisplays())
6867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateDisplay("800x600,800x600");
689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2U, root_windows.size());
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Shell::GetScreen()->GetPrimaryDisplay());
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_EQ(1.0f, window_->layer()->opacity());
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(snap_phantom_window_controller());
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The pointer is on the edge but not shared. The snap phantom window
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // controller should be non-NULL.
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 799, 0), 0);
705f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(snap_phantom_window_controller());
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Move the cursor across the edge. Now the snap phantom window controller
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // should be canceled.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 800, 0), 0);
710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(snap_phantom_window_controller());
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies windows are correctly restacked when reordering multiple windows.
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, RestackAttached) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(   0, 0, 200, 300));
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 0, 100, 200));
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 0, 100, 100));
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<aura::Window*> windows;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    windows.push_back(window2_.get());
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
7247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        window_.get(), gfx::Point(), HTRIGHT,
7257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Move it 100 to the right, which should expand w1 and push w2 and w3.
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2 should be topmost since it's initially the highest in the stack.
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("2 1 3", WindowOrderAsString(window_->parent()));
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<aura::Window*> windows;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    windows.push_back(window3_.get());
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
7387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        window2_.get(), gfx::Point(), HTRIGHT,
7397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Move it 100 to the right, which should expand w1 and push w2 and w3.
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 100, -10), 0);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 2 should be topmost since it's initially the highest in the stack.
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("2 3 1", WindowOrderAsString(window_->parent()));
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure we don't allow dragging below the work area.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontDragOffBottom) {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, Shell::GetScreen()->GetNumDisplays());
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 300, 400));
757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
758f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600), 0);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_y =
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            window_->bounds().ToString());
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure we don't allow dragging on the work area with multidisplay.
7687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontDragOffBottomWithMultiDisplay) {
7697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!SupportsMultipleDisplays())
7707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
7717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateDisplay("800x600,800x600");
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2, Shell::GetScreen()->GetNumDisplays());
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Positions the secondary display at the bottom the primary display.
7798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  Shell::GetInstance()->display_manager()->SetLayoutForCurrentDisplays(
780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ash::DisplayLayout(ash::DisplayLayout::BOTTOM, 0));
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
7834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    window_->SetBounds(gfx::Rect(100, 200, 300, 20));
7844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    DCHECK_LT(window_->bounds().height(),
7854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              WorkspaceWindowResizer::kMinOnscreenHeight);
786f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
7884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    ASSERT_TRUE(resizer.get());
7894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
7904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    int expected_y = kRootHeight - window_->bounds().height() - 10;
7914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // When the mouse cursor is in the primary display, the window cannot move
7924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // on non-work area but can get all the way towards the bottom,
7934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // restricted only by the window height.
7944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x20",
7954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              window_->bounds().ToString());
796f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Revert the drag in order to not remember the restore bounds.
797f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->RevertDrag();
7984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
7994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
800f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
801f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 10, 0));
8024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->SetBounds(gfx::Rect(100, 200, 300, 400));
804f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 400), 0);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_y =
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kRootHeight - WorkspaceWindowResizer::kMinOnscreenHeight - 10;
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When the mouse cursor is in the primary display, the window cannot move
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on non-work area with kMinOnscreenHeight margin.
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("100," + base::IntToString(expected_y) + " 300x400",
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              window_->bounds().ToString());
814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->CompleteDrag(0);
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window_->SetBounds(gfx::Rect(100, 200, 300, 400));
819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), window_->bounds().origin(), HTCAPTION));
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
822f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Drag down avoiding getting stuck against the shelf on the bottom screen.
823f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 500), 0);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The window can move to the secondary display beyond non-work area of
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the primary display.
826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ("100,700 300x400", window_->bounds().ToString());
827f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->CompleteDrag(0);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure we don't allow dragging off the top of the work area.
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontDragOffTop) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(10, 0, 0, 0));
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 300, 400));
837f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, -600), 0);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,10 300x400", window_->bounds().ToString());
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, ResizeBottomOutsideWorkArea) {
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 300, 380));
849f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTTOP));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 8, 0), 0);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,200 300x380", window_->bounds().ToString());
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideLeftWorkArea) {
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int left = ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_.get()).x();
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pixels_to_left_border = 50;
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_width = 300;
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_x = left - window_width + pixels_to_left_border;
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
864f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
865f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(pixels_to_left_border, 0), HTRIGHT));
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -window_width, 0), 0);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::IntToString(window_x) + ",100 " +
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IntToString(kMinimumOnScreenArea - window_x) +
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "x380", window_->bounds().ToString());
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideRightWorkArea) {
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int right = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_.get()).right();
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pixels_to_right_border = 50;
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_width = 300;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_x = right - pixels_to_right_border;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
882f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
883f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(window_x, 0), HTLEFT));
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ",100 " +
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IntToString(window_width - pixels_to_right_border +
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              kMinimumOnScreenArea) +
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "x380", window_->bounds().ToString());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, ResizeWindowOutsideBottomWorkArea) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bottom = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_.get()).bottom();
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int delta_to_bottom = 50;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = 380;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, bottom - delta_to_bottom, 300, height));
901f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
902f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(0, bottom - delta_to_bottom), HTTOP));
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, bottom), 0);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100," +
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IntToString(bottom - kMinimumOnScreenArea) +
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            " 300x" +
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IntToString(height - (delta_to_bottom -
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        kMinimumOnScreenArea)),
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            window_->bounds().ToString());
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that 'outside' check of the resizer take into account the extended
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// desktop in case of repositions.
9157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DragWindowOutsideRightToSecondaryDisplay) {
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only primary display.  Changes the window position to fit within the
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // display.
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int right = ScreenAsh::GetDisplayWorkAreaBoundsInParent(
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      window_.get()).right();
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pixels_to_right_border = 50;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_width = 300;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_x = right - pixels_to_right_border;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
926f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
927f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(window_x, 0), HTCAPTION));
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::IntToString(right - kMinimumOnScreenArea) +
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ",100 " +
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IntToString(window_width) +
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "x380", window_->bounds().ToString());
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!SupportsMultipleDisplays())
9367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
9377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // With secondary display.  Operation itself is same but doesn't change
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the position because the window is still within the secondary display.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateDisplay("1000x600,600x400");
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Shell::GetPrimaryRootWindow(), gfx::Insets(0, 0, 50, 0));
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(window_x, 100, window_width, 380));
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, window_width, 0), 0);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(base::IntToString(window_x + window_width) +
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            ",100 " +
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::IntToString(window_width) +
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "x380", window_->bounds().ToString());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies snapping to edges works.
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, SnapToEdge) {
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(96, 112, 320, 160));
9563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Click 50px to the right so that the mouse pointer does not leave the
9573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // workspace ensuring sticky behavior.
958f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
9593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      window_.get(),
9603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      window_->bounds().origin() + gfx::Vector2d(50, 0),
961f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      HTCAPTION));
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move to an x-coordinate of 15, which should not snap.
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An x-coordinate of 7 should snap.
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 7 - 96, 0), 0);
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move to -15, should still snap to 0.
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // At -32 should move past snap points.
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -32 - 96, 0), 0);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("-32,112 320x160", window_->bounds().ToString());
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -33 - 96, 0), 0);
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("-33,112 320x160", window_->bounds().ToString());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Right side should similarly snap.
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 7, 0), 0);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 32, 0), 0);
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("512,112 320x160", window_->bounds().ToString());
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 33, 0), 0);
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("513,112 320x160", window_->bounds().ToString());
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the bottom should snap too.
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 - 7), 0);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 32), 0);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,470 320x160", window_->bounds().ToString());
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 33), 0);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,471 320x160", window_->bounds().ToString());
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And the top should snap too.
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 20), 0);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,20 320x160", window_->bounds().ToString());
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, -112 + 7), 0);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,0 320x160", window_->bounds().ToString());
10041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // And bottom/left should snap too.
10061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resizer->Drag(
10071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CalculateDragPoint(*resizer, 7 - 96, 600 - 160 - 112 - 3 - 7), 0);
10081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
10091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resizer->Drag(
10101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CalculateDragPoint(*resizer, -15 - 96, 600 - 160 - 112 - 3 + 15), 0);
10111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ("0,437 320x160", window_->bounds().ToString());
10121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // should move past snap points.
10131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resizer->Drag(
10141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CalculateDragPoint(*resizer, -32 - 96, 600 - 160 - 112 - 2 + 32), 0);
10151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ("-32,470 320x160", window_->bounds().ToString());
10161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  resizer->Drag(
10171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      CalculateDragPoint(*resizer, -33 - 96, 600 - 160 - 112 - 2 + 33), 0);
10181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ("-33,471 320x160", window_->bounds().ToString());
10191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No need to test dragging < 0 as we force that to 0.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies a resize snap when dragging TOPLEFT.
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPLEFT) {
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTTOPLEFT));
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -98, -199), 0);
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies a resize snap when dragging TOPRIGHT.
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_TOPRIGHT) {
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          window_.get()));
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTTOPRIGHT));
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CalculateDragPoint(*resizer, work_area.right() - 120 - 1, -199), 0);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, window_->bounds().x());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(work_area.y(), window_->bounds().y());
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(230, window_->bounds().height());
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies a resize snap when dragging BOTTOMRIGHT.
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMRIGHT) {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          window_.get()));
1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1055f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMRIGHT));
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CalculateDragPoint(*resizer, work_area.right() - 120 - 1,
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         work_area.bottom() - 220 - 2), 0);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, window_->bounds().x());
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, window_->bounds().y());
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies a resize snap when dragging BOTTOMLEFT.
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, SnapToWorkArea_BOTTOMLEFT) {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          window_.get()));
1071f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1072f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMLEFT));
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CalculateDragPoint(*resizer, -98, work_area.bottom() - 220 - 2), 0);
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, window_->bounds().x());
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, window_->bounds().y());
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(120, window_->bounds().width());
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Verifies sticking to edges works.
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTestSticky, StickToEdge) {
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_->SetBounds(gfx::Rect(96, 112, 320, 160));
10873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Click 50px to the right so that the mouse pointer does not leave the
10883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // workspace ensuring sticky behavior.
1089f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
10903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      window_.get(),
10913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      window_->bounds().origin() + gfx::Vector2d(50, 0),
1092f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      HTCAPTION));
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Move to an x-coordinate of 15, which should not stick.
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Move to -15, should still stick to 0.
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("0,112 320x160", window_->bounds().ToString());
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // At -100 should move past edge.
1100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -100 - 96, 0), 0);
1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("-100,112 320x160", window_->bounds().ToString());
1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -101 - 96, 0), 0);
1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("-101,112 320x160", window_->bounds().ToString());
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Right side should similarly stick.
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 - 15, 0), 0);
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("465,112 320x160", window_->bounds().ToString());
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 15, 0), 0);
1109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("480,112 320x160", window_->bounds().ToString());
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 100, 0), 0);
1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("580,112 320x160", window_->bounds().ToString());
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 800 - 320 - 96 + 101, 0), 0);
1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("581,112 320x160", window_->bounds().ToString());
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // And the bottom should stick too.
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 3 + 15), 0);
1117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("96,437 320x160", window_->bounds().ToString());
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 100), 0);
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("96,538 320x160", window_->bounds().ToString());
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 600 - 160 - 112 - 2 + 101), 0);
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("96,539 320x160", window_->bounds().ToString());
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // No need to test dragging < 0 as we force that to 0.
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Verifies not sticking to edges when a mouse pointer is outside of work area.
11273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTestSticky, NoStickToEdgeWhenOutside) {
11283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager()->
11293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
11303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
11333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
11343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move to an x-coordinate of 15, which should not stick.
11353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 15 - 96, 0), 0);
11363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move to -15, should still stick to 0.
11373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -15 - 96, 0), 0);
11383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("-15,112 320x160", window_->bounds().ToString());
11393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
11403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Verifies a resize sticks when dragging TOPLEFT.
1142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPLEFT) {
1143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTTOPLEFT));
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
1147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -15 - 100, -15 -200), 0);
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ("0,0 120x230", window_->bounds().ToString());
1149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Verifies a resize sticks when dragging TOPRIGHT.
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_TOPRIGHT) {
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          window_.get()));
1156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTTOPRIGHT));
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 + 20,
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   -200 - 15), 0);
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(100, window_->bounds().x());
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(work_area.y(), window_->bounds().y());
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(230, window_->bounds().height());
1165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Verifies a resize snap when dragging BOTTOMRIGHT.
1168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMRIGHT) {
1169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          window_.get()));
1172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMRIGHT));
1174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, work_area.right() - 100 - 20 + 15,
1176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   work_area.bottom() - 200 - 30 + 15), 0);
1177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(100, window_->bounds().x());
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(200, window_->bounds().y());
1179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(work_area.right() - 100, window_->bounds().width());
1180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Verifies a resize snap when dragging BOTTOMLEFT.
1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTestSticky, StickToWorkArea_BOTTOMLEFT) {
1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(
1187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          window_.get()));
1188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMLEFT));
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -15 - 100,
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                   work_area.bottom() - 200 - 30 + 15), 0);
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(0, window_->bounds().x());
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(200, window_->bounds().y());
1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(120, window_->bounds().width());
1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(work_area.bottom() - 200, window_->bounds().height());
1197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, CtrlDragResizeToExactPosition) {
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMRIGHT));
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Resize the right bottom to add 10 in width, 12 in height.
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 12), ui::EF_CONTROL_DOWN);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Both bottom and right sides to resize to exact size requested.
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,112 330x172", window_->bounds().ToString());
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, CtrlCompleteDragMoveToExactPosition) {
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(96, 112, 320, 160));
1212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ctrl + drag the window to new poistion by adding (10, 12) to its origin,
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the window should move to the exact position.
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 12), 0);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->CompleteDrag(ui::EF_CONTROL_DOWN);
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("106,124 320x160", window_->bounds().ToString());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that a dragged window will restore to its pre-maximized size.
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, RestoreToPreMaximizeCoordinates) {
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(0, 0, 1000, 1000));
122568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window_.get());
122668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drag the window to new position by adding (10, 10) to original point,
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the window should get restored.
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 10, 10), 0);
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->CompleteDrag(0);
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("10,10 320x160", window_->bounds().ToString());
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The restore rectangle should get cleared as well.
123668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(window_state->HasRestoreBounds());
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that a dragged window will restore to its pre-maximized size.
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, RevertResizeOperation) {
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Rect initial_bounds(0, 0, 200, 400);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(initial_bounds);
124368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
124468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window_.get());
124568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->SetRestoreBoundsInScreen(gfx::Rect(96, 112, 320, 160));
1246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drag the window to new poistion by adding (180, 16) to original point,
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the window should get restored.
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 180, 16), 0);
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->RevertDrag();
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(initial_bounds.ToString(), window_->bounds().ToString());
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("96,112 320x160",
125568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            window_state->GetRestoreBoundsInScreen().ToString());
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that only usable sizes get returned by the resizer.
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyAttach) {
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(10, 10, 20, 30));
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(150, 160, 25, 20));
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move |window| one pixel to the left of |window2|. Should snap to right and
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // top.
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 119, 145), 0);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("130,160 20x30", window_->bounds().ToString());
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move |window| one pixel to the right of |window2|. Should snap to left and
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // top.
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 164, 145), 0);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("175,160 20x30", window_->bounds().ToString());
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move |window| one pixel above |window2|. Should snap to top and left.
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 142, 119), 0);
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("150,130 20x30", window_->bounds().ToString());
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move |window| one pixel above the bottom of |window2|. Should snap to
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bottom and left.
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 142, 169), 0);
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("150,180 20x30", window_->bounds().ToString());
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following variants verify magnetic snapping during resize when dragging a
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// particular edge.
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOP) {
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTTOP));
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,199 20x31", window_->bounds().ToString());
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPLEFT) {
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(99, 179, 10, 20));
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTTOPLEFT));
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("99,199 21x31", window_->bounds().ToString());
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(88, 201, 10, 20));
1317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTTOPLEFT));
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("98,201 22x29", window_->bounds().ToString());
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_TOPRIGHT) {
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(111, 179, 10, 20));
1332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTTOPRIGHT));
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
1342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTTOPRIGHT));
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("100,199 21x31", window_->bounds().ToString());
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_RIGHT) {
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(121, 199, 10, 20));
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT));
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,200 21x30", window_->bounds().ToString());
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMRIGHT) {
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(122, 212, 10, 20));
1369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTBOTTOMRIGHT));
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("100,200 22x32", window_->bounds().ToString());
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
1379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTBOTTOMRIGHT));
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("100,200 21x33", window_->bounds().ToString());
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOM) {
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(111, 233, 10, 20));
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM));
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,200 20x33", window_->bounds().ToString());
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_BOTTOMLEFT) {
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(99, 231, 10, 20));
1406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTBOTTOMLEFT));
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("99,200 21x31", window_->bounds().ToString());
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
1416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTBOTTOMLEFT));
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("99,200 21x29", window_->bounds().ToString());
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MagneticallyResize_LEFT) {
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->SetBounds(gfx::Rect(89, 209, 10, 20));
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect(100, 200, 20, 30));
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2_->Show();
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTLEFT));
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 0), 0);
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("99,200 21x30", window_->bounds().ToString());
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that the user user moved window flag is getting properly set.
1438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, CheckUserWindowManagedFlags) {
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_->SetBounds(gfx::Rect( 0,  50, 400, 200));
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<aura::Window*> no_attached_windows;
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that an abort doesn't change anything.
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Move it 100 to the bottom.
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->RevertDrag();
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_FALSE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that a completed move / size does change the user coordinates.
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(resizer.get());
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Move it 100 to the bottom.
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 0, 100), 0);
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("0,150 400x200", window_->bounds().ToString());
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resizer->CompleteDrag(0);
146468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_TRUE(wm::GetWindowState(window_.get())->bounds_changed_by_user());
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that a window with a specified max size doesn't exceed it when dragged.
14692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, TestMaxSizeEnforced) {
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect(0, 0, 400, 300));
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.set_max_size(gfx::Size(401, 301));
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMRIGHT));
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(401, window_->bounds().width());
14772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(301, window_->bounds().height());
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that a window with a specified max width doesn't restrict its height.
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, TestPartialMaxSizeEnforced) {
14822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect(0, 0, 400, 300));
14832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.set_max_size(gfx::Size(401, 0));
14842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOMRIGHT));
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 2, 2), 0);
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(401, window_->bounds().width());
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(302, window_->bounds().height());
14902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that a window with a specified max size can't be snapped.
14932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, PhantomSnapMaxSize) {
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // With max size not set we get a phantom window controller for dragging off
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // the right hand side.
1497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Make the window wider than maximum docked width.
1498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    window_->SetBounds(gfx::Rect(0, 0, 400, 200));
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
1502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(snap_phantom_window_controller());
15032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_TRUE(snap_phantom_window_controller());
1505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->RevertDrag();
15062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
1508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // With max size defined, we get no phantom window for snapping but we still
1509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // get a phantom window (docking guide).
1510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_.set_max_size(gfx::Size(400, 200));
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (switches::UseDockedWindows())
1517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_TRUE(snap_phantom_window_controller());
1518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    else
1519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      EXPECT_FALSE(snap_phantom_window_controller());
1520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->RevertDrag();
1521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  {
1523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // With max size defined, we get no phantom window for snapping.
1524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    window_->SetBounds(gfx::Rect(0, 0, 400, 200));
1525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_.set_max_size(gfx::Size(400, 200));
1526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // With min size defined, we get no phantom window for docking.
1527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_.set_min_size(gfx::Size(400, 200));
1528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        window_.get(), gfx::Point(), HTCAPTION));
1531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->Drag(CalculateDragPoint(*resizer, 801, 0), 0);
1532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_FALSE(snap_phantom_window_controller());
1533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    resizer->RevertDrag();
15342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontRewardRightmostWindowForOverflows) {
15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x800");
15391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
15412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Four 100x100 windows flush against eachother, starting at 100,100.
15432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
15442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
15452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate2_.set_max_size(gfx::Size(101, 0));
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
15512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
15522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
15532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
15547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
15557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
15562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
15572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 51 to the left, which should contract w1 and expand w2-4.
15582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // w2 will hit its max size straight away, and in doing so will leave extra
15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // pixels that a naive implementation may award to the rightmost window. A
15602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // fair implementation will give 25 pixels to each of the other windows.
15612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
15622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
15632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("149,100 101x100", window2_->bounds().ToString());
15642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("250,100 125x100", window3_->bounds().ToString());
15652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("375,100 125x100", window4_->bounds().ToString());
15662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontExceedMaxWidth) {
15692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x800");
15701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
15712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
15722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Four 100x100 windows flush against eachother, starting at 100,100.
15742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
15752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
15762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
15772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window4_->SetBounds(gfx::Rect(400, 100, 100, 100));
15782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate2_.set_max_size(gfx::Size(101, 0));
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate3_.set_max_size(gfx::Size(101, 0));
15802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
15822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
15832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
15842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
15852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
15867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
15877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
15882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
15892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 52 to the left, which should contract w1 and expand w2-4.
15902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
15912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("350,100 150x100", window4_->bounds().ToString());
15952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontExceedMaxHeight) {
15982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x800");
15991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
16002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
16012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Four 100x100 windows flush against eachother, starting at 100,100.
16032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
16042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
16052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
16062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
16072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate2_.set_max_size(gfx::Size(0, 101));
16082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate3_.set_max_size(gfx::Size(0, 101));
16092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
16112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
16122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
16132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
16142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
16157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM,
16167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
16172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 52 up, which should contract w1 and expand w2-4.
16192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, -52), 0);
16202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 100x48", window_->bounds().ToString());
16212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,148 100x101", window2_->bounds().ToString());
16222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,249 100x101", window3_->bounds().ToString());
16232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,350 100x150", window4_->bounds().ToString());
16242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
16272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_DontExceedMinHeight DISABLED_DontExceedMinHeight
16292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
16302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_DontExceedMinHeight DontExceedMinHeight
16312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
16322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MAYBE_DontExceedMinHeight) {
16342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x500");
16351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
16362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
16372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Four 100x100 windows flush against eachother, starting at 100,100.
16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
16402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(100, 200, 100, 100));
16412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(100, 300, 100, 100));
16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window4_->SetBounds(gfx::Rect(100, 400, 100, 100));
16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate2_.set_min_size(gfx::Size(0, 99));
16442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate3_.set_min_size(gfx::Size(0, 99));
16452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
16517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTBOTTOM,
16527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 52 down, which should expand w1 and contract w2-4.
16552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 0, 52), 0);
16562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 100x152", window_->bounds().ToString());
16572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,252 100x99", window2_->bounds().ToString());
16582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,351 100x99", window3_->bounds().ToString());
16592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,450 100x50", window4_->bounds().ToString());
16602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, DontExpandRightmostPastMaxWidth) {
16632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x800");
16641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
16652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
16662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Three 100x100 windows flush against eachother, starting at 100,100.
16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
16712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate3_.set_max_size(gfx::Size(101, 0));
16722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
16752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
16762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
16772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
16787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
16797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
16802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 51 to the left, which should contract w1 and expand w2-3.
16822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -51, 0), 0);
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 49x100", window_->bounds().ToString());
16842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("149,100 150x100", window2_->bounds().ToString());
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
16872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MoveAttachedWhenGrownToMaxSize) {
16892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("600x800");
16901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
16912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
16922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Three 100x100 windows flush against eachother, starting at 100,100.
16942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
16952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
16962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate2_.set_max_size(gfx::Size(101, 0));
16982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate3_.set_max_size(gfx::Size(101, 0));
16992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
17012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
17022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
17057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
17067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 52 to the left, which should contract w1 and expand and move w2-3.
17092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -52, 0), 0);
17102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 48x100", window_->bounds().ToString());
17112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("148,100 101x100", window2_->bounds().ToString());
17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("249,100 101x100", window3_->bounds().ToString());
17132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
17172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_MainWindowHonoursMaxWidth DISABLED_MainWindowHonoursMaxWidth
17182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_MainWindowHonoursMaxWidth MainWindowHonoursMaxWidth
17202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
17212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MAYBE_MainWindowHonoursMaxWidth) {
17232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("400x800");
17241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
17252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Three 100x100 windows flush against eachother, starting at 100,100.
17282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
17292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
17302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
17312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.set_max_size(gfx::Size(102, 0));
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
17342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
17362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window4_.get());
17372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
17387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
17397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
17402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
17412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 50 to the right, which should expand w1 and contract w2-3, as they
17422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // won't fit in the root window in their original sizes.
17432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, 50, 0), 0);
17442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 102x100", window_->bounds().ToString());
17452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("202,100 99x100", window2_->bounds().ToString());
17462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("301,100 99x100", window3_->bounds().ToString());
17472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, MainWindowHonoursMinWidth) {
17502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateDisplay("400x800");
17511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root = Shell::GetPrimaryRootWindow();
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Shell::GetInstance()->SetDisplayWorkAreaInsets(root, gfx::Insets());
17532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Three 100x100 windows flush against eachother, starting at 100,100.
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window_->SetBounds(gfx::Rect( 100, 100, 100, 100));
17562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window2_->SetBounds(gfx::Rect(200, 100, 100, 100));
17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window3_->SetBounds(gfx::Rect(300, 100, 100, 100));
17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.set_min_size(gfx::Size(98, 0));
17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<aura::Window*> windows;
17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window2_.get());
17622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  windows.push_back(window3_.get());
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<WorkspaceWindowResizer> resizer(WorkspaceWindowResizer::Create(
17647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      window_.get(), gfx::Point(), HTRIGHT,
17657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      aura::client::WINDOW_MOVE_SOURCE_MOUSE, windows));
17662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(resizer.get());
17672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Move it 50 to the left, which should contract w1 and expand w2-3.
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -50, 0), 0);
17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("100,100 98x100", window_->bounds().ToString());
17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("198,100 101x100", window2_->bounds().ToString());
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("299,100 101x100", window3_->bounds().ToString());
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
17732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// The following variants test that windows are resized correctly to the edges
17757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// of the screen using touch, when touch point is off of the window border.
17767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_RIGHT) {
17777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
17787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTRIGHT);
17807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
17817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
17827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
17847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       touch_resize_window_.get());
17857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
17867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag out of the right border a bit and check if the border is aligned with
17877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the touch point.
17887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(715, kRootHeight / 2),
17897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(725, kRootHeight / 2),
179058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
179158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
17927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 625, kRootHeight - 200).ToString(),
17937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
17947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag more, but stop before being snapped to the edge.
17957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(725, kRootHeight / 2),
17967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(760, kRootHeight / 2),
179758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
179858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
17997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 660, kRootHeight - 200).ToString(),
18007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag even more to snap to the edge.
18027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(760, kRootHeight / 2),
18037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(775, kRootHeight / 2),
180458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
180558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 700, kRootHeight - 200).ToString(),
18077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
18097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_LEFT) {
18117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
18127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTLEFT);
18147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
18157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
18187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       touch_resize_window_.get());
18197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag out of the left border a bit and check if the border is aligned with
18217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the touch point.
18227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(85, kRootHeight / 2),
18237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(75, kRootHeight / 2),
182458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
182558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(75, 100, 625, kRootHeight - 200).ToString(),
18277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag more, but stop before being snapped to the edge.
18297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(75, kRootHeight / 2),
18307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(40, kRootHeight / 2),
183158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
183258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(40, 100, 660, kRootHeight - 200).ToString(),
18347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag even more to snap to the edge.
18367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(40, kRootHeight / 2),
18377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(25, kRootHeight / 2),
183858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
183958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(0, 100, 700, kRootHeight - 200).ToString(),
18417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
18437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_TOP) {
18457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
18467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTTOP);
18487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
18497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
18527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       touch_resize_window_.get());
18537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag out of the top border a bit and check if the border is aligned with
18557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the touch point.
18567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(400, 85),
18577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(400, 75),
185858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
185958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 75, 600, kRootHeight - 175).ToString(),
18617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag more, but stop before being snapped to the edge.
18637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(400, 75),
18647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(400, 40),
186558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
186658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 40, 600, kRootHeight - 140).ToString(),
18687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag even more to snap to the edge.
18707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(400, 40),
18717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(400, 25),
187258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
187358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 0, 600, kRootHeight - 100).ToString(),
18757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
18777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, TouchResizeToEdge_BOTTOM) {
18797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  shelf_layout_manager()->SetAutoHideBehavior(SHELF_AUTO_HIDE_ALWAYS_HIDDEN);
18807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  InitTouchResizeWindow(gfx::Rect(100, 100, 600, kRootHeight - 200), HTBOTTOM);
18827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 200).ToString(),
18837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
18867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                       touch_resize_window_.get());
18877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
18887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag out of the bottom border a bit and check if the border is aligned with
18897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // the touch point.
18907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 85),
18917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(400, kRootHeight - 75),
189258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
189358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
18947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 175).ToString(),
18957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
18967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag more, but stop before being snapped to the edge.
18977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 75),
18987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(400, kRootHeight - 40),
189958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
190058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
19017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 140).ToString(),
19027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
19037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Drag even more to snap to the edge.
19047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  generator.GestureScrollSequence(gfx::Point(400, kRootHeight - 40),
19057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  gfx::Point(400, kRootHeight - 25),
190658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  base::TimeDelta::FromMilliseconds(10),
190758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  5);
19087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_EQ(gfx::Rect(100, 100, 600, kRootHeight - 100).ToString(),
19097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            touch_resize_window_->bounds().ToString());
19107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
19113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_F(WorkspaceWindowResizerTest, PhantomWindowShow) {
19133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!SupportsMultipleDisplays())
19143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
19153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  UpdateDisplay("500x400,500x400");
19173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  window_->SetBoundsInScreen(gfx::Rect(0, 0, 50, 60),
19183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             Shell::GetScreen()->GetPrimaryDisplay());
1919f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
19203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(root_windows[0], window_->GetRootWindow());
19213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1922f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<WindowResizer> resizer(CreateResizerForTest(
1923f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      window_.get(), gfx::Point(), HTCAPTION));
19243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(resizer.get());
1925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(snap_phantom_window_controller());
19263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The pointer is on the edge but not shared. The snap phantom window
19283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // controller should be non-NULL.
1929d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  resizer->Drag(CalculateDragPoint(*resizer, -1, 0), 0);
1930f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(snap_phantom_window_controller());
1931f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PhantomWindowController* phantom_controller(snap_phantom_window_controller());
19323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // phantom widget only in the left screen.
19343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
19353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
19363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(phantom_controller->phantom_widget_start_);
19373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[0],
19393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
19403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move phantom widget into the right screen. Test that 2 widgets got created.
19423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(600, 100, 50, 60));
19433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
19443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_start_);
19453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[1],
19473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
19483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[0],
19503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_start_->GetNativeWindow()->
19513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          GetRootWindow());
19523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunAnimationTillComplete(phantom_controller->animation_.get());
19533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move phantom widget only in the right screen. Start widget should close.
19553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(700, 100, 50, 60));
19563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
19573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(phantom_controller->phantom_widget_start_);
19583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[1],
19603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
19613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunAnimationTillComplete(phantom_controller->animation_.get());
19623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move phantom widget into the left screen. Start widget should open.
19643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(100, 100, 50, 60));
19653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
19663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_start_);
19673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[0],
19693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
19703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[1],
19723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_start_->GetNativeWindow()->
19733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          GetRootWindow());
19743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunAnimationTillComplete(phantom_controller->animation_.get());
19753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move phantom widget while in the left screen. Start widget should close.
19773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
19783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
19793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(phantom_controller->phantom_widget_start_);
19803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[0],
19823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
19833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunAnimationTillComplete(phantom_controller->animation_.get());
19843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move phantom widget spanning both screens with most of the window in the
19863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // right screen. Two widgets are created.
19873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(495, 100, 50, 60));
19883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
19893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_start_);
19903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[1],
19923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
19933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
19943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[0],
19953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_start_->GetNativeWindow()->
19963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          GetRootWindow());
19973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunAnimationTillComplete(phantom_controller->animation_.get());
19983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
19993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Move phantom widget back into the left screen. Phantom widgets should swap.
20003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Show(gfx::Rect(200, 100, 50, 60));
20013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_);
20023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(phantom_controller->phantom_widget_start_);
20033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
20043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[0],
20053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_->GetNativeWindow()->GetRootWindow());
20063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(
20073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      root_windows[1],
20083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      phantom_controller->phantom_widget_start_->GetNativeWindow()->
20093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          GetRootWindow());
20103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RunAnimationTillComplete(phantom_controller->animation_.get());
20113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
20123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Hide phantom controller. Both widgets should close.
20133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  phantom_controller->Hide();
20143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(phantom_controller->phantom_widget_);
20153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_FALSE(phantom_controller->phantom_widget_start_);
20163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
20173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
2020