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 7e044639028cc9b77c405409ba7c68b6edf1f0ba..8f49a6fb5235a117dda11b810b88530bb3ca04f2 100644 |
--- a/ui/events/gestures/gesture_recognizer_impl.cc |
+++ b/ui/events/gestures/gesture_recognizer_impl.cc |
@@ -4,11 +4,16 @@ |
#include "ui/events/gestures/gesture_recognizer_impl.h" |
+#include <limits> |
+ |
+#include "base/command_line.h" |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/message_loop/message_loop.h" |
#include "base/time/time.h" |
#include "ui/events/event.h" |
#include "ui/events/event_constants.h" |
+#include "ui/events/event_switches.h" |
#include "ui/events/event_utils.h" |
#include "ui/events/gestures/gesture_configuration.h" |
#include "ui/events/gestures/gesture_sequence.h" |
@@ -54,16 +59,27 @@ void TransferTouchIdToConsumerMap( |
} |
} |
+GestureProviderAura* CreateGestureProvider(GestureProviderAuraClient* client) { |
+ return new GestureProviderAura(client); |
+} |
+ |
+void DeleteGestureProvider(GestureProviderAura* provider) { |
+ delete provider; |
+} |
+ |
} // namespace |
//////////////////////////////////////////////////////////////////////////////// |
// GestureRecognizerImpl, public: |
-GestureRecognizerImpl::GestureRecognizerImpl() { |
+GestureRecognizerImpl::GestureRecognizerImpl() |
+ : use_unified_gesture_detector_(CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kUseUnifiedGestureDetector)) { |
} |
GestureRecognizerImpl::~GestureRecognizerImpl() { |
STLDeleteValues(&consumer_sequence_); |
+ STLDeleteValues(&consumer_gesture_provider_); |
} |
// Checks if this finger is already down, if so, returns the current target. |
@@ -83,34 +99,65 @@ GestureConsumer* GestureRecognizerImpl::GetTargetForGestureEvent( |
GestureConsumer* GestureRecognizerImpl::GetTargetForLocation( |
const gfx::PointF& location, int source_device_id) { |
- const GesturePoint* closest_point = NULL; |
- int64 closest_distance_squared = 0; |
- std::map<GestureConsumer*, GestureSequence*>::iterator i; |
- for (i = consumer_sequence_.begin(); i != consumer_sequence_.end(); ++i) { |
- const GesturePoint* points = i->second->points(); |
- for (int j = 0; j < GestureSequence::kMaxGesturePoints; ++j) { |
- if (!points[j].in_use() || |
- source_device_id != points[j].source_device_id()) { |
- continue; |
- } |
- gfx::Vector2dF delta = points[j].last_touch_position() - location; |
- // Relative distance is all we need here, so LengthSquared() is |
- // appropriate, and cheaper than Length(). |
- int64 distance_squared = delta.LengthSquared(); |
- if (!closest_point || distance_squared < closest_distance_squared) { |
- closest_point = &points[j]; |
- closest_distance_squared = distance_squared; |
+ const int max_distance = |
+ GestureConfiguration::max_separation_for_gesture_touches_in_pixels(); |
+ |
+ if (!use_unified_gesture_detector_) { |
+ const GesturePoint* closest_point = NULL; |
+ int64 closest_distance_squared = 0; |
+ std::map<GestureConsumer*, GestureSequence*>::iterator i; |
+ for (i = consumer_sequence_.begin(); i != consumer_sequence_.end(); ++i) { |
+ const GesturePoint* points = i->second->points(); |
+ for (int j = 0; j < GestureSequence::kMaxGesturePoints; ++j) { |
+ if (!points[j].in_use() || |
+ source_device_id != points[j].source_device_id()) { |
+ continue; |
+ } |
+ gfx::Vector2dF delta = points[j].last_touch_position() - location; |
+ // Relative distance is all we need here, so LengthSquared() is |
+ // appropriate, and cheaper than Length(). |
+ int64 distance_squared = delta.LengthSquared(); |
+ if (!closest_point || distance_squared < closest_distance_squared) { |
+ closest_point = &points[j]; |
+ closest_distance_squared = distance_squared; |
+ } |
} |
} |
- } |
- const int max_distance = |
- GestureConfiguration::max_separation_for_gesture_touches_in_pixels(); |
+ if (closest_distance_squared < max_distance * max_distance && closest_point) |
+ return touch_id_target_[closest_point->touch_id()]; |
+ else |
+ return NULL; |
+ } else { |
+ gfx::PointF closest_point; |
+ int closest_touch_id; |
+ float closest_distance_squared = std::numeric_limits<float>::infinity(); |
+ |
+ std::map<GestureConsumer*, GestureProviderAura*>::iterator i; |
+ for (i = consumer_gesture_provider_.begin(); |
+ i != consumer_gesture_provider_.end(); |
+ ++i) { |
+ const MotionEventAura& pointer_state = i->second->pointer_state(); |
+ for (size_t j = 0; j < pointer_state.GetPointerCount(); ++j) { |
+ if (source_device_id != pointer_state.GetSourceDeviceId(j)) |
+ continue; |
+ gfx::PointF point(pointer_state.GetX(j), pointer_state.GetY(j)); |
+ // Relative distance is all we need here, so LengthSquared() is |
+ // appropriate, and cheaper than Length(). |
+ float distance_squared = (point - location).LengthSquared(); |
+ if (distance_squared < closest_distance_squared) { |
+ closest_point = point; |
+ closest_touch_id = pointer_state.GetPointerId(j); |
+ closest_distance_squared = distance_squared; |
+ } |
+ } |
+ } |
- if (closest_distance_squared < max_distance * max_distance && closest_point) |
- return touch_id_target_[closest_point->touch_id()]; |
- else |
- return NULL; |
+ if (closest_distance_squared < max_distance * max_distance) |
+ return touch_id_target_[closest_touch_id]; |
+ else |
+ return NULL; |
+ } |
} |
void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, |
@@ -140,18 +187,30 @@ void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, |
&touch_id_target_); |
TransferTouchIdToConsumerMap(current_consumer, new_consumer, |
&touch_id_target_for_gestures_); |
- TransferConsumer(current_consumer, new_consumer, &consumer_sequence_); |
+ if (!use_unified_gesture_detector_) |
+ TransferConsumer(current_consumer, new_consumer, &consumer_sequence_); |
+ else |
+ TransferConsumer( |
+ current_consumer, new_consumer, &consumer_gesture_provider_); |
} |
} |
bool GestureRecognizerImpl::GetLastTouchPointForTarget( |
GestureConsumer* consumer, |
gfx::PointF* point) { |
- if (consumer_sequence_.count(consumer) == 0) |
- return false; |
- |
- *point = consumer_sequence_[consumer]->last_touch_location(); |
- return true; |
+ if (!use_unified_gesture_detector_) { |
+ if (consumer_sequence_.count(consumer) == 0) |
+ return false; |
+ *point = consumer_sequence_[consumer]->last_touch_location(); |
+ return true; |
+ } else { |
+ if (consumer_gesture_provider_.count(consumer) == 0) |
+ return false; |
+ const MotionEvent& pointer_state = |
+ consumer_gesture_provider_[consumer]->pointer_state(); |
+ *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY()); |
+ return true; |
+ } |
} |
bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) { |
@@ -187,6 +246,16 @@ GestureSequence* GestureRecognizerImpl::GetGestureSequenceForConsumer( |
return gesture_sequence; |
} |
+GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer( |
+ GestureConsumer* consumer) { |
+ GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer]; |
+ if (!gesture_provider) { |
+ gesture_provider = CreateGestureProvider(this); |
+ consumer_gesture_provider_[consumer] = gesture_provider; |
+ } |
+ return gesture_provider; |
+} |
+ |
void GestureRecognizerImpl::SetupTargets(const TouchEvent& event, |
GestureConsumer* target) { |
if (event.type() == ui::ET_TOUCH_RELEASED || |
@@ -214,22 +283,57 @@ void GestureRecognizerImpl::CancelTouches( |
} |
} |
+void GestureRecognizerImpl::DispatchGestureEvent(GestureEvent* event) { |
+ GestureConsumer* consumer = GetTargetForGestureEvent(*event); |
+ if (consumer) { |
+ GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer); |
+ if (helper) |
+ helper->DispatchGestureEvent(event); |
+ } |
+} |
+ |
GestureSequence::Gestures* GestureRecognizerImpl::ProcessTouchEventForGesture( |
const TouchEvent& event, |
ui::EventResult result, |
GestureConsumer* target) { |
SetupTargets(event, target); |
- GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target); |
- return gesture_sequence->ProcessTouchEventForGesture(event, result); |
+ |
+ if (!use_unified_gesture_detector_) { |
+ GestureSequence* gesture_sequence = GetGestureSequenceForConsumer(target); |
+ return gesture_sequence->ProcessTouchEventForGesture(event, result); |
+ } else { |
+ GestureProviderAura* gesture_provider = |
+ GetGestureProviderForConsumer(target); |
+ // TODO(tdresser) - detect gestures eagerly. |
+ if (!(result & ER_CONSUMED)) { |
+ if (gesture_provider->OnTouchEvent(event)) |
+ gesture_provider->OnTouchEventAck(result != ER_UNHANDLED); |
+ } |
+ return NULL; |
+ } |
} |
bool GestureRecognizerImpl::CleanupStateForConsumer( |
GestureConsumer* consumer) { |
bool state_cleaned_up = false; |
- if (consumer_sequence_.count(consumer)) { |
- state_cleaned_up = true; |
- delete consumer_sequence_[consumer]; |
- consumer_sequence_.erase(consumer); |
+ |
+ if (!use_unified_gesture_detector_) { |
+ if (consumer_sequence_.count(consumer)) { |
+ state_cleaned_up = true; |
+ delete consumer_sequence_[consumer]; |
+ consumer_sequence_.erase(consumer); |
+ } |
+ } else { |
+ if (consumer_gesture_provider_.count(consumer)) { |
+ state_cleaned_up = true; |
+ // Don't immediately delete the GestureProvider, as we could be in the |
+ // middle of dispatching a set of gestures. |
+ base::MessageLoop::current()->PostTask( |
sadrul
2014/05/07 13:42:17
Use DeleteSoon instead
tdresser
2014/05/07 14:04:17
Nice, thanks!
Done.
|
+ FROM_HERE, |
+ base::Bind(&DeleteGestureProvider, |
+ consumer_gesture_provider_[consumer])); |
+ consumer_gesture_provider_.erase(consumer); |
+ } |
} |
state_cleaned_up |= RemoveConsumerFromMap(consumer, &touch_id_target_); |
@@ -251,12 +355,12 @@ void GestureRecognizerImpl::RemoveGestureEventHelper( |
} |
void GestureRecognizerImpl::DispatchPostponedGestureEvent(GestureEvent* event) { |
- GestureConsumer* consumer = GetTargetForGestureEvent(*event); |
- if (consumer) { |
- GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer); |
- if (helper) |
- helper->DispatchPostponedGestureEvent(event); |
- } |
+ DispatchGestureEvent(event); |
+} |
+ |
+void GestureRecognizerImpl::OnGestureEvent(scoped_ptr<GestureEvent> event) { |
+ // |event| is destroyed after |DispatchGestureEvent| is called. |
+ DispatchGestureEvent(event.get()); |
} |
GestureEventHelper* GestureRecognizerImpl::FindDispatchHelperForConsumer( |