| Index: ui/events/gestures/gesture_recognizer_impl.cc
|
| diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc
|
| index 7f27c8f78be3b62f686d58e8b0f0a7b0887b0c9e..569325eb5a1192cb45a2cb68c1f37534ed0e2e9a 100644
|
| --- a/ui/events/gestures/gesture_recognizer_impl.cc
|
| +++ b/ui/events/gestures/gesture_recognizer_impl.cc
|
| @@ -129,8 +129,65 @@ void GestureRecognizerImpl::CancelActiveTouchesExcept(
|
| }
|
| }
|
|
|
| -void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer,
|
| +void GestureRecognizerImpl::BeginDragAndDrop(GestureConsumer* current_consumer,
|
| GestureConsumer* new_consumer) {
|
| + // This method transfers the gesture stream from |current_consumer| to
|
| + // |new_consumer|, while ensuring that both retain a touch event stream which
|
| + // is reasonably valid. In order to do this we
|
| + // - record what pointers are currently down on |current_consumer|
|
| + // - cancel touches on consumers other than |current_consumer|
|
| + // - move the gesture provider from |current_consumer| to |new_consumer|
|
| + // - synchronize the state of the new gesture provider associated with
|
| + // current_consumer with with the touch state of the consumer itself via
|
| + // OnTouchEnter.
|
| + // - synthesize touch cancels on |current_consumer|.
|
| + // - retarget the pointers that were previously targeted to
|
| + // |current_consumer| to |new_consumer|.
|
| + // NOTE: This currently doesn't synthesize touch press events on
|
| + // |new_consumer|, so the event stream it sees is still invalid.
|
| + DCHECK(current_consumer);
|
| + DCHECK(new_consumer);
|
| + GestureEventHelper* helper = FindDispatchHelperForConsumer(current_consumer);
|
| +
|
| + std::vector<int> touchids_targeted_at_current;
|
| +
|
| + for (const auto& touch_id_target: touch_id_target_) {
|
| + if (touch_id_target.second == current_consumer)
|
| + touchids_targeted_at_current.push_back(touch_id_target.first);
|
| + }
|
| +
|
| + CancelActiveTouchesExcept(current_consumer);
|
| +
|
| + std::vector<std::unique_ptr<TouchEvent>> cancelling_touches =
|
| + GetEventPerPointForConsumer(current_consumer, ET_TOUCH_CANCELLED);
|
| +
|
| + TransferConsumer(current_consumer, new_consumer, &consumer_gesture_provider_);
|
| +
|
| + // We're now in a situation where current_consumer has no gesture recognizer,
|
| + // but has some pointers down which need cancelling. In order to ensure that
|
| + // the GR sees a valid event stream, inform it of these pointers via
|
| + // OnTouchEnter, and then synthesize a touch cancel per pointer.
|
| + if (helper) {
|
| + GestureProviderAura* gesture_provider =
|
| + GetGestureProviderForConsumer(current_consumer);
|
| +
|
| + for (std::unique_ptr<TouchEvent>& event : cancelling_touches) {
|
| + gesture_provider->OnTouchEnter(event->touch_id(), event->x(), event->y());
|
| + helper->DispatchSyntheticTouchEvent(event.get());
|
| + }
|
| + }
|
| +
|
| + for (int touch_id : touchids_targeted_at_current)
|
| + touch_id_target_[touch_id] = new_consumer;
|
| +}
|
| +
|
| +
|
| +void GestureRecognizerImpl::BeginTabDrag(GestureConsumer* current_consumer,
|
| + GestureConsumer* new_consumer) {
|
| + // Tab Drag requires that the touches on |current_consumer| not be
|
| + // cancelled. We transfer the gesture provider from |current_consumer| to
|
| + // |new_consumer| without bothering to make the event stream valid for either
|
| + // consumer.
|
| DCHECK(current_consumer);
|
| DCHECK(new_consumer);
|
|
|
| @@ -154,31 +211,40 @@ bool GestureRecognizerImpl::GetLastTouchPointForTarget(
|
| return true;
|
| }
|
|
|
| -bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) {
|
| - bool cancelled_touch = false;
|
| +std::vector<std::unique_ptr<TouchEvent>>
|
| +GestureRecognizerImpl::GetEventPerPointForConsumer(GestureConsumer* consumer,
|
| + EventType type) {
|
| + std::vector<std::unique_ptr<TouchEvent>> cancelling_touches;
|
| if (consumer_gesture_provider_.count(consumer) == 0)
|
| - return false;
|
| + return cancelling_touches;
|
| const MotionEventAura& pointer_state =
|
| consumer_gesture_provider_[consumer]->pointer_state();
|
| if (pointer_state.GetPointerCount() == 0)
|
| - return false;
|
| - // pointer_state is modified every time after DispatchCancelTouchEvent.
|
| - std::unique_ptr<MotionEvent> pointer_state_clone = pointer_state.Clone();
|
| - for (size_t i = 0; i < pointer_state_clone->GetPointerCount(); ++i) {
|
| - TouchEvent touch_event(ui::ET_TOUCH_CANCELLED, gfx::Point(),
|
| - ui::EF_IS_SYNTHESIZED,
|
| - pointer_state_clone->GetPointerId(i),
|
| - ui::EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f);
|
| - gfx::PointF point(pointer_state_clone->GetX(i),
|
| - pointer_state_clone->GetY(i));
|
| - touch_event.set_location_f(point);
|
| - touch_event.set_root_location_f(point);
|
| - GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer);
|
| - if (helper)
|
| - helper->DispatchCancelTouchEvent(consumer, &touch_event);
|
| - cancelled_touch = true;
|
| + return cancelling_touches;
|
| + for (size_t i = 0; i < pointer_state.GetPointerCount(); ++i) {
|
| + std::unique_ptr<TouchEvent> touch_event(new TouchEvent(
|
| + type, gfx::Point(), EF_IS_SYNTHESIZED, pointer_state.GetPointerId(i),
|
| + EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f));
|
| + gfx::PointF point(pointer_state.GetX(i), pointer_state.GetY(i));
|
| + touch_event->set_location_f(point);
|
| + touch_event->set_root_location_f(point);
|
| + cancelling_touches.push_back(std::move(touch_event));
|
| }
|
| - return cancelled_touch;
|
| + return cancelling_touches;
|
| +}
|
| +
|
| +bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) {
|
| + GestureEventHelper* helper =
|
| + FindDispatchHelperForConsumer(consumer);
|
| +
|
| + if (!helper)
|
| + return false;
|
| +
|
| + std::vector<std::unique_ptr<TouchEvent>> cancelling_touches =
|
| + GetEventPerPointForConsumer(consumer, ET_TOUCH_CANCELLED);
|
| + for (const std::unique_ptr<TouchEvent>& cancelling_touch : cancelling_touches)
|
| + helper->DispatchSyntheticTouchEvent(cancelling_touch.get());
|
| + return cancelling_touches.size() > 0U;
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|