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

Unified Diff: ui/events/gestures/gesture_recognizer_impl.cc

Issue 1907323003: Drag and drop cleans up touch sequences from the source window. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update GR state without actually dispatching press events. Created 4 years, 7 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: 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;
}
////////////////////////////////////////////////////////////////////////////////

Powered by Google App Engine
This is Rietveld 408576698