This source file includes following definitions.
- allowed_touch_action_
- FilterGestureEvent
- FilterScrollEndingGesture
- OnSetTouchAction
- ResetTouchAction
- ShouldSuppressScroll
- Intersect
#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;
using blink::WebGestureEvent;
namespace content {
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) {
}
bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
switch(gesture_event->type) {
case WebInputEvent::GestureScrollBegin:
DCHECK(!drop_scroll_gesture_events_);
drop_scroll_gesture_events_ = ShouldSuppressScroll(*gesture_event);
return drop_scroll_gesture_events_;
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::GestureFlingStart:
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;
}
return FilterScrollEndingGesture();
case WebInputEvent::GestureScrollEnd:
return FilterScrollEndingGesture();
case WebInputEvent::GesturePinchBegin:
DCHECK(!drop_pinch_gesture_events_);
if (allowed_touch_action_ == TOUCH_ACTION_AUTO ||
allowed_touch_action_ & TOUCH_ACTION_PINCH_ZOOM) {
DCHECK(allowed_touch_action_ == TOUCH_ACTION_AUTO ||
allowed_touch_action_ == TOUCH_ACTION_MANIPULATION);
DCHECK(!drop_scroll_gesture_events_);
} else {
drop_pinch_gesture_events_ = true;
}
return drop_pinch_gesture_events_;
case WebInputEvent::GesturePinchUpdate:
return drop_pinch_gesture_events_;
case WebInputEvent::GesturePinchEnd:
if (drop_pinch_gesture_events_) {
drop_pinch_gesture_events_ = false;
return true;
}
DCHECK(!drop_scroll_gesture_events_);
break;
case WebInputEvent::GestureDoubleTap:
DCHECK_EQ(1, gesture_event->data.tap.tapCount);
if (!allow_current_double_tap_event_)
gesture_event->type = WebInputEvent::GestureTap;
allow_current_double_tap_event_ = true;
break;
case WebInputEvent::GestureTapUnconfirmed:
DCHECK_EQ(1, gesture_event->data.tap.tapCount);
allow_current_double_tap_event_ =
allowed_touch_action_ == TOUCH_ACTION_AUTO;
if (!allow_current_double_tap_event_) {
gesture_event->type = WebInputEvent::GestureTap;
drop_current_tap_ending_event_ = true;
}
break;
case WebInputEvent::GestureTap:
allow_current_double_tap_event_ =
allowed_touch_action_ == TOUCH_ACTION_AUTO;
case WebInputEvent::GestureTapCancel:
if (drop_current_tap_ending_event_) {
drop_current_tap_ending_event_ = false;
return true;
}
break;
case WebInputEvent::GestureTapDown:
DCHECK(!drop_current_tap_ending_event_);
break;
default:
break;
}
return false;
}
bool TouchActionFilter::FilterScrollEndingGesture() {
DCHECK(!drop_pinch_gesture_events_);
if (drop_scroll_gesture_events_) {
drop_scroll_gesture_events_ = false;
return true;
}
return false;
}
void TouchActionFilter::OnSetTouchAction(TouchAction touch_action) {
allowed_touch_action_ = Intersect(allowed_touch_action_, touch_action);
}
void TouchActionFilter::ResetTouchAction() {
DCHECK(!drop_scroll_gesture_events_);
DCHECK(!drop_pinch_gesture_events_);
allowed_touch_action_ = TOUCH_ACTION_AUTO;
}
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 (fabs(gesture_event.data.scrollBegin.deltaXHint) ==
fabs(gesture_event.data.scrollBegin.deltaYHint))
return false;
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;
if (!(ta1 & ta2))
return TOUCH_ACTION_NONE;
return static_cast<TouchAction>(ta1 & ta2);
}
}