toplevel_window_event_handler_unittest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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/toplevel_window_event_handler.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/ash_constants.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/root_window_controller.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell_window_ids.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/test/ash_test_base.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/lock_state_controller.h"
13ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/wm/resize_shadow.h"
14ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/wm/resize_shadow_controller.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/workspace/snap_sizer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/workspace_controller.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/aura_test_base.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/event_generator.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows headers define macros for these function names which screw with us.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(CreateWindow)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef CreateWindow
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple window delegate that returns the specified hit-test code when
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requested and applies a minimum size constraint if there is one.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestWindowDelegate : public aura::test::TestWindowDelegate {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
47ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  explicit TestWindowDelegate(int hittest_code) {
48ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    set_window_component(hittest_code);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestWindowDelegate() {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from aura::Test::TestWindowDelegate:
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnWindowDestroyed() OVERRIDE {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete this;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestWindowDelegate);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ToplevelWindowEventHandlerTest : public AshTestBase {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ToplevelWindowEventHandlerTest() {}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ToplevelWindowEventHandlerTest() {}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::Window* CreateWindow(int hittest_code) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestWindowDelegate* d1 = new TestWindowDelegate(hittest_code);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura::Window* w1 = new aura::Window(d1);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    w1->SetType(aura::client::WINDOW_TYPE_NORMAL);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    w1->set_id(1);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    w1->Init(ui::LAYER_TEXTURED);
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::Window* parent =
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Shell::GetContainer(Shell::GetPrimaryRootWindow(),
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          internal::kShellWindowId_AlwaysOnTopContainer);
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parent->AddChild(w1);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    w1->SetBounds(gfx::Rect(0, 0, 100, 100));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    w1->Show();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return w1;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DragFromCenterBy(aura::Window* window, int dx, int dy) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), window);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.DragMouseBy(dx, dy);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TouchDragFromCenterBy(aura::Window* window, int dx, int dy) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), window);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.PressMoveAndReleaseTouchBy(dx, dy);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ToplevelWindowEventHandler> handler_;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ToplevelWindowEventHandlerTest);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, Caption) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTCAPTION));
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Size size = w1->bounds().size();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 100, 100);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 100,100.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("100,100", w1->bounds().origin().ToString());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should not have.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(size.ToString(), w1->bounds().size().ToString());
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TouchDragFromCenterBy(w1.get(), 100, 100);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 100,100.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("200,200", w1->bounds().origin().ToString());
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should not have.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(size.ToString(), w1->bounds().size().ToString());
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomRight) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTBOTTOMRIGHT));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = w1->bounds().origin();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 100, 100);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 100,100.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(200, 200), w1->bounds().size());
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, GrowBox) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTGROWBOX));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      static_cast<TestWindowDelegate*>(w1->delegate());
130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = w1->bounds().origin();
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseToCenterOf(w1.get());
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.DragMouseBy(100, 100);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 100,100.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(200, 200), w1->bounds().size());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shrink the wnidow by (-100, -100).
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.DragMouseBy(-100, -100);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have decreased by 100,100.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(100, 100), w1->bounds().size());
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enforce minimum size.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.DragMouseBy(-60, -60);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 40), w1->bounds().size());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, Right) {
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTRIGHT));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = w1->bounds().origin();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 100, 100);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 100,0.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(200, 100), w1->bounds().size());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, Bottom) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTBOTTOM));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = w1->bounds().origin();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 100, 100);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 0,100.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(100, 200), w1->bounds().size());
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, TopRight) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTTOPRIGHT));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), -50, 50);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 0,50.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(0, 50), w1->bounds().origin());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have decreased by 50,50.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(50, 50), w1->bounds().size());
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, Top) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTTOP));
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 50, 50);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 0,50.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(0, 50), w1->bounds().origin());
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have decreased by 0,50.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(100, 50), w1->bounds().size());
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, Left) {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTLEFT));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 50, 50);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 50,0.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(50, 0), w1->bounds().origin());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have decreased by 50,0.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(50, 100), w1->bounds().size());
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomLeft) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTBOTTOMLEFT));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 50, -50);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 50,0.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(50, 0), w1->bounds().origin());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have decreased by 50,50.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(50, 50), w1->bounds().size());
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, TopLeft) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTTOPLEFT));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 50, 50);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should have been offset by 50,50.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(50, 50), w1->bounds().origin());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have decreased by 50,50.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(50, 50), w1->bounds().size());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, Client) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTCLIENT));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds = w1->bounds();
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 100, 100);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Neither position nor size should have changed.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bounds, w1->bounds());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, LeftPastMinimum) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTLEFT));
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWindowDelegate*>(w1->delegate());
231ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a large left-to-right drag.  Window width should be clamped to
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // minimum and position change should be limited as well.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 333, 0);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(60, 0), w1->bounds().origin());
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 100), w1->bounds().size());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, RightPastMinimum) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTRIGHT));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWindowDelegate*>(w1->delegate());
244ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = w1->bounds().origin();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a large right-to-left drag.  Window width should be clamped to
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // minimum and position should not change.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), -333, 0);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 100), w1->bounds().size());
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, TopLeftPastMinimum) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTTOPLEFT));
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWindowDelegate*>(w1->delegate());
258ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a large top-left to bottom-right drag.  Window width should be
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clamped to minimum and position should be limited.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 333, 444);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(60, 60), w1->bounds().origin());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 40), w1->bounds().size());
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, TopRightPastMinimum) {
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTTOPRIGHT));
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWindowDelegate*>(w1->delegate());
271ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a large top-right to bottom-left drag.  Window size should be
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clamped to minimum, x position should not change, and y position should
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be clamped.
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), -333, 444);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(0, 60), w1->bounds().origin());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 40), w1->bounds().size());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomLeftPastMinimum) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTBOTTOMLEFT));
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWindowDelegate*>(w1->delegate());
285ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a large bottom-left to top-right drag.  Window size should be
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clamped to minimum, x position should be clamped, and y position should
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not change.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), 333, -444);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Point(60, 0), w1->bounds().origin());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 40), w1->bounds().size());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomRightPastMinimum) {
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> w1(CreateWindow(HTBOTTOMRIGHT));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestWindowDelegate* window_delegate =
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<TestWindowDelegate*>(w1->delegate());
299ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  window_delegate->set_minimum_size(gfx::Size(40, 40));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = w1->bounds().origin();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate a large bottom-right to top-left drag.  Window size should be
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clamped to minimum and position should not change.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(w1.get(), -333, -444);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, w1->bounds().origin());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(40, 40), w1->bounds().size());
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomRightWorkArea) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTBOTTOMRIGHT));
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target.get()).work_area();
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = target->bounds().origin();
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drag further than work_area bottom.
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(target.get(), 100, work_area.height());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, target->bounds().origin());
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 100, work_area.height() - target->bounds.y()
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(200, work_area.height() - target->bounds().y()),
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            target->bounds().size());
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomLeftWorkArea) {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTBOTTOMLEFT));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target.get()).work_area();
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = target->bounds().origin();
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drag further than work_area bottom.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(target.get(), -30, work_area.height());
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // origin is now at 70, 100.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position.x() - 30, target->bounds().x());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position.y(), target->bounds().y());
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 30, work_area.height() - target->bounds.y()
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(130, work_area.height() - target->bounds().y()),
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            target->bounds().size());
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, BottomWorkArea) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTBOTTOM));
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target.get()).work_area();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point position = target->bounds().origin();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Drag further than work_area bottom.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(target.get(), 0, work_area.height());
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Position should not have changed.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(position, target->bounds().origin());
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size should have increased by 0, work_area.height() - target->bounds.y()
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(gfx::Size(100, work_area.height() - target->bounds().y()),
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            target->bounds().size());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies we don't let windows drag to a -y location.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, DontDragToNegativeY) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTTOP));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       target.get());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseTo(0, 5);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.DragMouseBy(0, -5);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The y location and height should not have changed.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, target->bounds().y());
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, target->bounds().height());
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies we don't let windows go bigger than the display width.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, DontGotWiderThanScreen) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTRIGHT));
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect work_area = Shell::GetScreen()->GetDisplayNearestWindow(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      target.get()).bounds();
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DragFromCenterBy(target.get(), work_area.width() * 2, 0);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The y location and height should not have changed.
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(work_area.width(), target->bounds().width());
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies that touch-gestures drag the window correctly.
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, GestureDrag) {
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> target(
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithDelegate(
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new TestWindowDelegate(HTCAPTION),
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          0,
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gfx::Rect(0, 0, 100, 100)));
3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(target.get());
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       target.get());
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect old_bounds = target->bounds();
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point location(5, 5);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target->SetProperty(aura::client::kCanMaximizeKey, true);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point end = location;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Snap right;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get the expected snapped bounds before snapping.
3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    internal::SnapSizer sizer(window_state, location,
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::SnapSizer::RIGHT_EDGE,
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::SnapSizer::OTHER_INPUT);
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds());
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end.Offset(100, 0);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureScrollSequence(location, end,
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(5),
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        10);
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunAllPendingInMessageLoop();
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that the window has moved after the gesture.
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(old_bounds.ToString(), target->bounds().ToString());
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(snapped_bounds.ToString(), target->bounds().ToString());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_bounds = target->bounds();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Snap left.
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get the expected snapped bounds before snapping.
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    internal::SnapSizer sizer(window_state, location,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::SnapSizer::LEFT_EDGE,
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal::SnapSizer::OTHER_INPUT);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds());
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end = location = target->GetBoundsInRootWindow().CenterPoint();
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end.Offset(-100, 0);
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureScrollSequence(location, end,
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(5),
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        10);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunAllPendingInMessageLoop();
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(old_bounds.ToString(), target->bounds().ToString());
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(snapped_bounds.ToString(), target->bounds().ToString());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect bounds_before_maximization = target->bounds();
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bounds_before_maximization.Offset(0, 100);
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target->SetBounds(bounds_before_maximization);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  old_bounds = target->bounds();
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maximize.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end = location = target->GetBoundsInRootWindow().CenterPoint();
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end.Offset(0, -100);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureScrollSequence(location, end,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(5),
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
44168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(old_bounds.ToString(), target->bounds().ToString());
44368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(window_state->IsMaximized());
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(old_bounds.ToString(),
44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            window_state->GetRestoreBoundsInScreen().ToString());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Restore();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  target->SetBounds(old_bounds);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Minimize.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end = location = target->GetBoundsInRootWindow().CenterPoint();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  end.Offset(0, 100);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureScrollSequence(location, end,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(5),
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      10);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(old_bounds.ToString(), target->bounds().ToString());
45868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(window_state->IsMinimized());
45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(window_state->always_restores_to_restore_bounds());
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(old_bounds.ToString(),
46168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            window_state->GetRestoreBoundsInScreen().ToString());
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that a gesture cannot minimize a window in login/lock screen.
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, GestureDragMinimizeLoginScreen) {
4664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  LockStateController* state_controller =
4674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      Shell::GetInstance()->lock_state_controller();
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_controller->OnLoginStateChanged(user::LOGGED_IN_NONE);
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  state_controller->OnLockStateChanged(false);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SetUserLoggedIn(false);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTCAPTION));
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::Window* lock = internal::RootWindowController::ForWindow(target.get())->
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetContainer(internal::kShellWindowId_LockSystemModalContainer);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  lock->AddChild(target.get());
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       target.get());
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect old_bounds = target->bounds();
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point location(5, 5);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target->SetProperty(aura::client::kCanMaximizeKey, true);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point end = location;
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  end.Offset(0, 100);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureScrollSequence(location, end,
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(5),
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      10);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunAllPendingInMessageLoop();
48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(wm::GetWindowState(target.get())->IsMinimized());
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, GestureDragToRestore) {
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> window(
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithDelegate(
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new TestWindowDelegate(HTCAPTION),
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          0,
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gfx::Rect(10, 20, 30, 40)));
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  window->Show();
49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(window.get());
49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  window_state->Activate();
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       window.get());
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect old_bounds = window->bounds();
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point location, end;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  end = location = window->GetBoundsInRootWindow().CenterPoint();
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  end.Offset(0, 100);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureScrollSequence(location, end,
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(5),
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      10);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunAllPendingInMessageLoop();
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(old_bounds.ToString(), window->bounds().ToString());
51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(window_state->IsMinimized());
51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(window_state->always_restores_to_restore_bounds());
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(old_bounds.ToString(),
51568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            window_state->GetRestoreBoundsInScreen().ToString());
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that an unresizable window cannot be dragged or snapped using gestures.
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, GestureDragForUnresizableWindow) {
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTCAPTION));
5214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wm::WindowState* window_state = wm::GetWindowState(target.get());
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       target.get());
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect old_bounds = target->bounds();
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point location(5, 5);
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target->SetProperty(aura::client::kCanResizeKey, false);
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point end = location;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to snap right. The window is not resizable. So it should not snap.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get the expected snapped bounds before the gesture.
5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    internal::SnapSizer sizer(window_state, location,
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        internal::SnapSizer::RIGHT_EDGE,
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        internal::SnapSizer::OTHER_INPUT);
5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds());
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end.Offset(100, 0);
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureScrollSequence(location, end,
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(5),
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        10);
5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunAllPendingInMessageLoop();
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that the window has moved after the gesture.
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect expected_bounds(old_bounds);
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_bounds.Offset(gfx::Vector2d(100, 0));
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_bounds.ToString(), target->bounds().ToString());
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that the window did not snap left.
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(snapped_bounds.ToString(), target->bounds().ToString());
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  old_bounds = target->bounds();
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to snap left. It should not snap.
5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Get the expected snapped bounds before the gesture.
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    internal::SnapSizer sizer(window_state, location,
5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        internal::SnapSizer::LEFT_EDGE,
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        internal::SnapSizer::OTHER_INPUT);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect snapped_bounds = sizer.GetSnapBounds(target->bounds());
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end = location = target->GetBoundsInRootWindow().CenterPoint();
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end.Offset(-100, 0);
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    generator.GestureScrollSequence(location, end,
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(5),
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        10);
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunAllPendingInMessageLoop();
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that the window has moved after the gesture.
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect expected_bounds(old_bounds);
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expected_bounds.Offset(gfx::Vector2d(-100, 0));
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_bounds.ToString(), target->bounds().ToString());
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Verify that the window did not snap left.
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_NE(snapped_bounds.ToString(), target->bounds().ToString());
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that dragging multiple windows at the same time is not allowed.
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, GestureDragMultipleWindows) {
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> target(
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithDelegate(
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new TestWindowDelegate(HTCAPTION),
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          0,
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gfx::Rect(0, 0, 100, 100)));
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<aura::Window> notmoved(
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateTestWindowInShellWithDelegate(
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          new TestWindowDelegate(HTCAPTION),
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          1, gfx::Rect(100, 0, 100, 100)));
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       target.get());
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect old_bounds = target->bounds();
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point location(5, 5);
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  target->SetProperty(aura::client::kCanMaximizeKey, true);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send some touch events to start dragging |target|.
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.MoveTouch(location);
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.PressTouch();
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  location.Offset(40, 5);
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.MoveTouch(location);
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Try to drag |notmoved| window. This should not move the window.
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect bounds = notmoved->bounds();
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    aura::test::EventGenerator gen(Shell::GetPrimaryRootWindow(),
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   notmoved.get());
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Point start = notmoved->bounds().origin() + gfx::Vector2d(10, 10);
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Point end = start + gfx::Vector2d(100, 10);
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gen.GestureScrollSequence(start, end,
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::TimeDelta::FromMilliseconds(10),
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        10);
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(bounds.ToString(), notmoved->bounds().ToString());
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies pressing escape resets the bounds to the original bounds.
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Disabled crbug.com/166219.
621d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#if defined(OS_WIN)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_EscapeReverts DISABLED_EscapeReverts
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_EscapeReverts EscapeReverts
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, MAYBE_EscapeReverts) {
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> target(CreateWindow(HTBOTTOMRIGHT));
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       target.get());
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressLeftButton();
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.MoveMouseBy(10, 11);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Execute any scheduled draws so that pending mouse events are processed.
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunAllPendingInMessageLoop();
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 110x111", target->bounds().ToString());
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.PressKey(ui::VKEY_ESCAPE, 0);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.ReleaseKey(ui::VKEY_ESCAPE, 0);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("0,0 100x100", target->bounds().ToString());
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verifies window minimization/maximization completes drag.
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Disabled crbug.com/166219.
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_MinimizeMaximizeCompletes DISABLED_MinimizeMaximizeCompletes
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_MinimizeMaximizeCompletes MinimizeMaximizeCompletes
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ToplevelWindowEventHandlerTest, MAYBE_MinimizeMaximizeCompletes) {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once window is minimized, window dragging completes.
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<aura::Window> target(CreateWindow(HTCAPTION));
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target->Focus();
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         target.get());
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.PressLeftButton();
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.MoveMouseBy(10, 11);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAllPendingInMessageLoop();
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("10,11 100x100", target->bounds().ToString());
66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    wm::WindowState* window_state = wm::GetWindowState(target.get());
66168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    window_state->Minimize();
66268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    window_state->Restore();
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.PressLeftButton();
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.MoveMouseBy(10, 11);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAllPendingInMessageLoop();
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("10,11 100x100", target->bounds().ToString());
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once window is maximized, window dragging completes.
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<aura::Window> target(CreateWindow(HTCAPTION));
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    target->Focus();
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         target.get());
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.PressLeftButton();
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.MoveMouseBy(10, 11);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAllPendingInMessageLoop();
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("10,11 100x100", target->bounds().ToString());
68068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    wm::WindowState* window_state = wm::GetWindowState(target.get());
68168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    window_state->Maximize();
68268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    window_state->Restore();
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.PressLeftButton();
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    generator.MoveMouseBy(10, 11);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAllPendingInMessageLoop();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("10,11 100x100", target->bounds().ToString());
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
691ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Test class for mouse and touch resize shadow tests.
692ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochclass ToplevelWindowEventHandlerResizeTest
693ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    : public ToplevelWindowEventHandlerTest {
694ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch public:
695ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ToplevelWindowEventHandlerResizeTest() : delegate_(NULL) {}
696ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual ~ToplevelWindowEventHandlerResizeTest() {}
697ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
698ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void SetUp() OVERRIDE {
699ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ToplevelWindowEventHandlerTest::SetUp();
700ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
701ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    delegate_ = new TestWindowDelegate(HTNOWHERE);
702ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    target_.reset(CreateTestWindowInShellWithDelegate(
703ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        delegate_, 0, gfx::Rect(0, 0, 100, 100)));
704ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Add a child window to |target_| in order to properly test that the resize
7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // shadows are shown when the mouse is ash::kResizeInsideBoundsSize inside
7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // |target_|'s edges.
7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    aura::Window* child = CreateTestWindowInShell(
7094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        SK_ColorWHITE, 0, gfx::Rect(0, 10, 100, 90));
7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    target_->AddChild(child);
7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gfx::Insets mouse_outer_insets(-ash::kResizeOutsideBoundsSize,
7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   -ash::kResizeOutsideBoundsSize,
7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   -ash::kResizeOutsideBoundsSize,
7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   -ash::kResizeOutsideBoundsSize);
7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    gfx::Insets touch_outer_insets =
7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        mouse_outer_insets.Scale(ash::kResizeOutsideBoundsScaleForTouch);
7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    target_->SetHitTestBoundsOverrideOuter(mouse_outer_insets,
7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                           touch_outer_insets);
7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    target_->set_hit_test_bounds_override_inner(
7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        gfx::Insets(ash::kResizeInsideBoundsSize,
7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    ash::kResizeInsideBoundsSize,
7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    ash::kResizeInsideBoundsSize,
7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                    ash::kResizeInsideBoundsSize));
725ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
726ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
727ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  virtual void TearDown() OVERRIDE {
728ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    target_.reset();
729ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    ToplevelWindowEventHandlerTest::TearDown();
730ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
731ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
732ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Called on each scroll event. Checks if the correct resize shadow is shown.
733ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void ProcessEvent(ui::EventType type, const gfx::Vector2dF& delta) {
734ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    if (type == ui::ET_GESTURE_SCROLL_END) {
735ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // After gesture scroll ends, there should be no resize shadow.
736ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_FALSE(HasResizeShadow());
737ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    } else {
738ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      // Check if there is a resize shadow under the correct border.
739ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      ASSERT_TRUE(HasResizeShadow());
740ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      EXPECT_EQ(HTBOTTOMRIGHT, ResizeShadowLastHitTest());
741ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
742ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
743ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
744ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch protected:
745ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  void SetHittestCode(int hittest_code) {
746ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    delegate_->set_window_component(hittest_code);
747ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
748ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
749ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  aura::Window* target() { return target_.get(); }
750ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
751ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  bool HasResizeShadow() const {
752ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // There is no shadow if no ResizeShadow object is associated with the
753ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // window or there is one but its hit test is set to HTNOWHERE. Since we
754ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // don't want to tie tests to that implementation detail, both cases are
755ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    // considered here.
756ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return ResizeShadow() && ResizeShadowLastHitTest() != HTNOWHERE;
757ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
758ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
759ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  int ResizeShadowLastHitTest() const {
760ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return ResizeShadow()->GetLastHitTestForTest();
761ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
762ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
763ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch private:
764ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  internal::ResizeShadow* ResizeShadow() const {
765ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    return Shell::GetInstance()->resize_shadow_controller()->
766ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        GetShadowForWindowForTest(target_.get());
767ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
768ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
769ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  TestWindowDelegate* delegate_;
770ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  scoped_ptr<aura::Window> target_;
771ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
772ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ToplevelWindowEventHandlerResizeTest);
773ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch};
774ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
775ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Tests resize shadows for touch resizing.
776ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ToplevelWindowEventHandlerResizeTest, TouchResizeShadows) {
777ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), target());
778ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
779ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Drag bottom right border of the window and check for the resize shadows.
780ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Shadows are checked in the callback function.
781ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetHittestCode(HTBOTTOMRIGHT);
782ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  generator.GestureScrollSequenceWithCallback(
783ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      gfx::Point(105, 105),
784ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      gfx::Point(150, 150),
785ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      base::TimeDelta::FromMilliseconds(100),
786ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      3,
787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      base::Bind(&ToplevelWindowEventHandlerResizeTest::ProcessEvent,
788ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                 base::Unretained(this)));
789ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  RunAllPendingInMessageLoop();
790ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
791ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
792ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Tests resize shadows for mouse resizing.
793ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(ToplevelWindowEventHandlerResizeTest, MouseResizeShadows) {
794ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(), target());
795ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
796ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // There should be no shadow at the beginning.
797ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(HasResizeShadow());
798ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
799ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Move mouse over the right border. Shadows should appear.
800ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetHittestCode(HTRIGHT);
801ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  generator.MoveMouseTo(gfx::Point(100, 50));
802ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(HasResizeShadow());
803ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(HTRIGHT, ResizeShadowLastHitTest());
804ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
805ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Move mouse over the bottom right border. Shadows should stay.
806ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetHittestCode(HTBOTTOMRIGHT);
807ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  generator.MoveMouseTo(100, 100);
808ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(HasResizeShadow());
809ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(HTBOTTOMRIGHT, ResizeShadowLastHitTest());
810ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
811ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Move mouse into the window. Shadows should disappear.
812ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetHittestCode(HTCLIENT);
813ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  generator.MoveMouseTo(50, 50);
814ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(HasResizeShadow());
815ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
816ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Move mouse over the bottom order. Shadows should reappear.
817ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetHittestCode(HTBOTTOM);
818ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  generator.MoveMouseTo(50, 100);
819ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_TRUE(HasResizeShadow());
820ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(HTBOTTOM, ResizeShadowLastHitTest());
821ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Move the mouse outside the bottom border but still within the window's
8234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // resize area.
8244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator.MoveMouseTo(50, 100 + ash::kResizeOutsideBoundsSize - 1);
8254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(HasResizeShadow());
8264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(HTBOTTOM, ResizeShadowLastHitTest());
8274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Move the mouse above the bottom border but still within the window's
8294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // resize area.
8304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator.MoveMouseTo(50, 100 - ash::kResizeInsideBoundsSize);
8314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(HasResizeShadow());
8324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(HTBOTTOM, ResizeShadowLastHitTest());
8334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
834ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Move mouse out of the window. Shadows should disappear.
835ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  generator.MoveMouseTo(150, 150);
836ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_FALSE(HasResizeShadow());
837ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
838ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  RunAllPendingInMessageLoop();
839ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
840ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace test
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
843