summaryrefslogtreecommitdiffstats
path: root/ui/aura
diff options
context:
space:
mode:
authortdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 19:25:25 +0000
committertdresser@chromium.org <tdresser@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-17 19:25:25 +0000
commitcc1fad52a7d5f4317d63404022a251724e13f667 (patch)
treea64da9f22c64fdd6c000d01983049e7fd029cab0 /ui/aura
parenta58c97e519a34d9d48d6154f37e7d44346ada85e (diff)
downloadchromium_src-cc1fad52a7d5f4317d63404022a251724e13f667.zip
chromium_src-cc1fad52a7d5f4317d63404022a251724e13f667.tar.gz
chromium_src-cc1fad52a7d5f4317d63404022a251724e13f667.tar.bz2
On touch capture, cancel non-captured touches.
When a touch capture occurs, any touches locked to other windows are cancelled. These touches are then locked to a GestureConsumer which ignores all further events, until the touch is released. BUG=123211 TEST=WindowTest.TouchCaptureCancelsOtherTouches, TouchCaptureDoesntCancelCapturedTouches Review URL: http://codereview.chromium.org/10038030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132619 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/aura')
-rw-r--r--ui/aura/root_window.cc78
-rw-r--r--ui/aura/root_window.h7
-rw-r--r--ui/aura/window_unittest.cc76
3 files changed, 134 insertions, 27 deletions
diff --git a/ui/aura/root_window.cc b/ui/aura/root_window.cc
index 2254ff4..d443d62 100644
--- a/ui/aura/root_window.cc
+++ b/ui/aura/root_window.cc
@@ -268,39 +268,45 @@ bool RootWindow::DispatchTouchEvent(TouchEvent* event) {
event->UpdateForRootTransform(layer()->transform());
bool handled = false;
- Window* target = NULL;
- if (HasCapture(capture_window_, ui::CW_LOCK_TOUCH))
- target = capture_window_;
-
- if (!target)
- target = static_cast<Window*>(
- gesture_recognizer_->GetTargetForTouchEvent(event));
-
+ GestureConsumer* consumer = gesture_recognizer_->GetTouchLockedTarget(event);
ui::TouchStatus status = ui::TOUCH_STATUS_UNKNOWN;
- if (!target && !bounds().Contains(event->location())) {
- // If the touch is outside the root window, set its target to the
- // root window.
- target = this;
- } else {
- if (!target)
- target = GetEventHandlerForPoint(event->location());
- if (!target)
- return false;
+ if (!consumer || !consumer->ignores_events()) {
+ Window* target = static_cast<Window*>(consumer);
- TouchEvent translated_event(*event, this, target);
- status = ProcessTouchEvent(target, &translated_event);
- handled = status != ui::TOUCH_STATUS_UNKNOWN;
+ if (!target && HasCapture(capture_window_, ui::CW_LOCK_TOUCH))
+ target = capture_window_;
+
+ if (!target) {
+ target = static_cast<Window*>(
+ gesture_recognizer_->GetTargetForLocation(event->GetLocation()));
+ }
- if (status == ui::TOUCH_STATUS_QUEUED ||
- status == ui::TOUCH_STATUS_QUEUED_END)
- gesture_recognizer_->QueueTouchEventForGesture(target, *event);
+ if (!target && !bounds().Contains(event->location())) {
+ // If the touch is outside the root window, set its target to the
+ // root window.
+ target = this;
+ } else {
+ if (!target)
+ target = GetEventHandlerForPoint(event->location());
+ if (!target)
+ return false;
+
+ TouchEvent translated_event(*event, this, target);
+ status = ProcessTouchEvent(target, &translated_event);
+ handled = status != ui::TOUCH_STATUS_UNKNOWN;
+
+ if (status == ui::TOUCH_STATUS_QUEUED ||
+ status == ui::TOUCH_STATUS_QUEUED_END)
+ gesture_recognizer_->QueueTouchEventForGesture(target, *event);
+ }
+ consumer = target;
}
// Get the list of GestureEvents from GestureRecognizer.
scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
- *event, status, target));
+ *event, status, consumer));
if (ProcessGestures(gestures.get()))
handled = true;
@@ -313,9 +319,13 @@ bool RootWindow::DispatchGestureEvent(GestureEvent* event) {
Window* target = NULL;
if (HasCapture(capture_window_, ui::CW_LOCK_TOUCH))
target = capture_window_;
- if (!target)
- target = static_cast<Window*>(
- gesture_recognizer_->GetTargetForGestureEvent(event));
+ if (!target) {
+ GestureConsumer* consumer =
+ gesture_recognizer_->GetTargetForGestureEvent(event);
+ if (consumer->ignores_events())
+ return false;
+ target = static_cast<Window*>(consumer);
+ }
if (target) {
GestureEvent translated_event(*event, this, target);
@@ -407,6 +417,9 @@ void RootWindow::SetCapture(Window* window, unsigned int flags) {
if (capture_window_ == window && flags == capture_window_flags_)
return;
+ if (flags & ui::CW_LOCK_TOUCH)
+ gesture_recognizer_->CancelNonCapturedTouches(window);
+
aura::Window* old_capture_window = capture_window_;
capture_window_ = window;
capture_window_flags_ = flags;
@@ -782,6 +795,10 @@ bool RootWindow::DispatchLongPressGestureEvent(ui::GestureEvent* event) {
return DispatchGestureEvent(static_cast<GestureEvent*>(event));
}
+bool RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) {
+ return DispatchTouchEvent(static_cast<TouchEvent*>(event));
+}
+
ui::GestureEvent* RootWindow::CreateGestureEvent(ui::EventType type,
const gfx::Point& location,
int flags,
@@ -793,6 +810,13 @@ ui::GestureEvent* RootWindow::CreateGestureEvent(ui::EventType type,
param_first, param_second, touch_id_bitfield);
}
+ui::TouchEvent* RootWindow::CreateTouchEvent(ui::EventType type,
+ const gfx::Point& location,
+ int touch_id,
+ base::TimeDelta time_stamp) {
+ return new TouchEvent(type, location, touch_id, time_stamp);
+}
+
void RootWindow::OnLayerAnimationEnded(
ui::LayerAnimationSequence* animation) {
OnHostResized(host_->GetBounds().size());
diff --git a/ui/aura/root_window.h b/ui/aura/root_window.h
index 140543e..dd6f533 100644
--- a/ui/aura/root_window.h
+++ b/ui/aura/root_window.h
@@ -294,7 +294,14 @@ class AURA_EXPORT RootWindow : public ui::CompositorDelegate,
float param_first,
float param_second,
unsigned int touch_id_bitfield) OVERRIDE;
+
+ virtual ui::TouchEvent* CreateTouchEvent(ui::EventType type,
+ const gfx::Point& location,
+ int touch_id,
+ base::TimeDelta time_stamp) OVERRIDE;
+
virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE;
+ virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
// Overridden from ui::LayerAnimationObserver:
virtual void OnLayerAnimationEnded(
diff --git a/ui/aura/window_unittest.cc b/ui/aura/window_unittest.cc
index dd95610..30c5dd0 100644
--- a/ui/aura/window_unittest.cc
+++ b/ui/aura/window_unittest.cc
@@ -125,6 +125,7 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate {
capture_lost_count_ = 0;
mouse_event_count_ = 0;
touch_event_count_ = 0;
+ gesture_event_count_ = 0;
}
int capture_changed_event_count() const {
@@ -133,6 +134,7 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate {
int capture_lost_count() const { return capture_lost_count_; }
int mouse_event_count() const { return mouse_event_count_; }
int touch_event_count() const { return touch_event_count_; }
+ int gesture_event_count() const { return gesture_event_count_; }
virtual bool OnMouseEvent(MouseEvent* event) OVERRIDE {
if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED)
@@ -145,6 +147,7 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate {
return ui::TOUCH_STATUS_UNKNOWN;
}
virtual ui::GestureStatus OnGestureEvent(GestureEvent* event) OVERRIDE {
+ gesture_event_count_++;
return ui::GESTURE_STATUS_UNKNOWN;
}
virtual void OnCaptureLost() OVERRIDE {
@@ -156,6 +159,7 @@ class CaptureWindowDelegateImpl : public TestWindowDelegate {
int capture_lost_count_;
int mouse_event_count_;
int touch_event_count_;
+ int gesture_event_count_;
DISALLOW_COPY_AND_ASSIGN(CaptureWindowDelegateImpl);
};
@@ -626,6 +630,78 @@ TEST_F(WindowTest, CaptureTests) {
EXPECT_EQ(NULL, root_window()->capture_window());
}
+TEST_F(WindowTest, TouchCaptureCancelsOtherTouches) {
+ CaptureWindowDelegateImpl delegate1;
+ scoped_ptr<Window> w1(CreateTestWindowWithDelegate(
+ &delegate1, 0, gfx::Rect(0, 0, 20, 20), NULL));
+ CaptureWindowDelegateImpl delegate2;
+ scoped_ptr<Window> w2(CreateTestWindowWithDelegate(
+ &delegate2, 0, gfx::Rect(20, 20, 20, 20), NULL));
+
+ // Press on w1.
+ TouchEvent press(ui::ET_TOUCH_PRESSED,
+ gfx::Point(10, 10), 0, getTime());
+ root_window()->DispatchTouchEvent(&press);
+ EXPECT_EQ(1, delegate1.gesture_event_count());
+ delegate1.ResetCounts();
+ w2->SetCapture(ui::CW_LOCK_TOUCH);
+
+ // The touch was cancelled when the other window
+ // attained a touch lock.
+ EXPECT_EQ(1, delegate1.touch_event_count());
+ EXPECT_EQ(0, delegate2.touch_event_count());
+
+ delegate1.ResetCounts();
+ delegate2.ResetCounts();
+
+ TouchEvent move(ui::ET_TOUCH_MOVED,
+ gfx::Point(10, 10), 0, getTime());
+ root_window()->DispatchTouchEvent(&move);
+
+ // This touch id is now ignored, no scroll fired.
+ EXPECT_EQ(0, delegate1.gesture_event_count());
+ EXPECT_EQ(0, delegate2.gesture_event_count());
+
+ TouchEvent release(ui::ET_TOUCH_RELEASED,
+ gfx::Point(10, 10), 0, getTime());
+ root_window()->DispatchTouchEvent(&release);
+ EXPECT_EQ(0, delegate1.gesture_event_count());
+ EXPECT_EQ(0, delegate2.gesture_event_count());
+
+ // A new press is captured by w2.
+
+ TouchEvent press2(ui::ET_TOUCH_PRESSED,
+ gfx::Point(10, 10), 0, getTime());
+ root_window()->DispatchTouchEvent(&press2);
+ EXPECT_EQ(0, delegate1.gesture_event_count());
+ EXPECT_EQ(1, delegate2.gesture_event_count());
+}
+
+TEST_F(WindowTest, TouchCaptureDoesntCancelCapturedTouches) {
+ CaptureWindowDelegateImpl delegate;
+ scoped_ptr<Window> window(CreateTestWindowWithDelegate(
+ &delegate, 0, gfx::Rect(0, 0, 20, 20), NULL));
+
+ TouchEvent press(ui::ET_TOUCH_PRESSED,
+ gfx::Point(10, 10), 0, getTime());
+ root_window()->DispatchTouchEvent(&press);
+
+ EXPECT_EQ(1, delegate.gesture_event_count());
+ delegate.ResetCounts();
+
+ window->SetCapture(ui::CW_LOCK_TOUCH);
+ EXPECT_EQ(0, delegate.gesture_event_count());
+ delegate.ResetCounts();
+
+ // The move event should still create a gesture, as this touch was
+ // on the window which was captured.
+ TouchEvent release(ui::ET_TOUCH_RELEASED,
+ gfx::Point(10, 10), 0, getTime() +
+ base::TimeDelta::FromMilliseconds(50));
+ root_window()->DispatchTouchEvent(&release);
+ EXPECT_EQ(1, delegate.gesture_event_count());
+}
+
// Changes capture while capture is already ongoing.
TEST_F(WindowTest, ChangeCaptureWhileMouseDown) {
CaptureWindowDelegateImpl delegate;