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

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

Issue 2726623002: Fixed two-finger pan filtering with 'touch-action: pan-x pan-y'. (Closed)
Patch Set: Dave's comments. Created 3 years, 9 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/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 8c86cd5a13c45a2517ddc54b021b7a6243ce74a7..d51412c74f3c4184c4273d845e26f04cbc672201 100644
--- a/content/browser/renderer_host/input/touch_action_filter.cc
+++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -18,22 +18,20 @@ namespace {
// Actions on an axis are disallowed if the perpendicular axis has a filter set
// and no filter is set for the queried axis.
bool IsYAxisActionDisallowed(TouchAction action) {
- return ((action & TOUCH_ACTION_PAN_X) && !(action & TOUCH_ACTION_PAN_Y));
+ return (action & TOUCH_ACTION_PAN_X) && !(action & TOUCH_ACTION_PAN_Y);
}
bool IsXAxisActionDisallowed(TouchAction action) {
- return ((action & TOUCH_ACTION_PAN_Y) && !(action & TOUCH_ACTION_PAN_X));
+ return (action & TOUCH_ACTION_PAN_Y) && !(action & TOUCH_ACTION_PAN_X);
}
} // namespace
-TouchActionFilter::TouchActionFilter() :
- drop_scroll_gesture_events_(false),
- drop_pinch_gesture_events_(false),
- drop_current_tap_ending_event_(false),
- allow_current_double_tap_event_(true),
- allowed_touch_action_(TOUCH_ACTION_AUTO) {
-}
+TouchActionFilter::TouchActionFilter()
+ : suppress_manipulation_events_(false),
+ drop_current_tap_ending_event_(false),
+ allow_current_double_tap_event_(true),
+ allowed_touch_action_(TOUCH_ACTION_AUTO) {}
bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
if (gesture_event->sourceDevice != blink::WebGestureDeviceTouchscreen)
@@ -43,26 +41,29 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
// can decide to send a touch cancel event).
switch (gesture_event->type()) {
case WebInputEvent::GestureScrollBegin:
- DCHECK(!drop_scroll_gesture_events_);
- DCHECK(!drop_pinch_gesture_events_);
- drop_pinch_gesture_events_ =
- (allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) == 0;
- drop_scroll_gesture_events_ = ShouldSuppressScroll(*gesture_event);
- return drop_scroll_gesture_events_;
+ DCHECK(!suppress_manipulation_events_);
+ suppress_manipulation_events_ =
+ ShouldSuppressManipulation(*gesture_event);
+ return suppress_manipulation_events_;
case WebInputEvent::GestureScrollUpdate:
- if (drop_scroll_gesture_events_) {
+ if (suppress_manipulation_events_)
return true;
- } else {
- // Scrolls restricted to a specific axis shouldn't permit movement
- // in the perpendicular axis.
- if (IsYAxisActionDisallowed(allowed_touch_action_)) {
- gesture_event->data.scrollUpdate.deltaY = 0;
- gesture_event->data.scrollUpdate.velocityY = 0;
- } else if (IsXAxisActionDisallowed(allowed_touch_action_)) {
- gesture_event->data.scrollUpdate.deltaX = 0;
- gesture_event->data.scrollUpdate.velocityX = 0;
- }
+
+ // Scrolls restricted to a specific axis shouldn't permit movement
+ // in the perpendicular axis.
+ //
+ // Note the direction suppression with pinch-zoom here, which matches
+ // Edge: a "touch-action: pan-y pinch-zoom" region allows vertical
+ // two-finger scrolling but a "touch-action: pan-x pinch-zoom" region
+ // doesn't.
+ // TODO(mustaq): Add it to spec?
+ if (IsYAxisActionDisallowed(allowed_touch_action_)) {
+ gesture_event->data.scrollUpdate.deltaY = 0;
+ gesture_event->data.scrollUpdate.velocityY = 0;
+ } else if (IsXAxisActionDisallowed(allowed_touch_action_)) {
+ gesture_event->data.scrollUpdate.deltaX = 0;
+ gesture_event->data.scrollUpdate.velocityX = 0;
}
break;
@@ -70,7 +71,7 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
// Touchscreen flings should always have non-zero velocity.
DCHECK(gesture_event->data.flingStart.velocityX ||
gesture_event->data.flingStart.velocityY);
- if (!drop_scroll_gesture_events_) {
+ if (!suppress_manipulation_events_) {
// Flings restricted to a specific axis shouldn't permit velocity
// in the perpendicular axis.
if (IsYAxisActionDisallowed(allowed_touch_action_))
@@ -84,23 +85,15 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
gesture_event->setType(WebInputEvent::GestureScrollEnd);
}
}
- return FilterScrollEndingGesture();
+ return FilterManipulationEventAndResetState();
case WebInputEvent::GestureScrollEnd:
- return FilterScrollEndingGesture();
+ return FilterManipulationEventAndResetState();
case WebInputEvent::GesturePinchBegin:
- return drop_pinch_gesture_events_;
-
case WebInputEvent::GesturePinchUpdate:
- return drop_pinch_gesture_events_;
-
case WebInputEvent::GesturePinchEnd:
- // TODO(mustaq): Don't reset drop_pinch_gesture_events_ here because a
- // pinch-zoom-out-then-zoom-in sends two separate pinch sequences within a
- // single gesture-scroll sequence, see crbug.com/662047#c13. Is it
- // expected?
- return drop_pinch_gesture_events_;
+ return suppress_manipulation_events_;
// The double tap gesture is a tap ending event. If a double tap gesture is
// filtered out, replace it with a tap event.
@@ -126,6 +119,7 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
allow_current_double_tap_event_ =
(allowed_touch_action_ & TOUCH_ACTION_DOUBLE_TAP_ZOOM) != 0;
// Fall through.
+
case WebInputEvent::GestureTapCancel:
if (drop_current_tap_ending_event_) {
drop_current_tap_ending_event_ = false;
@@ -146,10 +140,9 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
return false;
}
-bool TouchActionFilter::FilterScrollEndingGesture() {
- drop_pinch_gesture_events_ = false;
- if (drop_scroll_gesture_events_) {
- drop_scroll_gesture_events_ = false;
+bool TouchActionFilter::FilterManipulationEventAndResetState() {
+ if (suppress_manipulation_events_) {
+ suppress_manipulation_events_ = false;
return true;
}
return false;
@@ -176,15 +169,15 @@ void TouchActionFilter::ResetTouchAction() {
allowed_touch_action_ = TOUCH_ACTION_AUTO;
}
-bool TouchActionFilter::ShouldSuppressScroll(
+bool TouchActionFilter::ShouldSuppressManipulation(
const blink::WebGestureEvent& gesture_event) {
DCHECK_EQ(gesture_event.type(), WebInputEvent::GestureScrollBegin);
- // if there are two or more pointers then ensure that we allow panning
- // if pinch-zoom is allowed. Determine if this should really occur in the
- // GestureScrollBegin or not; see crbug.com/649034.
- if (!drop_pinch_gesture_events_ &&
- gesture_event.data.scrollBegin.pointerCount >= 2) {
- return false;
+
+ if (gesture_event.data.scrollBegin.pointerCount >= 2) {
+ // Any GestureScrollBegin with more than one fingers is like a pinch-zoom
+ // for touch-actions, see crbug.com/632525. Therefore, we switch to
+ // blocked-manipulation mode iff pinch-zoom is disallowed.
+ return (allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) == 0;
}
if ((allowed_touch_action_ & TOUCH_ACTION_PAN) == TOUCH_ACTION_PAN)
@@ -196,6 +189,11 @@ bool TouchActionFilter::ShouldSuppressScroll(
return true;
// If there's no hint or it's perfectly diagonal, then allow the scroll.
+ // Note, however, that the panning direction of the following GSU/GPB events
+ // is updated if needed to make them touch-action compliant.
+ //
+ // TODO(mustaq): With unidirectional touch-action, this can
+ // allow wrong panning with diagonal swipes. Investigate. crbug.com/697102
if (fabs(gesture_event.data.scrollBegin.deltaXHint) ==
fabs(gesture_event.data.scrollBegin.deltaYHint))
return false;

Powered by Google App Engine
This is Rietveld 408576698