Index: content/browser/renderer_host/input/immediate_input_router.cc |
diff --git a/content/browser/renderer_host/input/immediate_input_router.cc b/content/browser/renderer_host/input/immediate_input_router.cc |
index 444678fda27412acab88c21914cdf0a8ff814935..a21ce452c905783bbd097d256aeca936b45c4e7d 100644 |
--- a/content/browser/renderer_host/input/immediate_input_router.cc |
+++ b/content/browser/renderer_host/input/immediate_input_router.cc |
@@ -23,6 +23,7 @@ |
#include "content/public/browser/notification_types.h" |
#include "content/public/browser/user_metrics.h" |
#include "content/public/common/content_switches.h" |
+#include "content/public/common/touch_action.h" |
#include "ipc/ipc_sender.h" |
#include "ui/events/event.h" |
#include "ui/events/keycodes/keyboard_codes.h" |
@@ -85,6 +86,8 @@ ImmediateInputRouter::ImmediateInputRouter(IPC::Sender* sender, |
mouse_move_pending_(false), |
mouse_wheel_pending_(false), |
has_touch_handler_(false), |
+ drop_scroll_gesture_events_(false), |
+ allowed_touch_action_(content::TOUCH_ACTION_AUTO), |
current_ack_source_(ACK_SOURCE_NONE), |
touch_event_queue_(new TouchEventQueue(this)), |
gesture_event_filter_(new GestureEventFilter(this, this)) { |
@@ -180,7 +183,8 @@ void ImmediateInputRouter::SendKeyboardEvent( |
void ImmediateInputRouter::SendGestureEvent( |
const GestureEventWithLatencyInfo& gesture_event) { |
- HandleGestureScroll(gesture_event); |
+ if (FilterTouchAction(gesture_event)) |
+ return; |
if (!IsInOverscrollGesture() && |
!gesture_event_filter_->ShouldForward(gesture_event)) { |
@@ -227,7 +231,8 @@ void ImmediateInputRouter::SendTouchEventImmediately( |
void ImmediateInputRouter::SendGestureEventImmediately( |
const GestureEventWithLatencyInfo& gesture_event) { |
- HandleGestureScroll(gesture_event); |
+ if (FilterTouchAction(gesture_event)) |
+ return; |
FilterAndSendWebInputEvent(gesture_event.event, gesture_event.latency, false); |
} |
@@ -255,6 +260,8 @@ bool ImmediateInputRouter::OnMessageReceived(const IPC::Message& message) { |
IPC_MESSAGE_HANDLER(ViewHostMsg_SelectRange_ACK, OnSelectRangeAck) |
IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers, |
OnHasTouchEventHandlers) |
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SetTouchAction, |
+ OnSetTouchAction) |
IPC_MESSAGE_UNHANDLED(handled = false) |
IPC_END_MESSAGE_MAP() |
@@ -462,6 +469,23 @@ void ImmediateInputRouter::OnHasTouchEventHandlers(bool has_handlers) { |
client_->OnHasTouchEventHandlers(has_handlers); |
} |
+void ImmediateInputRouter::OnSetTouchAction( |
+ int touch_id, |
+ content::TouchAction touchAction) |
+{ |
+ // Don't process touch-action messages for synthetic touches we know |
+ // nothing about. |
+ if (!touch_event_queue_->IsTouchStartPendingAck(touch_id)) |
+ return; |
+ |
+ // For multiple fingers, we take the intersection of the touch actions for |
+ // all fingers that have gone down during this action. |
+ // TODO(rbyers): Get some agreed upon multi-finger semantic for touch-action |
+ // included in the pointer events specification. crbug.com/241964 |
+ if (touchAction == content::TOUCH_ACTION_NONE) |
+ allowed_touch_action_ = content::TOUCH_ACTION_NONE; |
+} |
+ |
void ImmediateInputRouter::ProcessInputEventAck( |
WebInputEvent::Type event_type, |
InputEventAckState ack_result, |
@@ -591,9 +615,41 @@ void ImmediateInputRouter::ProcessAckForOverscroll( |
event, (INPUT_EVENT_ACK_STATE_CONSUMED == ack_result)); |
} |
-void ImmediateInputRouter::HandleGestureScroll( |
+bool ImmediateInputRouter::FilterTouchAction( |
const GestureEventWithLatencyInfo& gesture_event) { |
+ |
+ // Filter for allowable touch actions first (eg. before the TouchEventQueue |
+ // can decide to send a touch cancel event). |
+ // TODO: Does this belong in GestureEventFilter, even though the filtering |
+ // happens at a different stage from the other filters there? |
+ // TODO(rbyers): Add touch-action control over for pinch. crbug.com/247566. |
+ switch(gesture_event.event.type) { |
+ case WebInputEvent::GestureScrollBegin: |
+ if (allowed_touch_action_ == TOUCH_ACTION_NONE) |
+ drop_scroll_gesture_events_ = true; |
+ // FALL THROUGH |
+ case WebInputEvent::GestureScrollUpdate: |
+ case WebInputEvent::GestureScrollUpdateWithoutPropagation: |
+ if (drop_scroll_gesture_events_) |
+ return true; |
+ 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; |
+ } |
+ break; |
+ |
+ default: |
+ break; |
+ } |
+ |
+ // This touch action is permitted, allow it to cancel in-progress touches. |
touch_event_queue_->OnGestureScrollEvent(gesture_event); |
+ return false; |
} |
void ImmediateInputRouter::SimulateTouchGestureWithMouse( |