diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 05:27:25 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-07 05:27:25 +0000 |
commit | 60ea81cc5a42676c32505e5cce6fa80835726afd (patch) | |
tree | 4f8aa9e842fe5cac253440ed911a8079498802a2 /ui/base/gestures | |
parent | 1de7a0c58d965df1528f0005ec8d39c907d1b223 (diff) | |
download | chromium_src-60ea81cc5a42676c32505e5cce6fa80835726afd.zip chromium_src-60ea81cc5a42676c32505e5cce6fa80835726afd.tar.gz chromium_src-60ea81cc5a42676c32505e5cce6fa80835726afd.tar.bz2 |
Changes SetCapture to transfer events rather then cancel all.
BUG=124277
TEST=covered by tests.
R=sadrul@chromium.org
Review URL: https://chromiumcodereview.appspot.com/10539037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/gestures')
-rw-r--r-- | ui/base/gestures/gesture_recognizer.h | 9 | ||||
-rw-r--r-- | ui/base/gestures/gesture_recognizer_impl.cc | 112 | ||||
-rw-r--r-- | ui/base/gestures/gesture_recognizer_impl.h | 34 |
3 files changed, 90 insertions, 65 deletions
diff --git a/ui/base/gestures/gesture_recognizer.h b/ui/base/gestures/gesture_recognizer.h index 84085e5..6a4392b 100644 --- a/ui/base/gestures/gesture_recognizer.h +++ b/ui/base/gestures/gesture_recognizer.h @@ -60,10 +60,11 @@ class UI_EXPORT GestureRecognizer { // of |location|, returns the target of the nearest active touch. virtual GestureConsumer* GetTargetForLocation(const gfx::Point& location) = 0; - // For each touch on windows other than |capturer|, a cancel event - // is fired. These touches are then ignored until they are released - // and pressed again. - virtual void CancelNonCapturedTouches(GestureConsumer* capturer) = 0; + // Makes |new_consumer| the target for events previously targetting + // |current_consumer|. All other targets are cancelled. If |new_consumer| is + // NULL, all targets are cancelled. + virtual void TransferEventsTo(GestureConsumer* current_consumer, + GestureConsumer* new_consumer) = 0; }; } // namespace ui diff --git a/ui/base/gestures/gesture_recognizer_impl.cc b/ui/base/gestures/gesture_recognizer_impl.cc index d17606a..350488d 100644 --- a/ui/base/gestures/gesture_recognizer_impl.cc +++ b/ui/base/gestures/gesture_recognizer_impl.cc @@ -12,11 +12,14 @@ #include "ui/base/gestures/gesture_sequence.h" #include "ui/base/gestures/gesture_types.h" +namespace ui { + namespace { + // This is used to pop a std::queue when returning from a function. class ScopedPop { public: - explicit ScopedPop(std::queue<ui::TouchEvent*>* queue) : queue_(queue) { + explicit ScopedPop(std::queue<TouchEvent*>* queue) : queue_(queue) { } ~ScopedPop() { @@ -25,14 +28,14 @@ class ScopedPop { } private: - std::queue<ui::TouchEvent*>* queue_; + std::queue<TouchEvent*>* queue_; DISALLOW_COPY_AND_ASSIGN(ScopedPop); }; -// CancelledTouchEvent mirrors a ui::TouchEvent object. -class MirroredTouchEvent : public ui::TouchEvent { +// CancelledTouchEvent mirrors a TouchEvent object. +class MirroredTouchEvent : public TouchEvent { public: - explicit MirroredTouchEvent(const ui::TouchEvent* real) + explicit MirroredTouchEvent(const TouchEvent* real) : type_(real->GetEventType()), location_(real->GetLocation()), touch_id_(real->GetTouchId()), @@ -47,8 +50,8 @@ class MirroredTouchEvent : public ui::TouchEvent { virtual ~MirroredTouchEvent() { } - // Overridden from ui::TouchEvent. - virtual ui::EventType GetEventType() const OVERRIDE { + // Overridden from TouchEvent. + virtual EventType GetEventType() const OVERRIDE { return type_; } @@ -85,10 +88,10 @@ class MirroredTouchEvent : public ui::TouchEvent { } protected: - void set_type(const ui::EventType type) { type_ = type; } + void set_type(const EventType type) { type_ = type; } private: - ui::EventType type_; + EventType type_; gfx::Point location_; int touch_id_; int flags_; @@ -104,9 +107,9 @@ class MirroredTouchEvent : public ui::TouchEvent { // A mirrored event, except for the type, which is always ET_TOUCH_CANCELLED. class CancelledTouchEvent : public MirroredTouchEvent { public: - explicit CancelledTouchEvent(const ui::TouchEvent* src) + explicit CancelledTouchEvent(const TouchEvent* src) : MirroredTouchEvent(src) { - set_type(ui::ET_TOUCH_CANCELLED); + set_type(ET_TOUCH_CANCELLED); } virtual ~CancelledTouchEvent() {} @@ -117,16 +120,46 @@ class CancelledTouchEvent : public MirroredTouchEvent { // Touches which are cancelled by a touch capture are routed to a // GestureEventIgnorer, which ignores them. -class GestureConsumerIgnorer : public ui::GestureConsumer { +class GestureConsumerIgnorer : public GestureConsumer { public: GestureConsumerIgnorer() : GestureConsumer(true) { } }; -} // namespace +template <typename T> +void TransferConsumer(GestureConsumer* current_consumer, + GestureConsumer* new_consumer, + std::map<GestureConsumer*, T>* map) { + if (map->count(current_consumer)) { + (*map)[new_consumer] = (*map)[current_consumer]; + map->erase(current_consumer); + } +} -namespace ui { +void RemoveConsumerFromMap(GestureConsumer* consumer, + GestureRecognizerImpl::TouchIdToConsumerMap* map) { + for (GestureRecognizerImpl::TouchIdToConsumerMap::iterator i = map->begin(); + i != map->end();) { + if (i->second == consumer) + map->erase(i++); + else + ++i; + } +} + +void TransferTouchIdToConsumerMap( + GestureConsumer* old_consumer, + GestureConsumer* new_consumer, + GestureRecognizerImpl::TouchIdToConsumerMap* map) { + for (GestureRecognizerImpl::TouchIdToConsumerMap::iterator i = map->begin(); + i != map->end(); ++i) { + if (i->second == old_consumer) + i->second = new_consumer; + } +} + +} // namespace //////////////////////////////////////////////////////////////////////////////// // GestureRecognizerImpl, public: @@ -139,6 +172,8 @@ GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper) GestureRecognizerImpl::~GestureRecognizerImpl() { } +// Checks if this finger is already down, if so, returns the current target. +// Otherwise, returns NULL. GestureConsumer* GestureRecognizerImpl::GetTouchLockedTarget( TouchEvent* event) { return touch_id_target_[event->GetTouchId()]; @@ -181,21 +216,33 @@ GestureConsumer* GestureRecognizerImpl::GetTargetForLocation( return NULL; } -void GestureRecognizerImpl::CancelNonCapturedTouches( - GestureConsumer* capturer) { - std::map<int, GestureConsumer*>::iterator i; - // Fire touch cancels, and target touch_ids to gesture_consumer_ignorer. - for (i = touch_id_target_.begin(); i != touch_id_target_.end(); ++i) { - if (capturer != i->second && - touch_id_target_[i->first] != gesture_consumer_ignorer_.get()) { +void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, + GestureConsumer* new_consumer) { + // Send cancel to all those save |new_consumer| and |current_consumer|. + // Don't send a cancel to |current_consumer|, unless |new_consumer| is NULL. + for (TouchIdToConsumerMap::iterator i = touch_id_target_.begin(); + i != touch_id_target_.end(); ++i) { + if (i->second != new_consumer && + (i->second != current_consumer || new_consumer == NULL) && + i->second != gesture_consumer_ignorer_.get()) { scoped_ptr<TouchEvent> touch_event(helper_->CreateTouchEvent( ui::ET_TOUCH_CANCELLED, gfx::Point(0, 0), i->first, base::Time::NowFromSystemTime() - base::Time())); helper_->DispatchCancelTouchEvent(touch_event.get()); - touch_id_target_[i->first] = gesture_consumer_ignorer_.get(); + i->second = gesture_consumer_ignorer_.get(); } } + + // Transer events from |current_consumer| to |new_consumer|. + if (current_consumer && new_consumer) { + TransferTouchIdToConsumerMap(current_consumer, new_consumer, + &touch_id_target_); + TransferTouchIdToConsumerMap(current_consumer, new_consumer, + &touch_id_target_for_gestures_); + TransferConsumer(current_consumer, new_consumer, &event_queue_); + TransferConsumer(current_consumer, new_consumer, &consumer_sequence_); + } } //////////////////////////////////////////////////////////////////////////////// @@ -280,25 +327,8 @@ void GestureRecognizerImpl::FlushTouchQueue(GestureConsumer* consumer) { event_queue_.erase(consumer); } - int touch_id = -1; - std::map<int, GestureConsumer*>::iterator i; - for (i = touch_id_target_.begin(); i != touch_id_target_.end(); ++i) { - if (i->second == consumer) - touch_id = i->first; - } - - if (touch_id_target_.count(touch_id)) - touch_id_target_.erase(touch_id); - - for (i = touch_id_target_for_gestures_.begin(); - i != touch_id_target_for_gestures_.end(); - ++i) { - if (i->second == consumer) - touch_id = i->first; - } - - if (touch_id_target_for_gestures_.count(touch_id)) - touch_id_target_for_gestures_.erase(touch_id); + RemoveConsumerFromMap(consumer, &touch_id_target_); + RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_); } // GestureRecognizer, static diff --git a/ui/base/gestures/gesture_recognizer_impl.h b/ui/base/gestures/gesture_recognizer_impl.h index 9c659eb..18030b7 100644 --- a/ui/base/gestures/gesture_recognizer_impl.h +++ b/ui/base/gestures/gesture_recognizer_impl.h @@ -18,32 +18,27 @@ #include "ui/gfx/point.h" namespace ui { -class TouchEvent; -class GestureEvent; -class GestureSequence; class GestureConsumer; +class GestureEvent; class GestureEventHelper; +class GestureSequence; +class TouchEvent; class UI_EXPORT GestureRecognizerImpl : public GestureRecognizer { public: + typedef std::map<int, GestureConsumer*> TouchIdToConsumerMap; + explicit GestureRecognizerImpl(GestureEventHelper* helper); virtual ~GestureRecognizerImpl(); - // Checks if this finger is already down, if so, returns the current target. - // Otherwise, returns NULL. + // Overridden from GestureRecognizer virtual GestureConsumer* GetTouchLockedTarget(TouchEvent* event) OVERRIDE; - - // Returns the target of the touches the gesture is composed of. virtual GestureConsumer* GetTargetForGestureEvent( GestureEvent* event) OVERRIDE; - virtual GestureConsumer* GetTargetForLocation( const gfx::Point& location) OVERRIDE; - - // Each touch which isn't targeted to capturer results in a touch - // cancel event. These touches are then targeted to - // gesture_consumer_ignorer. - virtual void CancelNonCapturedTouches(GestureConsumer* capturer) OVERRIDE; + virtual void TransferEventsTo(GestureConsumer* current_consumer, + GestureConsumer* new_consumer) OVERRIDE; protected: virtual GestureSequence* CreateSequence(GestureEventHelper* helper); @@ -65,13 +60,12 @@ class UI_EXPORT GestureRecognizerImpl : public GestureRecognizer { std::map<GestureConsumer*, TouchEventQueue*> event_queue_; std::map<GestureConsumer*, GestureSequence*> consumer_sequence_; - // Both touch_id_target_ and touch_id_target_for_gestures_ - // map a touch-id to its target window. - // touch_ids are removed from touch_id_target_ on ET_TOUCH_RELEASE - // and ET_TOUCH_CANCEL. touch_id_target_for_gestures_ never has touch_ids - // removed. - std::map<int, GestureConsumer*> touch_id_target_; - std::map<int, GestureConsumer*> touch_id_target_for_gestures_; + // Both |touch_id_target_| and |touch_id_target_for_gestures_| map a touch-id + // to its target window. touch-ids are removed from |touch_id_target_| on + // ET_TOUCH_RELEASE and ET_TOUCH_CANCEL. |touch_id_target_for_gestures_| are + // removed in FlushTouchQueue(). + TouchIdToConsumerMap touch_id_target_; + TouchIdToConsumerMap touch_id_target_for_gestures_; // Touches cancelled by touch capture are routed to the // gesture_consumer_ignorer_. |