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/system_gesture_event_filter.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <vector>
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/accelerators/accelerator_controller.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/display/display_manager.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_model.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/system/tray/system_tray_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/test/ash_test_base.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/test/display_manager_test_api.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/test/shell_test_api.h"
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/test/test_shelf_delegate.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/gestures/long_press_affordance_handler.h"
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_util.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/env.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/event_generator.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/test/test_windows.h"
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/hit_test.h"
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/events/event_handler.h"
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/event_utils.h"
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/events/gestures/gesture_configuration.h"
3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/events/test/test_event_handler.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/screen.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h"
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/widget/widget.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget_delegate.h"
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/window/non_client_view.h"
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/window/window_button_order_provider.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace test {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ResizableWidgetDelegate : public views::WidgetDelegateView {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResizableWidgetDelegate() {}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ResizableWidgetDelegate() {}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool CanResize() const OVERRIDE { return true; }
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanMaximize() const OVERRIDE { return true; }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void DeleteDelegate() OVERRIDE { delete this; }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ResizableWidgetDelegate);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Support class for testing windows with a maximum size.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MaxSizeNCFV : public views::NonClientFrameView {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MaxSizeNCFV() {}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual gfx::Size GetMaximumSize() const OVERRIDE {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::Size(200, 200);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual gfx::Rect GetBoundsForClientView() const OVERRIDE {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::Rect();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual gfx::Rect GetWindowBoundsForClientBounds(
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const gfx::Rect& client_bounds) const OVERRIDE {
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return gfx::Rect();
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This function must ask the ClientView to do a hittest.  We don't do this in
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the parent NonClientView because that makes it more difficult to calculate
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // hittests for regions that are partially obscured by the ClientView, e.g.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTSYSMENU.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int NonClientHitTest(const gfx::Point& point) OVERRIDE {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return HTNOWHERE;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetWindowMask(const gfx::Size& size,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             gfx::Path* window_mask) OVERRIDE {}
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ResetWindowControls() OVERRIDE {}
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void UpdateWindowIcon() OVERRIDE {}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void UpdateWindowTitle() OVERRIDE {}
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MaxSizeNCFV);
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MaxSizeWidgetDelegate : public views::WidgetDelegateView {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MaxSizeWidgetDelegate() {}
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MaxSizeWidgetDelegate() {}
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanResize() const OVERRIDE { return true; }
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool CanMaximize() const OVERRIDE { return false; }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DeleteDelegate() OVERRIDE { delete this; }
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual views::NonClientFrameView* CreateNonClientFrameView(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      views::Widget* widget) OVERRIDE {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new MaxSizeNCFV;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MaxSizeWidgetDelegate);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class SystemGestureEventFilterTest : public AshTestBase {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SystemGestureEventFilterTest() : AshTestBase() {}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SystemGestureEventFilterTest() {}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  LongPressAffordanceHandler* GetLongPressAffordance() {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShellTestApi shell_test(Shell::GetInstance());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return shell_test.system_gesture_event_filter()->
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        long_press_affordance_.get();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::OneShotTimer<LongPressAffordanceHandler>*
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  GetLongPressAffordanceTimer() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &GetLongPressAffordance()->timer_;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* GetLongPressAffordanceTarget() {
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return GetLongPressAffordance()->tap_down_target_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::View* GetLongPressAffordanceView() {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return reinterpret_cast<views::View*>(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetLongPressAffordance()->view_.get());
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from AshTestBase:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // TODO(jonross): TwoFingerDragDelayed() and ThreeFingerGestureStopsDrag()
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // both use hardcoded touch points, assuming that they target empty header
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // space. Window control order now reflects configuration files and can
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // change. The tests should be improved to dynamically decide touch points.
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // To address this we specify the originally expected window control
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // positions to be consistent across tests.
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<views::FrameButton> leading;
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<views::FrameButton> trailing;
147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    trailing.push_back(views::FRAME_BUTTON_MINIMIZE);
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    trailing.push_back(views::FRAME_BUTTON_MAXIMIZE);
149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    trailing.push_back(views::FRAME_BUTTON_CLOSE);
150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    views::WindowButtonOrderProvider::GetInstance()->
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        SetWindowButtonOrder(leading, trailing);
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test::AshTestBase::SetUp();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Enable brightness key.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    test::DisplayManagerTestApi(Shell::GetInstance()->display_manager()).
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SetFirstDisplayAsInternalDisplay();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SystemGestureEventFilterTest);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::GestureEvent* CreateGesture(ui::EventType type,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int y,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    float delta_x,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    float delta_y,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int touch_id) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ui::GestureEvent(type, x, y, 0,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(base::Time::Now().ToDoubleT() * 1000),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::GestureEventDetails(type, delta_x, delta_y), 1 << touch_id);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, LongPressAffordanceStateOnCaptureLoss) {
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::TestWindowDelegate delegate;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window0(
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aura::test::CreateTestWindowWithDelegate(
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &delegate, 9, gfx::Rect(0, 0, 100, 100), root_window));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window1(
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aura::test::CreateTestWindowWithDelegate(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &delegate, 10, gfx::Rect(0, 0, 100, 50), window0.get()));
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<aura::Window> window2(
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      aura::test::CreateTestWindowWithDelegate(
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &delegate, 11, gfx::Rect(0, 50, 100, 50), window0.get()));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kTouchId = 5;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Capture first window.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window1->SetCapture();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window1->HasCapture());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send touch event to first window.
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       gfx::Point(10, 10),
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       kTouchId,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       ui::EventTimeForNow());
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ui::EventDispatchDetails details =
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      root_window->GetHost()->dispatcher()->OnEventFromSource(&press);
2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(details.dispatcher_destroyed);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window1->HasCapture());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::OneShotTimer<LongPressAffordanceHandler>* timer =
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetLongPressAffordanceTimer();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(timer->IsRunning());
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(window1, GetLongPressAffordanceTarget());
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force timeout so that the affordance animation can start.
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timer->user_task().Run();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timer->Stop();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetLongPressAffordance()->is_animating());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change capture.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window2->SetCapture();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window2->HasCapture());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetLongPressAffordance()->is_animating());
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(window1, GetLongPressAffordanceTarget());
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Animate to completion.
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetLongPressAffordance()->End();  // end grow animation.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force timeout to start shrink animation.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(timer->IsRunning());
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timer->user_task().Run();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  timer->Stop();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(GetLongPressAffordance()->is_animating());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetLongPressAffordance()->End();  // end shrink animation.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if state has reset.
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(NULL, GetLongPressAffordanceTarget());
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(NULL, GetLongPressAffordanceView());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, TwoFingerDrag) {
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Rect bounds(0, 0, 600, 600);
2371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ResizableWidgetDelegate, root_window, bounds);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kSteps = 15;
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kTouchPoints = 2;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point points[kTouchPoints] = {
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Point(250, 250),
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    gfx::Point(350, 350),
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::EventGenerator generator(root_window,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       toplevel->GetNativeWindow());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* toplevel_state =
25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      wm::GetWindowState(toplevel->GetNativeWindow());
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swipe down to minimize.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150);
25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(toplevel_state->IsMinimized());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Restore();
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->GetNativeWindow()->SetBounds(bounds);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swipe up to maximize.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, -150);
26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(toplevel_state->IsMaximized());
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Restore();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->GetNativeWindow()->SetBounds(bounds);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swipe right to snap.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect normal_bounds = toplevel->GetWindowBoundsInScreen();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect right_tile_bounds = toplevel->GetWindowBoundsInScreen();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(normal_bounds.ToString(), right_tile_bounds.ToString());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swipe left to snap.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point left_points[kTouchPoints];
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kTouchPoints; ++i) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    left_points[i] = points[i];
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    left_points[i].Offset(right_tile_bounds.x(), right_tile_bounds.y());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, left_points, 15, kSteps,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      -150, 0);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect left_tile_bounds = toplevel->GetWindowBoundsInScreen();
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(normal_bounds.ToString(), left_tile_bounds.ToString());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(right_tile_bounds.ToString(), left_tile_bounds.ToString());
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swipe right again.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect current_bounds = toplevel->GetWindowBoundsInScreen();
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_NE(current_bounds.ToString(), left_tile_bounds.ToString());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(current_bounds.ToString(), right_tile_bounds.ToString());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, TwoFingerDragTwoWindows) {
2941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::GestureConfiguration::set_max_separation_for_gesture_touches_in_pixels(0);
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* first = views::Widget::CreateWindowWithContextAndBounds(
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new ResizableWidgetDelegate, root_window, gfx::Rect(10, 0, 50, 100));
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first->Show();
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* second = views::Widget::CreateWindowWithContextAndBounds(
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ResizableWidgetDelegate, root_window, gfx::Rect(100, 0, 100, 100));
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  second->Show();
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start a two-finger drag on |first|, and then try to use another two-finger
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // drag to move |second|. The attempt to move |second| should fail.
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& first_bounds = first->GetWindowBoundsInScreen();
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::Rect& second_bounds = second->GetWindowBoundsInScreen();
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kSteps = 15;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kTouchPoints = 4;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point points[kTouchPoints] = {
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    first_bounds.origin() + gfx::Vector2d(5, 5),
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    first_bounds.origin() + gfx::Vector2d(30, 10),
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    second_bounds.origin() + gfx::Vector2d(5, 5),
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    second_bounds.origin() + gfx::Vector2d(40, 20)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::EventGenerator generator(root_window);
3171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Do not drag too fast to avoid fling.
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points,
3191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      50, kSteps, 0, 150);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(first_bounds.ToString(),
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            first->GetWindowBoundsInScreen().ToString());
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(second_bounds.ToString(),
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            second->GetWindowBoundsInScreen().ToString());
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, WindowsWithMaxSizeDontSnap) {
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect bounds(250, 150, 100, 100);
3291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new MaxSizeWidgetDelegate, root_window, bounds);
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->Show();
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kSteps = 15;
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kTouchPoints = 2;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point points[kTouchPoints] = {
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point(bounds.x() + 10, bounds.y() + 30),
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point(bounds.x() + 30, bounds.y() + 20),
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  aura::test::EventGenerator generator(root_window,
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       toplevel->GetNativeWindow());
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Swipe down to minimize.
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150);
34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  wm::WindowState* toplevel_state =
34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      wm::GetWindowState(toplevel->GetNativeWindow());
34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_TRUE(toplevel_state->IsMinimized());
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->Restore();
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->GetNativeWindow()->SetBounds(bounds);
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that swiping up doesn't maximize.
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, -150);
35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_FALSE(toplevel_state->IsMaximized());
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->Restore();
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->GetNativeWindow()->SetBounds(bounds);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that swiping right doesn't snap.
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Rect normal_bounds = toplevel->GetWindowBoundsInScreen();
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0);
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  normal_bounds.set_x(normal_bounds.x() + 150);
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(normal_bounds.ToString(),
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      toplevel->GetWindowBoundsInScreen().ToString());
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->GetNativeWindow()->SetBounds(bounds);
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check that swiping left doesn't snap.
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  normal_bounds = toplevel->GetWindowBoundsInScreen();
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, -150, 0);
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  normal_bounds.set_x(normal_bounds.x() - 150);
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(normal_bounds.ToString(),
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      toplevel->GetWindowBoundsInScreen().ToString());
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  toplevel->GetNativeWindow()->SetBounds(bounds);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Swipe right again, make sure the window still doesn't snap.
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  normal_bounds = toplevel->GetWindowBoundsInScreen();
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  normal_bounds.set_x(normal_bounds.x() + 150);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 150, 0);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(normal_bounds.ToString(),
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      toplevel->GetWindowBoundsInScreen().ToString());
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, DISABLED_TwoFingerDragEdge) {
387f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Rect bounds(0, 0, 200, 100);
3881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new ResizableWidgetDelegate, root_window, bounds);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  toplevel->Show();
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kSteps = 15;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kTouchPoints = 2;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point points[kTouchPoints] = {
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Point(30, 20),  // Caption
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Point(0, 40),   // Left edge
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()->
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      GetNonClientComponent(points[0]));
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(HTLEFT, toplevel->GetNativeWindow()->delegate()->
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetNonClientComponent(points[1]));
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aura::test::EventGenerator generator(root_window,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       toplevel->GetNativeWindow());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds = toplevel->GetNativeWindow()->bounds();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Swipe down. Nothing should happen.
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  generator.GestureMultiFingerScroll(kTouchPoints, points, 15, kSteps, 0, 150);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(),
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            toplevel->GetNativeWindow()->bounds().ToString());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// We do not allow resizing a window via multiple edges simultaneously. Test
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that the behavior is reasonable if a user attempts to resize a window via
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// several edges.
418cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest,
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       TwoFingerAttemptResizeLeftAndRightEdgesSimultaneously) {
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect initial_bounds(0, 0, 400, 400);
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  views::Widget* toplevel =
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      views::Widget::CreateWindowWithContextAndBounds(
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          new ResizableWidgetDelegate, CurrentContext(), initial_bounds);
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  toplevel->Show();
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kSteps = 15;
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const int kTouchPoints = 2;
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point points[kTouchPoints] = {
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::Point(0, 40),    // Left edge
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::Point(399, 40),  // Right edge
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int delays[kTouchPoints] = {0, 120};
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(HTLEFT, toplevel->GetNonClientComponent(points[0]));
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(HTRIGHT, toplevel->GetNonClientComponent(points[1]));
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetEventGenerator().GestureMultiFingerScrollWithDelays(
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      kTouchPoints, points, delays, 15, kSteps, 0, 40);
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The window bounds should not have changed because neither of the fingers
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // moved horizontally.
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(initial_bounds.ToString(),
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            toplevel->GetNativeWindow()->bounds().ToString());
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, TwoFingerDragDelayed) {
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Rect bounds(0, 0, 200, 100);
4481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
4491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
4501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new ResizableWidgetDelegate, root_window, bounds);
4511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  toplevel->Show();
4521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int kSteps = 15;
4541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int kTouchPoints = 2;
4551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Point points[kTouchPoints] = {
4561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Point(30, 20),  // Caption
4571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Point(34, 20),  // Caption
4581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  };
4591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int delays[kTouchPoints] = {0, 120};
4601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()->
4621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        GetNonClientComponent(points[0]));
4631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()->
4641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        GetNonClientComponent(points[1]));
4651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::test::EventGenerator generator(root_window,
4671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                       toplevel->GetNativeWindow());
4681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bounds = toplevel->GetNativeWindow()->bounds();
4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swipe right and down starting with one finger.
4711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Add another finger after 120ms and continue dragging.
4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The window should move and the drag should be determined by the center
4731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // point between the fingers.
4741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  generator.GestureMultiFingerScrollWithDelays(
4751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      kTouchPoints, points, delays, 15, kSteps, 150, 150);
4761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bounds += gfx::Vector2d(150 + (points[1].x() - points[0].x()) / 2, 150);
4771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(),
4781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            toplevel->GetNativeWindow()->bounds().ToString());
4791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
481cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, ThreeFingerGestureStopsDrag) {
482cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  gfx::Rect bounds(0, 0, 200, 100);
4831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
4841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
4851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new ResizableWidgetDelegate, root_window, bounds);
4861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  toplevel->Show();
4871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int kSteps = 10;
4891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int kTouchPoints = 3;
4901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  gfx::Point points[kTouchPoints] = {
4911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Point(30, 20),  // Caption
4921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Point(34, 20),  // Caption
4931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    gfx::Point(38, 20),  // Caption
4941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  };
4951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int delays[kTouchPoints] = {0, 0, 120};
4961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()->
4981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        GetNonClientComponent(points[0]));
4991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(HTCAPTION, toplevel->GetNativeWindow()->delegate()->
5001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        GetNonClientComponent(points[1]));
5011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  aura::test::EventGenerator generator(root_window,
5031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                       toplevel->GetNativeWindow());
5041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bounds = toplevel->GetNativeWindow()->bounds();
5061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Swipe right and down starting with two fingers.
5071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Add third finger after 120ms and continue dragging.
5081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // The window should start moving but stop when the 3rd finger touches down.
5091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const int kEventSeparation = 15;
5101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  generator.GestureMultiFingerScrollWithDelays(
5111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      kTouchPoints, points, delays, kEventSeparation, kSteps, 150, 150);
5121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int expected_drag = 150 / kSteps * 120 / kEventSeparation;
5131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bounds += gfx::Vector2d(expected_drag, expected_drag);
5141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_EQ(bounds.ToString(),
5151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)            toplevel->GetNativeWindow()->bounds().ToString());
5161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
5171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
518cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, DragLeftNearEdgeSnaps) {
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect bounds(200, 150, 400, 100);
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new ResizableWidgetDelegate, root_window, bounds);
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  toplevel->Show();
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kSteps = 15;
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kTouchPoints = 2;
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point points[kTouchPoints] = {
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
531a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* toplevel_window = toplevel->GetNativeWindow();
532a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::test::EventGenerator generator(root_window, toplevel_window);
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Check that dragging left snaps before reaching the screen edge.
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect work_area =
536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Shell::GetScreen()->GetDisplayNearestWindow(root_window).work_area();
537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int drag_x = work_area.x() + 20 - points[0].x();
538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.GestureMultiFingerScroll(
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      kTouchPoints, points, 120, kSteps, drag_x, 0);
540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
541a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(wm::GetDefaultLeftSnappedWindowBoundsInParent(
542a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                toplevel_window).ToString(),
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            toplevel_window->bounds().ToString());
544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest, DragRightNearEdgeSnaps) {
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect bounds(200, 150, 400, 100);
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  views::Widget* toplevel = views::Widget::CreateWindowWithContextAndBounds(
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new ResizableWidgetDelegate, root_window, bounds);
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  toplevel->Show();
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kSteps = 15;
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const int kTouchPoints = 2;
555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point points[kTouchPoints] = {
556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
559a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::Window* toplevel_window = toplevel->GetNativeWindow();
560a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  aura::test::EventGenerator generator(root_window, toplevel_window);
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Check that dragging right snaps before reaching the screen edge.
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect work_area =
564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Shell::GetScreen()->GetDisplayNearestWindow(root_window).work_area();
565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int drag_x = work_area.right() - 20 - points[0].x();
566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.GestureMultiFingerScroll(
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      kTouchPoints, points, 120, kSteps, drag_x, 0);
568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(wm::GetDefaultRightSnappedWindowBoundsInParent(
569a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                toplevel_window).ToString(),
570a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            toplevel_window->bounds().ToString());
571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Tests that the window manager does not consume gesture events targeted to
5745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// windows of type WINDOW_TYPE_CONTROL. This is important because the web
5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// contents are often (but not always) of type WINDOW_TYPE_CONTROL.
576cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(SystemGestureEventFilterTest,
5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ControlWindowGetsMultiFingerGestureEvents) {
5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> parent(
5795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CreateTestWindowInShellWithBounds(gfx::Rect(100, 100)));
5805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::test::EventCountDelegate delegate;
5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delegate.set_window_component(HTCLIENT);
5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<aura::Window> child(new aura::Window(&delegate));
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->SetType(ui::wm::WINDOW_TYPE_CONTROL);
5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->Init(aura::WINDOW_LAYER_TEXTURED);
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  parent->AddChild(child.get());
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->SetBounds(gfx::Rect(100, 100));
5885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  child->Show();
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
59023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ui::test::TestEventHandler event_handler;
5915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Env::GetInstance()->PrependPreTargetHandler(&event_handler);
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetEventGenerator().MoveMouseTo(0, 0);
5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 1; i <= 3; ++i)
5955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetEventGenerator().PressTouchId(i);
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (int i = 1; i <= 3; ++i)
5975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetEventGenerator().ReleaseTouchId(i);
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(event_handler.num_gesture_events(),
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            delegate.GetGestureCountAndReset());
6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  aura::Env::GetInstance()->RemovePreTargetHandler(&event_handler);
6025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace test
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
606