Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(919)

Unified Diff: content/browser/renderer_host/gesture_event_filter.cc

Issue 10855200: Defer GestureTapDown events briefly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed proof-reading nits Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/gesture_event_filter.cc
diff --git a/content/browser/renderer_host/gesture_event_filter.cc b/content/browser/renderer_host/gesture_event_filter.cc
index 3c61cd412758e8c06fcadbc3d8dd98fc86479167..ab9eeee55d1d7f9255d0f1bc081cf6f916f7f554 100644
--- a/content/browser/renderer_host/gesture_event_filter.cc
+++ b/content/browser/renderer_host/gesture_event_filter.cc
@@ -12,6 +12,13 @@ using WebKit::WebInputEvent;
namespace content {
namespace {
+
+// Default maximum time between the GestureRecognizer generating a
+// GestureTapDown and when it is forwarded to the renderer.
+// TODO(rjkroege): Make this configurable.
+static const int kMaxiumTapGapTimeMs = 100;
+
+// TODO(rjkroege): Coalesce pinch updates.
// Returns |true| if two gesture events should be coalesced.
bool ShouldCoalesceGestureEvents(const WebKit::WebGestureEvent& last_event,
const WebKit::WebGestureEvent& new_event) {
@@ -24,15 +31,14 @@ bool ShouldCoalesceGestureEvents(const WebKit::WebGestureEvent& last_event,
GestureEventFilter::GestureEventFilter(RenderWidgetHostImpl* rwhv)
: render_widget_host_(rwhv),
fling_in_progress_(false),
- gesture_event_pending_(false),
- tap_suppression_controller_(new TapSuppressionController(rwhv)) {
+ tap_suppression_controller_(new TapSuppressionController(rwhv)),
+ maximum_tap_gap_time_ms_(kMaxiumTapGapTimeMs) {
}
GestureEventFilter::~GestureEventFilter() { }
bool GestureEventFilter::ShouldDiscardFlingCancelEvent(
const WebKit::WebGestureEvent& gesture_event) {
- DCHECK(gesture_event.type == WebInputEvent::GestureFlingCancel);
if (coalesced_gesture_events_.empty() && fling_in_progress_)
return false;
GestureEventQueue::reverse_iterator it =
@@ -47,59 +53,63 @@ bool GestureEventFilter::ShouldDiscardFlingCancelEvent(
return true;
}
+// TODO(rjkroege): separate touchpad and touchscreen events.
bool GestureEventFilter::ShouldForward(const WebGestureEvent& gesture_event) {
- if (gesture_event.type == WebInputEvent::GestureFlingCancel) {
- if (ShouldDiscardFlingCancelEvent(gesture_event))
- return false;
- fling_in_progress_ = false;
- }
-
- if (gesture_event_pending_) {
- if (coalesced_gesture_events_.empty() ||
- !ShouldCoalesceGestureEvents(coalesced_gesture_events_.back(),
- gesture_event)) {
- coalesced_gesture_events_.push_back(gesture_event);
- } else {
- WebGestureEvent* last_gesture_event =
- &coalesced_gesture_events_.back();
- last_gesture_event->deltaX += gesture_event.deltaX;
- last_gesture_event->deltaY += gesture_event.deltaY;
- DCHECK_GE(gesture_event.timeStampSeconds,
- last_gesture_event->timeStampSeconds);
- last_gesture_event->timeStampSeconds = gesture_event.timeStampSeconds;
+ switch (gesture_event.type) {
+ case WebInputEvent::GestureFlingCancel:
sadrul 2012/08/16 16:08:15 indent!
rjkroege 2012/08/16 17:12:26 Done.
+ if (!ShouldDiscardFlingCancelEvent(gesture_event)) {
+ coalesced_gesture_events_.push_back(gesture_event);
+ fling_in_progress_ = false;
+ return ShouldHandleEventNow();
}
return false;
- }
- gesture_event_pending_ = true;
-
- if (gesture_event.type == WebInputEvent::GestureFlingCancel) {
- tap_suppression_controller_->GestureFlingCancel(
- gesture_event.timeStampSeconds);
- } else if (gesture_event.type == WebInputEvent::GestureFlingStart) {
+ case WebInputEvent::GestureFlingStart:
fling_in_progress_ = true;
+ coalesced_gesture_events_.push_back(gesture_event);
+ return ShouldHandleEventNow();
+ case WebInputEvent::GestureTapDown:
+ deferred_tap_gesture_event_ = gesture_event;
sadrul 2012/08/16 16:08:15 Let's call it deferred_tap_down_event_
rjkroege 2012/08/16 17:12:26 Done.
+ send_gtd_timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(maximum_tap_gap_time_ms_),
+ this,
+ &GestureEventFilter::SendGestureTapDownNow);
+ return false;
+ case WebInputEvent::GestureTap:
+ send_gtd_timer_.Stop();
+ coalesced_gesture_events_.push_back(deferred_tap_gesture_event_);
+ if (ShouldHandleEventNow())
+ render_widget_host_->ForwardGestureEventImmediately(
+ deferred_tap_gesture_event_);
sadrul 2012/08/16 16:08:15 Should the tap-event be also forwarded immediately
rjkroege 2012/08/16 17:12:26 Probably not. Doing so would deviate from the patt
+ coalesced_gesture_events_.push_back(gesture_event);
+ return false;
+ case WebInputEvent::GestureScrollBegin:
+ case WebInputEvent::GesturePinchBegin:
+ send_gtd_timer_.Stop();
+ coalesced_gesture_events_.push_back(gesture_event);
+ return ShouldHandleEventNow();
+ case WebInputEvent::GestureScrollUpdate:
+ MergeOrInsertScrollEvent(gesture_event);
+ return ShouldHandleEventNow();
+ default:
+ coalesced_gesture_events_.push_back(gesture_event);
+ return ShouldHandleEventNow();
}
- return true;
+ DLOG(FATAL) << "Unhandled case.\n";
sadrul 2012/08/16 16:08:15 You can use NOTREACHED here.
rjkroege 2012/08/16 17:12:26 Done.
+ return false;
}
void GestureEventFilter::Reset() {
fling_in_progress_ = false;
coalesced_gesture_events_.clear();
- gesture_event_pending_ = false;
+ // TODO(rjkroege): Reset the tap suppression controller.
}
void GestureEventFilter::ProcessGestureAck(bool processed, int type) {
- if (type == WebInputEvent::GestureFlingCancel)
- tap_suppression_controller_->GestureFlingCancelAck(processed);
-
- gesture_event_pending_ = false;
-
- // Now send the next (coalesced) gesture event.
+ coalesced_gesture_events_.pop_front();
if (!coalesced_gesture_events_.empty()) {
- WebGestureEvent next_gesture_event =
- coalesced_gesture_events_.front();
- coalesced_gesture_events_.pop_front();
- render_widget_host_->ForwardGestureEvent(next_gesture_event);
+ WebGestureEvent next_gesture_event = coalesced_gesture_events_.front();
+ render_widget_host_->ForwardGestureEventImmediately(next_gesture_event);
}
}
@@ -111,4 +121,36 @@ void GestureEventFilter::FlingHasBeenHalted() {
fling_in_progress_ = false;
}
+bool GestureEventFilter::ShouldHandleEventNow() {
+ return coalesced_gesture_events_.size() == 1;
+}
+
+void GestureEventFilter::SendGestureTapDownNow() {
+ coalesced_gesture_events_.push_back(deferred_tap_gesture_event_);
+ if (ShouldHandleEventNow())
sadrul 2012/08/16 16:08:15 braces!
rjkroege 2012/08/16 17:12:26 Done.
+ render_widget_host_->ForwardGestureEventImmediately(
+ deferred_tap_gesture_event_);
+}
+
+void GestureEventFilter::MergeOrInsertScrollEvent(
+ const WebGestureEvent& gesture_event) {
+ WebGestureEvent* last_gesture_event = &coalesced_gesture_events_.back();
+ if (coalesced_gesture_events_.size() > 1 &&
sadrul 2012/08/16 16:08:15 Could it be == 1 as well?
rjkroege 2012/08/16 17:12:26 No. The 0th event has already been sent to the ren
+ last_gesture_event->type == gesture_event.type &&
+ last_gesture_event->modifiers == gesture_event.modifiers) {
+ last_gesture_event->deltaX += gesture_event.deltaX;
+ last_gesture_event->deltaY += gesture_event.deltaY;
+ DLOG_IF(WARNING,
+ gesture_event.timeStampSeconds >=
+ last_gesture_event->timeStampSeconds)
+ << "Event time not monotonic?\n";
+ DLOG_IF(FATAL,
+ last_gesture_event->type != WebInputEvent::GestureScrollUpdate)
+ << "Bad gesture type after coalescing?\n";
sadrul 2012/08/16 16:08:15 Perhaps just DCHECK at the beginning that gesture_
rjkroege 2012/08/16 17:12:26 Done.
+ last_gesture_event->timeStampSeconds = gesture_event.timeStampSeconds;
+ } else {
+ coalesced_gesture_events_.push_back(gesture_event);
+ }
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698