summaryrefslogtreecommitdiffstats
path: root/ui/events
diff options
context:
space:
mode:
authorjdduke <jdduke@chromium.org>2014-11-18 12:44:35 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-18 20:45:45 +0000
commit019a29ecaa7e23348b65e1c86807554ded255028 (patch)
treef7faa7e0d0c448d6cc9938aea0d685328445c9bc /ui/events
parent5779b38e9f3fae82dbbed7219d96cdd19eef1813 (diff)
downloadchromium_src-019a29ecaa7e23348b65e1c86807554ded255028.zip
chromium_src-019a29ecaa7e23348b65e1c86807554ded255028.tar.gz
chromium_src-019a29ecaa7e23348b65e1c86807554ded255028.tar.bz2
Track whether a scroll sequence has been partially prevented
Listeners and consumers of a gesture event stream may wish to know if part of the gesture stream has been prevented, i.e., whether the page has consumed any of the underlying touchmove events. Route this bit for scroll update events from the TouchDispositionGestureFilter through to the generated WebGestureEvent types. This change depends on the Blink patch: https://codereview.chromium.org/690173002/ BUG=428429 Review URL: https://codereview.chromium.org/712133003 Cr-Commit-Position: refs/heads/master@{#304665}
Diffstat (limited to 'ui/events')
-rw-r--r--ui/events/gesture_detection/gesture_event_data.cc2
-rw-r--r--ui/events/gesture_detection/touch_disposition_gesture_filter.cc16
-rw-r--r--ui/events/gesture_detection/touch_disposition_gesture_filter.h8
-rw-r--r--ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc57
-rw-r--r--ui/events/gesture_event_details.cc51
-rw-r--r--ui/events/gesture_event_details.h51
6 files changed, 145 insertions, 40 deletions
diff --git a/ui/events/gesture_detection/gesture_event_data.cc b/ui/events/gesture_detection/gesture_event_data.cc
index 2102f23..b166ffa 100644
--- a/ui/events/gesture_detection/gesture_event_data.cc
+++ b/ui/events/gesture_detection/gesture_event_data.cc
@@ -36,7 +36,7 @@ GestureEventData::GestureEventData(const GestureEventDetails& details,
GestureEventData::GestureEventData(EventType type,
const GestureEventData& other)
- : details(type),
+ : details(type, other.details),
motion_event_id(other.motion_event_id),
primary_tool_type(other.primary_tool_type),
time(other.time),
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
index fcb92d4..564d014 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
@@ -314,6 +314,15 @@ void TouchDispositionGestureFilter::SendGesture(
ending_event_primary_tool_type_ = event.primary_tool_type;
needs_scroll_ending_event_ = true;
break;
+ case ET_GESTURE_SCROLL_UPDATE:
+ if (state_.HasFilteredGestureType(ET_GESTURE_SCROLL_UPDATE)) {
+ GestureEventData modified_event(ET_GESTURE_SCROLL_UPDATE, event);
+ modified_event.details
+ .mark_previous_scroll_update_in_sequence_prevented();
+ client_->ForwardGestureEvent(modified_event);
+ return;
+ }
+ break;
case ET_GESTURE_SCROLL_END:
needs_scroll_ending_event_ = false;
break;
@@ -418,10 +427,17 @@ bool TouchDispositionGestureFilter::GestureHandlingState::Filter(
last_gesture_of_type_dropped_.has_bit(
GetGestureTypeIndex(antecedent_event_type)))) {
last_gesture_of_type_dropped_.mark_bit(GetGestureTypeIndex(gesture_type));
+ any_gesture_of_type_dropped_.mark_bit(GetGestureTypeIndex(gesture_type));
return true;
}
last_gesture_of_type_dropped_.clear_bit(GetGestureTypeIndex(gesture_type));
return false;
}
+bool TouchDispositionGestureFilter::GestureHandlingState::
+ HasFilteredGestureType(EventType gesture_type) const {
+ return any_gesture_of_type_dropped_.has_bit(
+ GetGestureTypeIndex(gesture_type));
+}
+
} // namespace content
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter.h b/ui/events/gesture_detection/touch_disposition_gesture_filter.h
index 290afaa..5895a6b 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter.h
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter.h
@@ -66,14 +66,18 @@ class GESTURE_DETECTION_EXPORT TouchDispositionGestureFilter {
// Returns true iff the gesture should be dropped.
bool Filter(EventType type);
+ // Whether an event of |type| has been filtered from the current sequence.
+ bool HasFilteredGestureType(EventType type) const;
+
private:
// True iff the sequence has had any touch down event consumed.
bool start_touch_consumed_;
// True iff the most recently ack'ed touch event was consumed.
bool current_touch_consumed_;
- // If the previous gesture of a given type was dropped instead of being
- // dispatched, its type will occur in this set.
+ // Indicates whether the previous gesture of a given type was dropped.
BitSet32 last_gesture_of_type_dropped_;
+ // Indicates whether *any* previous gesture of a given type was dropped.
+ BitSet32 any_gesture_of_type_dropped_;
};
void FilterAndSendPacket(const GestureEventDataPacket& packet);
diff --git a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
index 5d823b7..eb77e64 100644
--- a/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
+++ b/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
@@ -179,9 +179,13 @@ class TouchDispositionGestureFilterTest
bool GesturesSent() const { return !sent_gestures_.empty(); }
- base::TimeTicks LastSentGestureTime() const {
+ const GestureEventData& last_sent_gesture() const {
CHECK(last_sent_gesture_);
- return last_sent_gesture_->time;
+ return *last_sent_gesture_;
+ }
+
+ base::TimeTicks LastSentGestureTime() const {
+ return last_sent_gesture().time;
}
base::TimeTicks CurrentTouchTime() const {
@@ -197,18 +201,15 @@ class TouchDispositionGestureFilterTest
}
gfx::PointF LastSentGestureLocation() const {
- CHECK(last_sent_gesture_);
- return gfx::PointF(last_sent_gesture_->x, last_sent_gesture_->y);
+ return gfx::PointF(last_sent_gesture().x, last_sent_gesture().y);
}
gfx::PointF LastSentGestureRawLocation() const {
- CHECK(last_sent_gesture_);
- return gfx::PointF(last_sent_gesture_->raw_x, last_sent_gesture_->raw_y);
+ return gfx::PointF(last_sent_gesture().raw_x, last_sent_gesture().raw_y);
}
int LastSentGestureFlags() const {
- CHECK(last_sent_gesture_);
- return last_sent_gesture_->flags;
+ return last_sent_gesture().flags;
}
const gfx::RectF& ShowPressBoundingBox() const {
@@ -1148,4 +1149,44 @@ TEST_F(TouchDispositionGestureFilterTest, EventFlagPropagation) {
EXPECT_EQ(0, LastSentGestureFlags());
}
+
+TEST_F(TouchDispositionGestureFilterTest, PreviousScrollPrevented) {
+ PushGesture(ET_GESTURE_BEGIN);
+ PressTouchPoint(1, 1);
+ EXPECT_FALSE(GesturesSent());
+ SendTouchNotConsumedAck();
+ EXPECT_TRUE(
+ GesturesMatch(Gestures(ET_GESTURE_BEGIN), GetAndResetSentGestures()));
+
+ // The sent scroll update should always reflect whether any preceding scroll
+ // update has been dropped.
+ PushGesture(ET_GESTURE_SCROLL_UPDATE);
+ MoveTouchPoint(0, 2, 2);
+ SendTouchNotConsumedAck();
+ ASSERT_TRUE(GesturesSent());
+ EXPECT_FALSE(last_sent_gesture()
+ .details.previous_scroll_update_in_sequence_prevented());
+ GetAndResetSentGestures();
+
+ PushGesture(ET_GESTURE_SCROLL_UPDATE);
+ MoveTouchPoint(0, -2, -2);
+ SendTouchConsumedAck();
+ EXPECT_FALSE(GesturesSent());
+
+ PushGesture(ET_GESTURE_SCROLL_UPDATE);
+ MoveTouchPoint(0, 2, 2);
+ SendTouchNotConsumedAck();
+ ASSERT_TRUE(GesturesSent());
+ EXPECT_TRUE(last_sent_gesture()
+ .details.previous_scroll_update_in_sequence_prevented());
+ GetAndResetSentGestures();
+
+ PushGesture(ET_GESTURE_SCROLL_UPDATE);
+ MoveTouchPoint(0, 2, 2);
+ SendTouchNotConsumedAck();
+ ASSERT_TRUE(GesturesSent());
+ EXPECT_TRUE(last_sent_gesture()
+ .details.previous_scroll_update_in_sequence_prevented());
+}
+
} // namespace ui
diff --git a/ui/events/gesture_event_details.cc b/ui/events/gesture_event_details.cc
index 7807131..e14fb17 100644
--- a/ui/events/gesture_event_details.cc
+++ b/ui/events/gesture_event_details.cc
@@ -24,30 +24,30 @@ GestureEventDetails::GestureEventDetails(ui::EventType type,
DCHECK_LE(type, ET_GESTURE_TYPE_END);
switch (type_) {
case ui::ET_GESTURE_SCROLL_BEGIN:
- data.scroll_begin.x_hint = delta_x;
- data.scroll_begin.y_hint = delta_y;
+ data_.scroll_begin.x_hint = delta_x;
+ data_.scroll_begin.y_hint = delta_y;
break;
case ui::ET_GESTURE_SCROLL_UPDATE:
- data.scroll_update.x = delta_x;
- data.scroll_update.y = delta_y;
+ data_.scroll_update.x = delta_x;
+ data_.scroll_update.y = delta_y;
break;
case ui::ET_SCROLL_FLING_START:
- data.fling_velocity.x = delta_x;
- data.fling_velocity.y = delta_y;
+ data_.fling_velocity.x = delta_x;
+ data_.fling_velocity.y = delta_y;
break;
case ui::ET_GESTURE_TWO_FINGER_TAP:
- data.first_finger_enclosing_rectangle.width = delta_x;
- data.first_finger_enclosing_rectangle.height = delta_y;
+ data_.first_finger_enclosing_rectangle.width = delta_x;
+ data_.first_finger_enclosing_rectangle.height = delta_y;
break;
case ui::ET_GESTURE_SWIPE:
- data.swipe.left = delta_x < 0;
- data.swipe.right = delta_x > 0;
- data.swipe.up = delta_y < 0;
- data.swipe.down = delta_y > 0;
+ data_.swipe.left = delta_x < 0;
+ data_.swipe.right = delta_x > 0;
+ data_.swipe.up = delta_y < 0;
+ data_.swipe.down = delta_y > 0;
break;
default:
@@ -55,6 +55,33 @@ GestureEventDetails::GestureEventDetails(ui::EventType type,
}
}
+GestureEventDetails::GestureEventDetails(ui::EventType type,
+ const GestureEventDetails& other)
+ : type_(type),
+ data_(other.data_),
+ touch_points_(other.touch_points_),
+ bounding_box_(other.bounding_box_),
+ oldest_touch_id_(other.oldest_touch_id_) {
+ DCHECK_GE(type, ET_GESTURE_TYPE_START);
+ DCHECK_LE(type, ET_GESTURE_TYPE_END);
+ switch (type) {
+ case ui::ET_GESTURE_SCROLL_BEGIN:
+ // Synthetic creation of SCROLL_BEGIN from PINCH_BEGIN is explicitly
+ // allowed as an exception.
+ if (other.type() == ui::ET_GESTURE_PINCH_BEGIN)
+ break;
+ case ui::ET_GESTURE_SCROLL_UPDATE:
+ case ui::ET_SCROLL_FLING_START:
+ case ui::ET_GESTURE_SWIPE:
+ case ui::ET_GESTURE_PINCH_UPDATE:
+ DCHECK_EQ(type, other.type()) << " - Invalid gesture conversion from "
+ << other.type() << " to " << type;
+ break;
+ default:
+ break;
+ }
+}
+
GestureEventDetails::Details::Details() {
memset(this, 0, sizeof(Details));
}
diff --git a/ui/events/gesture_event_details.h b/ui/events/gesture_event_details.h
index da7a60b..66b28b9 100644
--- a/ui/events/gesture_event_details.h
+++ b/ui/events/gesture_event_details.h
@@ -19,6 +19,10 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
explicit GestureEventDetails(EventType type);
GestureEventDetails(EventType type, float delta_x, float delta_y);
+ // The caller is responsible for ensuring that the gesture data from |other|
+ // is compatible and sufficient for that expected by gestures of |type|.
+ GestureEventDetails(EventType type, const GestureEventDetails& other);
+
EventType type() const { return type_; }
int touch_points() const { return touch_points_; }
@@ -46,74 +50,74 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
float scroll_x_hint() const {
DCHECK_EQ(ET_GESTURE_SCROLL_BEGIN, type_);
- return data.scroll_begin.x_hint;
+ return data_.scroll_begin.x_hint;
}
float scroll_y_hint() const {
DCHECK_EQ(ET_GESTURE_SCROLL_BEGIN, type_);
- return data.scroll_begin.y_hint;
+ return data_.scroll_begin.y_hint;
}
float scroll_x() const {
DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
- return data.scroll_update.x;
+ return data_.scroll_update.x;
}
float scroll_y() const {
DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
- return data.scroll_update.y;
+ return data_.scroll_update.y;
}
float velocity_x() const {
DCHECK_EQ(ET_SCROLL_FLING_START, type_);
- return data.fling_velocity.x;
+ return data_.fling_velocity.x;
}
float velocity_y() const {
DCHECK_EQ(ET_SCROLL_FLING_START, type_);
- return data.fling_velocity.y;
+ return data_.fling_velocity.y;
}
float first_finger_width() const {
DCHECK_EQ(ET_GESTURE_TWO_FINGER_TAP, type_);
- return data.first_finger_enclosing_rectangle.width;
+ return data_.first_finger_enclosing_rectangle.width;
}
float first_finger_height() const {
DCHECK_EQ(ET_GESTURE_TWO_FINGER_TAP, type_);
- return data.first_finger_enclosing_rectangle.height;
+ return data_.first_finger_enclosing_rectangle.height;
}
float scale() const {
DCHECK_EQ(ET_GESTURE_PINCH_UPDATE, type_);
- return data.scale;
+ return data_.scale;
}
bool swipe_left() const {
DCHECK_EQ(ET_GESTURE_SWIPE, type_);
- return data.swipe.left;
+ return data_.swipe.left;
}
bool swipe_right() const {
DCHECK_EQ(ET_GESTURE_SWIPE, type_);
- return data.swipe.right;
+ return data_.swipe.right;
}
bool swipe_up() const {
DCHECK_EQ(ET_GESTURE_SWIPE, type_);
- return data.swipe.up;
+ return data_.swipe.up;
}
bool swipe_down() const {
DCHECK_EQ(ET_GESTURE_SWIPE, type_);
- return data.swipe.down;
+ return data_.swipe.down;
}
int tap_count() const {
DCHECK(type_ == ET_GESTURE_TAP ||
type_ == ET_GESTURE_TAP_UNCONFIRMED ||
type_ == ET_GESTURE_DOUBLE_TAP);
- return data.tap_count;
+ return data_.tap_count;
}
void set_tap_count(int tap_count) {
@@ -121,13 +125,23 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
DCHECK(type_ == ET_GESTURE_TAP ||
type_ == ET_GESTURE_TAP_UNCONFIRMED ||
type_ == ET_GESTURE_DOUBLE_TAP);
- data.tap_count = tap_count;
+ data_.tap_count = tap_count;
}
void set_scale(float scale) {
DCHECK_GE(scale, 0.0f);
DCHECK_EQ(type_, ET_GESTURE_PINCH_UPDATE);
- data.scale = scale;
+ data_.scale = scale;
+ }
+
+ void mark_previous_scroll_update_in_sequence_prevented() {
+ DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
+ data_.scroll_update.previous_update_in_sequence_prevented = true;
+ }
+
+ bool previous_scroll_update_in_sequence_prevented() const {
+ DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
+ return data_.scroll_update.previous_update_in_sequence_prevented;
}
private:
@@ -144,6 +158,9 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
struct { // SCROLL delta.
float x;
float y;
+ // Whether any previous scroll update in the current scroll sequence was
+ // suppressed because the underlying touch was consumed.
+ bool previous_update_in_sequence_prevented;
} scroll_update;
float scale; // PINCH scale.
@@ -170,7 +187,7 @@ struct EVENTS_BASE_EXPORT GestureEventDetails {
// Tap information must be set for ET_GESTURE_TAP,
// ET_GESTURE_TAP_UNCONFIRMED, and ET_GESTURE_DOUBLE_TAP events.
int tap_count; // TAP repeat count.
- } data;
+ } data_;
int touch_points_; // Number of active touch points in the gesture.