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

Side by Side 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: Fix Mac. 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/gestures/gesture_recognizer_impl.h" 5 #include "ui/events/gestures/gesture_recognizer_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <memory> 10 #include <memory>
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 if (i->second == consumer) { 43 if (i->second == consumer) {
44 map->erase(i++); 44 map->erase(i++);
45 consumer_removed = true; 45 consumer_removed = true;
46 } else { 46 } else {
47 ++i; 47 ++i;
48 } 48 }
49 } 49 }
50 return consumer_removed; 50 return consumer_removed;
51 } 51 }
52 52
53 void TransferTouchIdToConsumerMap(
54 GestureConsumer* old_consumer,
55 GestureConsumer* new_consumer,
56 GestureRecognizerImpl::TouchIdToConsumerMap* map) {
57 for (GestureRecognizerImpl::TouchIdToConsumerMap::iterator i = map->begin();
58 i != map->end(); ++i) {
59 if (i->second == old_consumer)
60 i->second = new_consumer;
61 }
62 }
63
64 GestureProviderAura* CreateGestureProvider(GestureConsumer* consumer, 53 GestureProviderAura* CreateGestureProvider(GestureConsumer* consumer,
65 GestureProviderAuraClient* client) { 54 GestureProviderAuraClient* client) {
66 return new GestureProviderAura(consumer, client); 55 return new GestureProviderAura(consumer, client);
67 } 56 }
68 57
69 } // namespace 58 } // namespace
70 59
71 //////////////////////////////////////////////////////////////////////////////// 60 ////////////////////////////////////////////////////////////////////////////////
72 // GestureRecognizerImpl, public: 61 // GestureRecognizerImpl, public:
73 62
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 111
123 void GestureRecognizerImpl::CancelActiveTouchesExcept( 112 void GestureRecognizerImpl::CancelActiveTouchesExcept(
124 GestureConsumer* not_cancelled) { 113 GestureConsumer* not_cancelled) {
125 for (const auto& consumer_provider : consumer_gesture_provider_) { 114 for (const auto& consumer_provider : consumer_gesture_provider_) {
126 if (consumer_provider.first == not_cancelled) 115 if (consumer_provider.first == not_cancelled)
127 continue; 116 continue;
128 CancelActiveTouches(consumer_provider.first); 117 CancelActiveTouches(consumer_provider.first);
129 } 118 }
130 } 119 }
131 120
132 void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, 121 void GestureRecognizerImpl::TransferEventsTo(
133 GestureConsumer* new_consumer) { 122 GestureConsumer* current_consumer,
123 GestureConsumer* new_consumer,
124 ShouldCancelTouches should_cancel_touches) {
125 // This method transfers the gesture stream from |current_consumer| to
126 // |new_consumer|. If |should_cancel_touches| is Cancel, it ensures that both
127 // consumers retain a touch event stream which is reasonably valid. In order
128 // to do this we
129 // - record what pointers are currently down on |current_consumer|
130 // - cancel touches on consumers other than |current_consumer|
131 // - move the gesture provider from |current_consumer| to |new_consumer|
132 // - if |should_cancel_touches|
133 // - synchronize the state of the new gesture provider associated with
134 // current_consumer with with the touch state of the consumer itself via
135 // OnTouchEnter.
136 // - synthesize touch cancels on |current_consumer|.
137 // - retarget the pointers that were previously targeted to
138 // |current_consumer| to |new_consumer|.
139 // NOTE: This currently doesn't synthesize touch press events on
140 // |new_consumer|, so the event stream it sees is still invalid.
134 DCHECK(current_consumer); 141 DCHECK(current_consumer);
135 DCHECK(new_consumer); 142 DCHECK(new_consumer);
143 GestureEventHelper* helper = FindDispatchHelperForConsumer(current_consumer);
144
145 std::vector<int> touchids_targeted_at_current;
146
147 for (const auto& touch_id_target: touch_id_target_) {
148 if (touch_id_target.second == current_consumer)
149 touchids_targeted_at_current.push_back(touch_id_target.first);
150 }
136 151
137 CancelActiveTouchesExcept(current_consumer); 152 CancelActiveTouchesExcept(current_consumer);
138 153
139 TransferTouchIdToConsumerMap(current_consumer, new_consumer, 154 std::vector<std::unique_ptr<TouchEvent>> cancelling_touches =
140 &touch_id_target_); 155 GetEventPerPointForConsumer(current_consumer, ET_TOUCH_CANCELLED);
156
141 TransferConsumer(current_consumer, new_consumer, &consumer_gesture_provider_); 157 TransferConsumer(current_consumer, new_consumer, &consumer_gesture_provider_);
158
159 // We're now in a situation where current_consumer has no gesture recognizer,
160 // but has some pointers down which need cancelling. In order to ensure that
161 // the GR sees a valid event stream, inform it of these pointers via
162 // OnTouchEnter, and then synthesize a touch cancel per pointer.
163 if (should_cancel_touches ==
164 GestureRecognizer::ShouldCancelTouches::Cancel &&
165 helper) {
166 GestureProviderAura* gesture_provider =
167 GetGestureProviderForConsumer(current_consumer);
168
169 for (std::unique_ptr<TouchEvent>& event : cancelling_touches) {
170 gesture_provider->OnTouchEnter(event->touch_id(), event->x(), event->y());
171 helper->DispatchSyntheticTouchEvent(event.get());
172 }
173 }
174
175 for (int touch_id : touchids_targeted_at_current)
176 touch_id_target_[touch_id] = new_consumer;
142 } 177 }
143 178
144 bool GestureRecognizerImpl::GetLastTouchPointForTarget( 179 bool GestureRecognizerImpl::GetLastTouchPointForTarget(
145 GestureConsumer* consumer, 180 GestureConsumer* consumer,
146 gfx::PointF* point) { 181 gfx::PointF* point) {
147 if (consumer_gesture_provider_.count(consumer) == 0) 182 if (consumer_gesture_provider_.count(consumer) == 0)
148 return false; 183 return false;
149 const MotionEvent& pointer_state = 184 const MotionEvent& pointer_state =
150 consumer_gesture_provider_[consumer]->pointer_state(); 185 consumer_gesture_provider_[consumer]->pointer_state();
151 if (!pointer_state.GetPointerCount()) 186 if (!pointer_state.GetPointerCount())
152 return false; 187 return false;
153 *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY()); 188 *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY());
154 return true; 189 return true;
155 } 190 }
156 191
157 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) { 192 std::vector<std::unique_ptr<TouchEvent>>
158 bool cancelled_touch = false; 193 GestureRecognizerImpl::GetEventPerPointForConsumer(GestureConsumer* consumer,
194 EventType type) {
195 std::vector<std::unique_ptr<TouchEvent>> cancelling_touches;
159 if (consumer_gesture_provider_.count(consumer) == 0) 196 if (consumer_gesture_provider_.count(consumer) == 0)
160 return false; 197 return cancelling_touches;
161 const MotionEventAura& pointer_state = 198 const MotionEventAura& pointer_state =
162 consumer_gesture_provider_[consumer]->pointer_state(); 199 consumer_gesture_provider_[consumer]->pointer_state();
163 if (pointer_state.GetPointerCount() == 0) 200 if (pointer_state.GetPointerCount() == 0)
201 return cancelling_touches;
202 for (size_t i = 0; i < pointer_state.GetPointerCount(); ++i) {
203 std::unique_ptr<TouchEvent> touch_event(new TouchEvent(
204 type, gfx::Point(), EF_IS_SYNTHESIZED, pointer_state.GetPointerId(i),
205 EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f));
206 gfx::PointF point(pointer_state.GetX(i), pointer_state.GetY(i));
207 touch_event->set_location_f(point);
208 touch_event->set_root_location_f(point);
209 cancelling_touches.push_back(std::move(touch_event));
210 }
211 return cancelling_touches;
212 }
213
214 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) {
215 GestureEventHelper* helper =
216 FindDispatchHelperForConsumer(consumer);
217
218 if (!helper)
164 return false; 219 return false;
165 // pointer_state is modified every time after DispatchCancelTouchEvent. 220
166 std::unique_ptr<MotionEvent> pointer_state_clone = pointer_state.Clone(); 221 std::vector<std::unique_ptr<TouchEvent>> cancelling_touches =
167 for (size_t i = 0; i < pointer_state_clone->GetPointerCount(); ++i) { 222 GetEventPerPointForConsumer(consumer, ET_TOUCH_CANCELLED);
168 TouchEvent touch_event(ui::ET_TOUCH_CANCELLED, gfx::Point(), 223 for (const std::unique_ptr<TouchEvent>& cancelling_touch : cancelling_touches)
169 ui::EF_IS_SYNTHESIZED, 224 helper->DispatchSyntheticTouchEvent(cancelling_touch.get());
170 pointer_state_clone->GetPointerId(i), 225 return cancelling_touches.size() > 0U;
171 ui::EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f);
172 gfx::PointF point(pointer_state_clone->GetX(i),
173 pointer_state_clone->GetY(i));
174 touch_event.set_location_f(point);
175 touch_event.set_root_location_f(point);
176 GestureEventHelper* helper = FindDispatchHelperForConsumer(consumer);
177 if (helper)
178 helper->DispatchCancelTouchEvent(consumer, &touch_event);
179 cancelled_touch = true;
180 }
181 return cancelled_touch;
182 } 226 }
183 227
184 //////////////////////////////////////////////////////////////////////////////// 228 ////////////////////////////////////////////////////////////////////////////////
185 // GestureRecognizerImpl, private: 229 // GestureRecognizerImpl, private:
186 230
187 GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer( 231 GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer(
188 GestureConsumer* consumer) { 232 GestureConsumer* consumer) {
189 GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer]; 233 GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer];
190 if (!gesture_provider) { 234 if (!gesture_provider) {
191 gesture_provider = CreateGestureProvider(consumer, this); 235 gesture_provider = CreateGestureProvider(consumer, this);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 std::vector<GestureEventHelper*>::iterator it; 350 std::vector<GestureEventHelper*>::iterator it;
307 for (it = helpers.begin(); it != helpers.end(); ++it) 351 for (it = helpers.begin(); it != helpers.end(); ++it)
308 gesture_recognizer->AddGestureEventHelper(*it); 352 gesture_recognizer->AddGestureEventHelper(*it);
309 353
310 helpers.clear(); 354 helpers.clear();
311 g_gesture_recognizer_instance = 355 g_gesture_recognizer_instance =
312 static_cast<GestureRecognizerImpl*>(gesture_recognizer); 356 static_cast<GestureRecognizerImpl*>(gesture_recognizer);
313 } 357 }
314 358
315 } // namespace ui 359 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/gestures/gesture_recognizer_impl.h ('k') | ui/events/gestures/gesture_recognizer_impl_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698