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

Unified Diff: content/browser/renderer_host/input/touch_action_filter.cc

Issue 93733005: Implement support for touch-action: pan-x/pan-y in chromium (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Apply jdduke CR feedback Created 7 years 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/input/touch_action_filter.cc
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc
index 665ff15bd30f77441f7d6fc095df4ea6c9cbf071..37fc1e6e5d976afbda28c40e908ce0e834e0cf0e 100644
--- a/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -4,6 +4,9 @@
#include "content/browser/renderer_host/input/touch_action_filter.h"
+#include <math.h>
+
+#include "base/logging.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
using blink::WebInputEvent;
@@ -16,29 +19,43 @@ TouchActionFilter::TouchActionFilter() :
allowed_touch_action_(TOUCH_ACTION_AUTO) {
}
-bool TouchActionFilter::FilterGestureEvent(
- const WebGestureEvent& gesture_event) {
+bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
// Filter for allowable touch actions first (eg. before the TouchEventQueue
// can decide to send a touch cancel event).
// TODO(rbyers): Add touch-action control over for pinch. crbug.com/247566.
- switch(gesture_event.type) {
+ switch(gesture_event->type) {
case WebInputEvent::GestureScrollBegin:
- if (allowed_touch_action_ == TOUCH_ACTION_NONE)
- drop_scroll_gesture_events_ = true;
- // FALL THROUGH
+ DCHECK(!drop_scroll_gesture_events_);
+ drop_scroll_gesture_events_ = ShouldSuppressScroll(*gesture_event);
+ return drop_scroll_gesture_events_;
jdduke (slow) 2013/12/19 16:17:16 If a GSB is dropped, the pinch sequence wrapped by
Rick Byers 2013/12/19 16:35:09 Yes, thanks. As discussed I'll be dropping pinch
+
case WebInputEvent::GestureScrollUpdate:
if (drop_scroll_gesture_events_)
return true;
+ else {
+ if (allowed_touch_action_ == TOUCH_ACTION_PAN_X) {
+ gesture_event->data.scrollUpdate.deltaY = 0;
+ gesture_event->data.scrollUpdate.velocityY = 0;
+ } else if (allowed_touch_action_ == TOUCH_ACTION_PAN_Y) {
+ gesture_event->data.scrollUpdate.deltaX = 0;
+ gesture_event->data.scrollUpdate.velocityX = 0;
+ }
+ }
break;
- case WebInputEvent::GestureScrollEnd:
case WebInputEvent::GestureFlingStart:
- allowed_touch_action_ = content::TOUCH_ACTION_AUTO;
- if (drop_scroll_gesture_events_) {
- drop_scroll_gesture_events_ = false;
- return true;
+ if (gesture_event->sourceDevice != WebGestureEvent::Touchscreen)
+ break;
+ if (!drop_scroll_gesture_events_) {
+ if (allowed_touch_action_ == TOUCH_ACTION_PAN_X)
+ gesture_event->data.flingStart.velocityY = 0;
+ if (allowed_touch_action_ == TOUCH_ACTION_PAN_Y)
+ gesture_event->data.flingStart.velocityX = 0;
}
- break;
+ return FilterGestureEnd();
+
+ case WebInputEvent::GestureScrollEnd:
+ return FilterGestureEnd();
default:
// Gesture events unrelated to touch actions (panning/zooming) are left
@@ -49,15 +66,57 @@ bool TouchActionFilter::FilterGestureEvent(
return false;
}
-void TouchActionFilter::OnSetTouchAction(
- content::TouchAction touch_action) {
+bool TouchActionFilter::FilterGestureEnd() {
+ allowed_touch_action_ = TOUCH_ACTION_AUTO;
+ if (drop_scroll_gesture_events_) {
+ drop_scroll_gesture_events_ = false;
+ return true;
+ }
+ return false;
+}
+
+void TouchActionFilter::OnSetTouchAction(TouchAction touch_action) {
// For multiple fingers, we take the intersection of the touch actions for
// all fingers that have gone down during this action.
// TODO(rbyers): What exact multi-finger semantic do we want? This is left
// as implementation-defined in the pointer events specification.
// crbug.com/247566.
- if (touch_action == content::TOUCH_ACTION_NONE)
- allowed_touch_action_ = content::TOUCH_ACTION_NONE;
+ allowed_touch_action_ = Intersect(allowed_touch_action_, touch_action);
+}
+
+bool TouchActionFilter::ShouldSuppressScroll(
+ const blink::WebGestureEvent& gesture_event) {
+ DCHECK_EQ(gesture_event.type, WebInputEvent::GestureScrollBegin);
+ if (allowed_touch_action_ == TOUCH_ACTION_AUTO)
+ return false;
+ if (allowed_touch_action_ == TOUCH_ACTION_NONE)
+ return true;
+
+ // If there's no hint or it's perfectly diagonal, then allow the scroll.
+ if (fabs(gesture_event.data.scrollBegin.deltaXHint) ==
+ fabs(gesture_event.data.scrollBegin.deltaYHint))
+ return false;
+
+ // Determine the primary initial axis of the scroll, and check whether
+ // panning along that axis is permitted.
+ if (fabs(gesture_event.data.scrollBegin.deltaXHint) >
+ fabs(gesture_event.data.scrollBegin.deltaYHint))
+ return !(allowed_touch_action_ & TOUCH_ACTION_PAN_X);
+ return !(allowed_touch_action_ & TOUCH_ACTION_PAN_Y);
+}
+
+TouchAction TouchActionFilter::Intersect(TouchAction ta1, TouchAction ta2) {
+ if (ta1 == TOUCH_ACTION_NONE || ta2 == TOUCH_ACTION_NONE)
+ return TOUCH_ACTION_NONE;
+ if (ta1 == TOUCH_ACTION_AUTO)
+ return ta2;
+ if (ta2 == TOUCH_ACTION_AUTO)
+ return ta1;
+
+ // Only the true flags are left - take their intersection.
+ if (!(ta1 & ta2))
+ return TOUCH_ACTION_NONE;
+ return static_cast<TouchAction>(ta1 & ta2);
}
}

Powered by Google App Engine
This is Rietveld 408576698