Commit a98ac8d7 authored by dtapuska's avatar dtapuska Committed by Commit bot

Implement direction-specific touch-action values.

Add PanLeft, PanRight, PanUp and PanDown support by generalizing the PanX and PanY code.

The fix for the bug is a 3 part change and is required
because of the dependencies of blink as there is a static
cast (causing a ABI dependency). To work around this ABI
problem this is part 1 adding the PanXXX definitions to the
content classes and disabling the static assertions and
casting. The second change is
https://codereview.chromium.org/1137483003/. Once that
change has landed a follow up change to this change one
will remove the #if 0 and re-add the static cast between
blink::WebTouchAction and content::TouchAction

BUG=476556
TEST=content_unittests

Review URL: https://codereview.chromium.org/1131093002

Cr-Commit-Position: refs/heads/master@{#329011}
parent 3c886914
......@@ -13,6 +13,19 @@ using blink::WebInputEvent;
using blink::WebGestureEvent;
namespace content {
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));
}
bool IsXAxisActionDisallowed(TouchAction action) {
return ((action & TOUCH_ACTION_PAN_Y) && !(action & TOUCH_ACTION_PAN_X));
}
} // namespace
TouchActionFilter::TouchActionFilter() :
drop_scroll_gesture_events_(false),
......@@ -25,20 +38,22 @@ TouchActionFilter::TouchActionFilter() :
bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
// Filter for allowable touch actions first (eg. before the TouchEventQueue
// can decide to send a touch cancel event).
switch(gesture_event->type) {
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_)
if (drop_scroll_gesture_events_) {
return true;
else {
if (allowed_touch_action_ == TOUCH_ACTION_PAN_X) {
} 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 (allowed_touch_action_ == TOUCH_ACTION_PAN_Y) {
} else if (IsXAxisActionDisallowed(allowed_touch_action_)) {
gesture_event->data.scrollUpdate.deltaX = 0;
gesture_event->data.scrollUpdate.velocityX = 0;
}
......@@ -52,9 +67,11 @@ bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) {
DCHECK(gesture_event->data.flingStart.velocityX ||
gesture_event->data.flingStart.velocityY);
if (!drop_scroll_gesture_events_) {
if (allowed_touch_action_ == TOUCH_ACTION_PAN_X)
// Flings restricted to a specific axis shouldn't permit velocity
// in the perpendicular axis.
if (IsYAxisActionDisallowed(allowed_touch_action_))
gesture_event->data.flingStart.velocityY = 0;
if (allowed_touch_action_ == TOUCH_ACTION_PAN_Y)
else if (IsXAxisActionDisallowed(allowed_touch_action_))
gesture_event->data.flingStart.velocityX = 0;
// As the renderer expects a scroll-ending event, but does not expect a
// zero-velocity fling, convert the now zero-velocity fling accordingly.
......@@ -184,9 +201,27 @@ bool TouchActionFilter::ShouldSuppressScroll(
// 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);
fabs(gesture_event.data.scrollBegin.deltaYHint)) {
if (gesture_event.data.scrollBegin.deltaXHint > 0 &&
allowed_touch_action_ & TOUCH_ACTION_PAN_LEFT) {
return false;
} else if (gesture_event.data.scrollBegin.deltaXHint < 0 &&
allowed_touch_action_ & TOUCH_ACTION_PAN_RIGHT) {
return false;
} else {
return true;
}
} else {
if (gesture_event.data.scrollBegin.deltaYHint > 0 &&
allowed_touch_action_ & TOUCH_ACTION_PAN_UP) {
return false;
} else if (gesture_event.data.scrollBegin.deltaYHint < 0 &&
allowed_touch_action_ & TOUCH_ACTION_PAN_DOWN) {
return false;
} else {
return true;
}
}
}
TouchAction TouchActionFilter::Intersect(TouchAction ta1, TouchAction ta2) {
......@@ -203,4 +238,4 @@ TouchAction TouchActionFilter::Intersect(TouchAction ta1, TouchAction ta2) {
return static_cast<TouchAction>(ta1 & ta2);
}
}
} // namespace content
......@@ -17,17 +17,25 @@ enum TouchAction {
// No scrolling or zooming allowed.
TOUCH_ACTION_NONE = 1 << 0,
TOUCH_ACTION_PAN_X = 1 << 1,
TOUCH_ACTION_PAN_LEFT = 1 << 1,
TOUCH_ACTION_PAN_Y = 1 << 2,
TOUCH_ACTION_PAN_RIGHT = 1 << 2,
TOUCH_ACTION_PAN_X = TOUCH_ACTION_PAN_LEFT | TOUCH_ACTION_PAN_RIGHT,
TOUCH_ACTION_PAN_UP = 1 << 3,
TOUCH_ACTION_PAN_DOWN = 1 << 4,
TOUCH_ACTION_PAN_Y = TOUCH_ACTION_PAN_UP | TOUCH_ACTION_PAN_DOWN,
TOUCH_ACTION_PAN_X_Y = TOUCH_ACTION_PAN_X | TOUCH_ACTION_PAN_Y,
TOUCH_ACTION_PINCH_ZOOM = 1 << 3,
TOUCH_ACTION_PINCH_ZOOM = 1 << 5,
TOUCH_ACTION_MANIPULATION = TOUCH_ACTION_PAN_X_Y | TOUCH_ACTION_PINCH_ZOOM,
TOUCH_ACTION_MAX = (1 << 4) - 1
TOUCH_ACTION_MAX = (1 << 6) - 1
};
} // namespace content
......
......@@ -2322,6 +2322,13 @@ void RenderWidget::hasTouchEventHandlers(bool has_handlers) {
static_assert(int(blink::WebTouchAction##a) == int(TOUCH_ACTION_##b), \
"mismatching enums: " #a)
inline content::TouchAction& operator|=(content::TouchAction& a,
content::TouchAction b) {
a = static_cast<content::TouchAction>(static_cast<int>(a) |
static_cast<int>(b));
return a;
}
void RenderWidget::setTouchAction(
blink::WebTouchAction web_touch_action) {
......@@ -2330,15 +2337,35 @@ void RenderWidget::setTouchAction(
if (handling_event_type_ != WebInputEvent::TouchStart)
return;
// Verify the same values are used by the types so we can cast between them.
// TODO(dtapuska): A dependant change needs to land in blink to change
// the blink::WebTouchAction enum; in the meantime don't do
// a static cast between the values. (http://crbug.com/476556)
#if 0
// Verify the same values are used by the types so we can cast between them.
STATIC_ASSERT_WTI_ENUM_MATCH(Auto, AUTO);
STATIC_ASSERT_WTI_ENUM_MATCH(None, NONE);
STATIC_ASSERT_WTI_ENUM_MATCH(PanLeft, PAN_LEFT);
STATIC_ASSERT_WTI_ENUM_MATCH(PanRight, PAN_RIGHT);
STATIC_ASSERT_WTI_ENUM_MATCH(PanX, PAN_X);
STATIC_ASSERT_WTI_ENUM_MATCH(PanUp, PAN_UP);
STATIC_ASSERT_WTI_ENUM_MATCH(PanDown, PAN_DOWN);
STATIC_ASSERT_WTI_ENUM_MATCH(PanY, PAN_Y);
STATIC_ASSERT_WTI_ENUM_MATCH(PinchZoom, PINCH_ZOOM);
content::TouchAction content_touch_action =
static_cast<content::TouchAction>(web_touch_action);
#else
content::TouchAction content_touch_action = TOUCH_ACTION_AUTO;
if (web_touch_action & blink::WebTouchActionNone)
content_touch_action |= TOUCH_ACTION_NONE;
if (web_touch_action & blink::WebTouchActionPanX)
content_touch_action |= TOUCH_ACTION_PAN_X;
if (web_touch_action & blink::WebTouchActionPanY)
content_touch_action |= TOUCH_ACTION_PAN_Y;
if (web_touch_action & blink::WebTouchActionPinchZoom)
content_touch_action |= TOUCH_ACTION_PINCH_ZOOM;
#endif
Send(new InputHostMsg_SetTouchAction(routing_id_, content_touch_action));
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment