summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authorskuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-18 21:48:32 +0000
committerskuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-18 21:48:32 +0000
commita390331c41538fb075438294ff716464a0473123 (patch)
tree5736a9bd9c0c7bc2093116750037f387e6326201 /ash
parent0cd1d65299b6bb59a3820cba996356cc54c06491 (diff)
downloadchromium_src-a390331c41538fb075438294ff716464a0473123.zip
chromium_src-a390331c41538fb075438294ff716464a0473123.tar.gz
chromium_src-a390331c41538fb075438294ff716464a0473123.tar.bz2
Adding four bezel gestures
BUG=126061, 126060, 123167 TEST=Unit test Review URL: https://chromiumcodereview.appspot.com/10383108 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@137968 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/accelerators/accelerator_controller.h4
-rw-r--r--ash/accelerators/accelerator_controller_unittest.cc2
-rw-r--r--ash/test/test_launcher_delegate.cc7
-rw-r--r--ash/test/test_launcher_delegate.h1
-rw-r--r--ash/volume_control_delegate.h4
-rw-r--r--ash/wm/system_gesture_event_filter.cc123
-rw-r--r--ash/wm/system_gesture_event_filter.h39
-rw-r--r--ash/wm/system_gesture_event_filter_unittest.cc295
8 files changed, 473 insertions, 2 deletions
diff --git a/ash/accelerators/accelerator_controller.h b/ash/accelerators/accelerator_controller.h
index 1c8193d..df47427 100644
--- a/ash/accelerators/accelerator_controller.h
+++ b/ash/accelerators/accelerator_controller.h
@@ -77,6 +77,10 @@ class ASH_EXPORT AcceleratorController : public ui::AcceleratorTarget {
return brightness_control_delegate_.get();
}
+ VolumeControlDelegate* volume_control_delegate() const {
+ return volume_control_delegate_.get();
+ }
+
private:
// Initializes the accelerators this class handles as a target.
void Init();
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index c4ffe7f..54b6f82 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -142,6 +142,8 @@ class DummyVolumeControlDelegate : public VolumeControlDelegate {
last_accelerator_ = accelerator;
return consume_;
}
+ virtual void SetVolumePercent(double percent) OVERRIDE {
+ }
int handle_volume_mute_count() const {
return handle_volume_mute_count_;
diff --git a/ash/test/test_launcher_delegate.cc b/ash/test/test_launcher_delegate.cc
index bb5f0d2..cec42a7 100644
--- a/ash/test/test_launcher_delegate.cc
+++ b/ash/test/test_launcher_delegate.cc
@@ -26,12 +26,19 @@ TestLauncherDelegate::~TestLauncherDelegate() {
}
void TestLauncherDelegate::AddLauncherItem(aura::Window* window) {
+ AddLauncherItem(window, STATUS_CLOSED);
+}
+
+void TestLauncherDelegate::AddLauncherItem(
+ aura::Window* window,
+ LauncherItemStatus status) {
ash::LauncherItem item;
item.type = ash::TYPE_TABBED;
DCHECK(window_to_id_.find(window) == window_to_id_.end());
window_to_id_[window] = model_->next_id();
item.image.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
item.image.allocPixels();
+ item.status = status;
model_->Add(item);
if (observed_windows_.find(window->parent()) == observed_windows_.end()) {
window->parent()->AddObserver(this);
diff --git a/ash/test/test_launcher_delegate.h b/ash/test/test_launcher_delegate.h
index 7cc0203..f56be8f 100644
--- a/ash/test/test_launcher_delegate.h
+++ b/ash/test/test_launcher_delegate.h
@@ -28,6 +28,7 @@ class TestLauncherDelegate : public LauncherDelegate,
virtual ~TestLauncherDelegate();
void AddLauncherItem(aura::Window* window);
+ void AddLauncherItem(aura::Window* window, LauncherItemStatus status);
static TestLauncherDelegate* instance() { return instance_; }
diff --git a/ash/volume_control_delegate.h b/ash/volume_control_delegate.h
index 46b3cf3..d922ea6 100644
--- a/ash/volume_control_delegate.h
+++ b/ash/volume_control_delegate.h
@@ -20,6 +20,10 @@ class VolumeControlDelegate {
virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) = 0;
virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) = 0;
virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) = 0;
+
+ // Requests that the volume be set to |percent|, in the range
+ // [0.0, 100.0].
+ virtual void SetVolumePercent(double percent) = 0;
};
} // namespace ash
diff --git a/ash/wm/system_gesture_event_filter.cc b/ash/wm/system_gesture_event_filter.cc
index 1568052..abf1ee8 100644
--- a/ash/wm/system_gesture_event_filter.cc
+++ b/ash/wm/system_gesture_event_filter.cc
@@ -5,14 +5,22 @@
#include "ash/wm/system_gesture_event_filter.h"
#include "ash/shell.h"
+#include "ash/accelerators/accelerator_controller.h"
+#include "ash/system/brightness/brightness_control_delegate.h"
+#include "ash/volume_control_delegate.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
+#include "ui/gfx/screen.h"
namespace ash {
namespace internal {
SystemGestureEventFilter::SystemGestureEventFilter()
- : aura::EventFilter() {
+ : aura::EventFilter(),
+ overlap_percent_(5),
+ start_location_(BEZEL_START_UNSET),
+ orientation_(SCROLL_ORIENTATION_UNSET),
+ is_scrubbing_(false){
}
SystemGestureEventFilter::~SystemGestureEventFilter() {
@@ -39,10 +47,121 @@ ui::GestureStatus SystemGestureEventFilter::PreHandleGestureEvent(
// TODO(tdresser) handle system level gesture events
if (event->type() == ui::ET_GESTURE_THREE_FINGER_SWIPE)
return ui::GESTURE_STATUS_CONSUMED;
- if (target == Shell::GetRootWindow())
+ if (!target || target == Shell::GetRootWindow()) {
+ switch (event->type()) {
+ case ui::ET_GESTURE_SCROLL_BEGIN: {
+ gfx::Rect screen =
+ gfx::Screen::GetPrimaryMonitor().bounds();
+ int overlap_area = screen.width() * overlap_percent_ / 100;
+ orientation_ = SCROLL_ORIENTATION_UNSET;
+
+ if (event->x() <= screen.x() + overlap_area) {
+ start_location_ = BEZEL_START_LEFT;
+ } else if (event->x() >= screen.right() - overlap_area) {
+ start_location_ = BEZEL_START_RIGHT;
+ } else if (event->y() >= screen.bottom()) {
+ start_location_ = BEZEL_START_BOTTOM;
+ }
+ }
+ break;
+ case ui::ET_GESTURE_SCROLL_UPDATE:
+ if (start_location_ == BEZEL_START_UNSET)
+ break;
+ if (orientation_ == SCROLL_ORIENTATION_UNSET) {
+ if (!event->delta_x() && !event->delta_y())
+ break;
+ // For left and right the scroll angle needs to be much steeper to
+ // be accepted for a 'device configuration' gesture.
+ if (start_location_ == BEZEL_START_LEFT ||
+ start_location_ == BEZEL_START_RIGHT) {
+ orientation_ = abs(event->delta_y()) > abs(event->delta_x()) * 3 ?
+ SCROLL_ORIENTATION_VERTICAL : SCROLL_ORIENTATION_HORIZONTAL;
+ } else {
+ orientation_ = abs(event->delta_y()) > abs(event->delta_x()) ?
+ SCROLL_ORIENTATION_VERTICAL : SCROLL_ORIENTATION_HORIZONTAL;
+ }
+ }
+ if (orientation_ == SCROLL_ORIENTATION_HORIZONTAL) {
+ if (HandleApplicationControl(event))
+ start_location_ = BEZEL_START_UNSET;
+ } else {
+ if (start_location_ == BEZEL_START_BOTTOM) {
+ if (HandleLauncherControl(event))
+ start_location_ = BEZEL_START_UNSET;
+ } else {
+ if (HandleDeviceControl(event))
+ start_location_ = BEZEL_START_UNSET;
+ }
+ }
+ break;
+ case ui::ET_GESTURE_SCROLL_END:
+ start_location_ = BEZEL_START_UNSET;
+ break;
+ default:
+ break;
+ }
return ui::GESTURE_STATUS_CONSUMED;
+ }
return ui::GESTURE_STATUS_UNKNOWN;
}
+bool SystemGestureEventFilter::HandleDeviceControl(aura::GestureEvent* event) {
+ gfx::Rect screen = gfx::Screen::GetPrimaryMonitor().bounds();
+ double percent = 100.0 * (event->y() - screen.y()) / screen.height();
+ if (percent > 100.0)
+ percent = 100.0;
+ if (percent < 0.0)
+ percent = 0.0;
+ ash::AcceleratorController* accelerator =
+ ash::Shell::GetInstance()->accelerator_controller();
+ if (start_location_ == BEZEL_START_LEFT) {
+ ash::BrightnessControlDelegate* delegate =
+ accelerator->brightness_control_delegate();
+ if (delegate)
+ delegate->SetBrightnessPercent(100.0 - percent, true);
+ } else if (start_location_ == BEZEL_START_RIGHT) {
+ ash::VolumeControlDelegate* delegate =
+ accelerator->volume_control_delegate();
+ if (delegate)
+ delegate->SetVolumePercent(100.0 - percent);
+ } else {
+ return true;
+ }
+ // More notifications can be send.
+ return false;
+}
+
+bool SystemGestureEventFilter::HandleLauncherControl(
+ aura::GestureEvent* event) {
+ ash::AcceleratorController* accelerator =
+ ash::Shell::GetInstance()->accelerator_controller();
+ if (start_location_ == BEZEL_START_BOTTOM && event->delta_y() < 0)
+ // We leave the work to switch to the next window to our accelerators.
+ accelerator->AcceleratorPressed(
+ ui::Accelerator(ui::VKEY_LWIN, false, true, false));
+ else
+ return false;
+ // No further notifications for this gesture.
+ return true;
+}
+
+bool SystemGestureEventFilter::HandleApplicationControl(
+ aura::GestureEvent* event) {
+ ash::AcceleratorController* accelerator =
+ ash::Shell::GetInstance()->accelerator_controller();
+ if (start_location_ == BEZEL_START_LEFT && event->delta_x() > 0)
+ // We leave the work to switch to the next window to our accelerators.
+ accelerator->AcceleratorPressed(
+ ui::Accelerator(ui::VKEY_F5, true, false, false));
+ else if (start_location_ == BEZEL_START_RIGHT && event->delta_x() < 0)
+ // We leave the work to switch to the previous window to our accelerators.
+ accelerator->AcceleratorPressed(
+ ui::Accelerator(ui::VKEY_F5, false, false, false));
+ else
+ return false;
+ // No further notifications for this gesture.
+ return true;
+}
+
} // namespace internal
} // namespace ash
diff --git a/ash/wm/system_gesture_event_filter.h b/ash/wm/system_gesture_event_filter.h
index fe58711..f240691 100644
--- a/ash/wm/system_gesture_event_filter.h
+++ b/ash/wm/system_gesture_event_filter.h
@@ -18,6 +18,20 @@ class Window;
namespace ash {
namespace internal {
+enum BezelStart {
+ BEZEL_START_UNSET = 0,
+ BEZEL_START_TOP,
+ BEZEL_START_LEFT,
+ BEZEL_START_RIGHT,
+ BEZEL_START_BOTTOM
+};
+
+enum ScrollOrientation {
+ SCROLL_ORIENTATION_UNSET = 0,
+ SCROLL_ORIENTATION_HORIZONTAL,
+ SCROLL_ORIENTATION_VERTICAL
+};
+
// An event filter which handles system level gesture events.
class SystemGestureEventFilter : public aura::EventFilter {
public:
@@ -36,6 +50,31 @@ class SystemGestureEventFilter : public aura::EventFilter {
aura::GestureEvent* event) OVERRIDE;
private:
+ // Handle events meant for volume / brightness. Returns true when no further
+ // events from this gesture should be sent.
+ bool HandleDeviceControl(aura::GestureEvent* event);
+
+ // Handle events meant for showing the launcher. Returns true when no further
+ // events from this gesture should be sent.
+ bool HandleLauncherControl(aura::GestureEvent* event);
+
+ // Handle events meant to switch through applications. Returns true when no
+ // further events from this gesture should be sent.
+ bool HandleApplicationControl(aura::GestureEvent* event);
+
+ // The percentage of the screen to the left and right which belongs to
+ // device gestures.
+ const int overlap_percent_;
+
+ // Which bezel corner are we on.
+ BezelStart start_location_;
+
+ // Which orientation are we moving.
+ ScrollOrientation orientation_;
+
+ // A device swipe gesture is in progress.
+ bool is_scrubbing_;
+
DISALLOW_COPY_AND_ASSIGN(SystemGestureEventFilter);
};
diff --git a/ash/wm/system_gesture_event_filter_unittest.cc b/ash/wm/system_gesture_event_filter_unittest.cc
index 8e26aec..6ef332d 100644
--- a/ash/wm/system_gesture_event_filter_unittest.cc
+++ b/ash/wm/system_gesture_event_filter_unittest.cc
@@ -4,13 +4,96 @@
#include "ash/wm/system_gesture_event_filter.h"
+#include "ash/accelerators/accelerator_controller.h"
+#include "ash/launcher/launcher.h"
+#include "ash/launcher/launcher_model.h"
#include "ash/shell.h"
+#include "ash/system/brightness/brightness_control_delegate.h"
#include "ash/test/ash_test_base.h"
+#include "ash/test/test_launcher_delegate.h"
+#include "ash/volume_control_delegate.h"
+#include "ash/wm/window_util.h"
#include "base/time.h"
+#include "ui/gfx/screen.h"
#include "ui/aura/event.h"
#include "ui/aura/root_window.h"
+#include "ui/aura/test/test_windows.h"
namespace ash {
+namespace test {
+
+namespace {
+
+class DelegatePercentTracker {
+ public:
+ explicit DelegatePercentTracker()
+ : handle_percent_count_(0),
+ handle_percent_(0){
+ }
+ int handle_percent_count() const {
+ return handle_percent_count_;
+ }
+ double handle_percent() const {
+ return handle_percent_;
+ }
+ void SetPercent(double percent) {
+ handle_percent_ = percent;
+ handle_percent_count_++;
+ }
+
+ private:
+ int handle_percent_count_;
+ int handle_percent_;
+
+ DISALLOW_COPY_AND_ASSIGN(DelegatePercentTracker);
+};
+
+class DummyVolumeControlDelegate : public VolumeControlDelegate,
+ public DelegatePercentTracker {
+ public:
+ explicit DummyVolumeControlDelegate() {}
+ virtual ~DummyVolumeControlDelegate() {}
+
+ virtual bool HandleVolumeMute(const ui::Accelerator& accelerator) OVERRIDE {
+ return true;
+ }
+ virtual bool HandleVolumeDown(const ui::Accelerator& accelerator) OVERRIDE {
+ return true;
+ }
+ virtual bool HandleVolumeUp(const ui::Accelerator& accelerator) OVERRIDE {
+ return true;
+ }
+ virtual void SetVolumePercent(double percent) OVERRIDE {
+ SetPercent(percent);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DummyVolumeControlDelegate);
+};
+
+class DummyBrightnessControlDelegate : public BrightnessControlDelegate,
+ public DelegatePercentTracker {
+ public:
+ explicit DummyBrightnessControlDelegate() {}
+ virtual ~DummyBrightnessControlDelegate() {}
+
+ virtual bool HandleBrightnessDown(
+ const ui::Accelerator& accelerator) OVERRIDE { return true; }
+ virtual bool HandleBrightnessUp(
+ const ui::Accelerator& accelerator) OVERRIDE { return true; }
+ virtual void SetBrightnessPercent(double percent, bool gradual) OVERRIDE {
+ SetPercent(percent);
+ }
+ virtual void GetBrightnessPercent(
+ const base::Callback<void(double)>& callback) OVERRIDE {
+ callback.Run(100.0);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DummyBrightnessControlDelegate);
+};
+
+} // namespace
typedef test::AshTestBase SystemGestureEventFilterTest;
@@ -74,4 +157,216 @@ TEST_F(SystemGestureEventFilterTest, ThreeFingerSwipe) {
EXPECT_FALSE(consumed);
}
+// Ensure that the device control operation gets properly handled.
+TEST_F(SystemGestureEventFilterTest, DeviceControl) {
+ aura::RootWindow* root_window = Shell::GetRootWindow();
+
+ gfx::Rect screen = gfx::Screen::GetPrimaryMonitor().bounds();
+ int ypos_half = screen.height() / 2;
+
+ ash::AcceleratorController* accelerator =
+ ash::Shell::GetInstance()->accelerator_controller();
+
+ DummyBrightnessControlDelegate* delegateBrightness =
+ new DummyBrightnessControlDelegate();
+ accelerator->SetBrightnessControlDelegate(
+ scoped_ptr<BrightnessControlDelegate>(delegateBrightness).Pass());
+
+ DummyVolumeControlDelegate* delegateVolume =
+ new DummyVolumeControlDelegate();
+ accelerator->SetVolumeControlDelegate(
+ scoped_ptr<VolumeControlDelegate>(delegateVolume).Pass());
+
+ const int kTouchId = 5;
+
+ for (int pass = 0; pass < 2; pass++) {
+ DelegatePercentTracker* delegate =
+ static_cast<DelegatePercentTracker*>(delegateBrightness);
+ int xpos = screen.x() - 10;
+ int ypos = screen.y();
+ if (pass) {
+ // On the second pass the volume will be tested.
+ delegate = static_cast<DelegatePercentTracker*>(delegateVolume);
+ xpos = screen.right() + 40; // Make sure it is out of the screen.
+ }
+ // Get a target for kTouchId
+ aura::TouchEvent press1(ui::ET_TOUCH_PRESSED,
+ gfx::Point(-10, ypos + ypos_half),
+ kTouchId,
+ base::Time::NowFromSystemTime() - base::Time());
+ root_window->DispatchTouchEvent(&press1);
+
+ aura::GestureEvent* event1 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_BEGIN, xpos, ypos, 0,
+ base::Time::Now(), 0, 0, 1 << kTouchId);
+ bool consumed = root_window->DispatchGestureEvent(event1);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(0, delegate->handle_percent_count());
+
+ // No move at the beginning will produce no events.
+ aura::GestureEvent* event2 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE,
+ xpos, ypos, 0, base::Time::Now(), 0, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event2);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(0, delegate->handle_percent_count());
+
+ // A move to a new Y location will produce an event.
+ aura::GestureEvent* event3 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos, ypos + ypos_half, 0,
+ base::Time::Now(), 0, ypos_half, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event3);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(1, delegate->handle_percent_count());
+ EXPECT_EQ(50.0, delegate->handle_percent());
+
+ // A move to an illegal Y location will produce legal results.
+ aura::GestureEvent* event4 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos, ypos - 100, 0,
+ base::Time::Now(), 0, -ypos_half - 100, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event4);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(2, delegate->handle_percent_count());
+ EXPECT_EQ(100.0, delegate->handle_percent());
+
+ aura::GestureEvent* event5 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos, ypos + 2 * screen.height(), 0,
+ base::Time::Now(), 0, 2 * screen.height() + 100, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event5);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(3, delegate->handle_percent_count());
+ EXPECT_EQ(0.0, delegate->handle_percent());
+
+ // Finishing the gesture should not change anything.
+ aura::GestureEvent* event7 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_END, xpos, ypos + ypos_half, 0,
+ base::Time::Now(), 0, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event7);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(3, delegate->handle_percent_count());
+
+ // Another event after this one should get ignored.
+ aura::GestureEvent* event8 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos, ypos_half, 0,
+ base::Time::Now(), 0, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event8);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(3, delegate->handle_percent_count());
+
+ aura::TouchEvent release1(ui::ET_TOUCH_RELEASED,
+ gfx::Point(2 * xpos, ypos + ypos_half), kTouchId,
+ base::Time::NowFromSystemTime() - base::Time());
+ root_window->DispatchTouchEvent(&release1);
+ }
+}
+
+// Ensure that the application control operations gets properly handled.
+TEST_F(SystemGestureEventFilterTest, ApplicationControl) {
+ aura::RootWindow* root_window = Shell::GetRootWindow();
+
+ gfx::Rect screen = gfx::Screen::GetPrimaryMonitor().bounds();
+ int ypos_half = screen.height() / 2;
+
+ aura::test::TestWindowDelegate delegate;
+ scoped_ptr<aura::Window> window0(
+ aura::test::CreateTestWindowWithDelegate(
+ &delegate, 9, gfx::Rect(0, 0, 100, 100), root_window));
+ scoped_ptr<aura::Window> window1(
+ aura::test::CreateTestWindowWithDelegate(
+ &delegate, 10, gfx::Rect(0, 0, 100, 100), window0.get()));
+ scoped_ptr<aura::Window> window2(
+ aura::test::CreateTestWindowWithDelegate(
+ &delegate, 11, gfx::Rect(0, 0, 100, 100), window0.get()));
+
+ const int kTouchId = 5;
+
+ for (int pass = 0; pass < 2; pass++) {
+ // Add the launcher items and make sure the first item is the active one.
+ TestLauncherDelegate::instance()->AddLauncherItem(window1.get(),
+ ash::STATUS_ACTIVE);
+ TestLauncherDelegate::instance()->AddLauncherItem(window2.get(),
+ ash::STATUS_RUNNING);
+ ash::wm::ActivateWindow(window1.get());
+
+ int xpos = screen.x() - 10;
+ int delta_x = 100;
+ int ypos = screen.y();
+ if (pass) {
+ xpos = screen.right() + 40; // Make sure the touch is out of the screen.
+ delta_x = -100;
+ }
+
+ aura::Window* active_window = ash::wm::GetActiveWindow();
+
+ // Get a target for kTouchId
+ aura::TouchEvent press(ui::ET_TOUCH_PRESSED,
+ gfx::Point(-10, ypos + ypos_half),
+ kTouchId,
+ base::Time::NowFromSystemTime() - base::Time());
+ root_window->DispatchTouchEvent(&press);
+
+ aura::GestureEvent* event1 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_BEGIN, xpos, ypos, 0,
+ base::Time::Now(), 0, 0, 1 << kTouchId);
+ bool consumed = root_window->DispatchGestureEvent(event1);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
+
+ // No move at the beginning will produce no events.
+ aura::GestureEvent* event2 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE,
+ xpos, ypos, 0, base::Time::Now(), 0, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event2);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
+
+ // A move further to the outside will not trigger an action.
+ aura::GestureEvent* event3 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos - delta_x, ypos, 0,
+ base::Time::Now(), -delta_x, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event3);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
+
+ // A move to the proper side will trigger an action.
+ aura::GestureEvent* event4 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos + delta_x, ypos, 0,
+ base::Time::Now(), 2 * delta_x, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event4);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_NE(ash::wm::GetActiveWindow(), active_window);
+ active_window = ash::wm::GetActiveWindow();
+
+ // A second move to the proper side will not trigger an action.
+ aura::GestureEvent* event5 = new aura::GestureEvent(
+ ui::ET_GESTURE_SCROLL_UPDATE, xpos + 2 * delta_x, ypos, 0,
+ base::Time::Now(), delta_x, 0, 1 << kTouchId);
+ consumed = root_window->DispatchGestureEvent(event5);
+
+ EXPECT_TRUE(consumed);
+ EXPECT_EQ(ash::wm::GetActiveWindow(), active_window);
+
+ aura::TouchEvent release(ui::ET_TOUCH_RELEASED,
+ gfx::Point(2 * xpos, ypos + ypos_half), kTouchId,
+ base::Time::NowFromSystemTime() - base::Time());
+ root_window->DispatchTouchEvent(&release);
+
+ // Remove the launcher items again.
+ TestLauncherDelegate::instance()->OnWillRemoveWindow(window1.get());
+ TestLauncherDelegate::instance()->OnWillRemoveWindow(window2.get());
+ }
+}
+
+} // namespace test
} // namespace ash