Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 122 | 122 |
| 123 void GestureRecognizerImpl::CancelActiveTouchesExcept( | 123 void GestureRecognizerImpl::CancelActiveTouchesExcept( |
| 124 GestureConsumer* not_cancelled) { | 124 GestureConsumer* not_cancelled) { |
| 125 for (const auto& consumer_provider : consumer_gesture_provider_) { | 125 for (const auto& consumer_provider : consumer_gesture_provider_) { |
| 126 if (consumer_provider.first == not_cancelled) | 126 if (consumer_provider.first == not_cancelled) |
| 127 continue; | 127 continue; |
| 128 CancelActiveTouches(consumer_provider.first); | 128 CancelActiveTouches(consumer_provider.first); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 | 131 |
| 132 void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer, | 132 void GestureRecognizerImpl::BeginDragAndDrop(GestureConsumer* current_consumer, |
| 133 GestureConsumer* new_consumer) { | 133 GestureConsumer* new_consumer) { |
| 134 // This method transfers the gesture stream from |current_consumer| to | |
| 135 // |new_consumer|, while ensuring that both retain a touch event stream which | |
| 136 // is reasonably valid. In order to do this we | |
| 137 // - record what pointers are currently down on |current_consumer| | |
| 138 // - cancel touches on consumers other than |current_consumer| | |
| 139 // - move the gesture provider from |current_consumer| to |new_consumer| | |
| 140 // - synthesize touch presses on |current_consumer|, to get the state of its | |
| 141 // new, empty gesture provider in line with the touch state of the consumer | |
| 142 // itself | |
| 143 // - synthesize touch cancels on |current_consumer| | |
| 144 // - retarget the pointers that were previously targeted to | |
| 145 // |current_consumer| to |new_consumer|. | |
| 146 // NOTE: This currently doesn't synthesize touch press events on | |
| 147 // |new_consumer|, so the event stream it sees is still invalid. | |
| 148 DCHECK(current_consumer); | |
| 149 DCHECK(new_consumer); | |
| 150 GestureEventHelper* helper = FindDispatchHelperForConsumer(current_consumer); | |
| 151 | |
| 152 std::vector<int> touchids_targeted_at_current; | |
| 153 | |
| 154 for (const auto& touch_id_target: touch_id_target_) { | |
| 155 if (touch_id_target.second == current_consumer) | |
| 156 touchids_targeted_at_current.push_back(touch_id_target.first); | |
| 157 } | |
| 158 | |
| 159 CancelActiveTouchesExcept(current_consumer); | |
| 160 | |
| 161 std::vector<std::unique_ptr<TouchEvent>> pressing_touches = | |
| 162 GetEventPerPointForConsumer(current_consumer, ET_TOUCH_PRESSED); | |
| 163 std::vector<std::unique_ptr<TouchEvent>> cancelling_touches = | |
| 164 GetEventPerPointForConsumer(current_consumer, ET_TOUCH_CANCELLED); | |
| 165 | |
| 166 TransferConsumer(current_consumer, new_consumer, &consumer_gesture_provider_); | |
| 167 | |
| 168 if (!helper) | |
| 169 return; | |
| 170 | |
| 171 // We're now in a situation where current_consumer has no gesture recognizer, | |
| 172 // but has some pointers down which need cancelling. In order to ensure that | |
| 173 // the GR sees a valid event stream, synthesize a touch press per pointer, and | |
| 174 // then synthesize a touch cancel per pointer. These extra touch presses will | |
| 175 // be filtered out in the RenderWidgetHostViewAura. | |
| 176 | |
| 177 for (std::unique_ptr<TouchEvent>& event : pressing_touches) | |
| 178 helper->DispatchSyntheticTouchEvent(event.get()); | |
|
sadrul
2016/05/03 18:38:16
We really shouldn't dispatch a second set of touch
tdresser
2016/05/03 18:56:42
That would mean we'd need to relax this:
https://c
sadrul
2016/05/04 13:28:18
If not overly complicated, then yeah, I would go w
| |
| 179 | |
| 180 for (std::unique_ptr<TouchEvent>& event : cancelling_touches) | |
| 181 helper->DispatchSyntheticTouchEvent(event.get()); | |
| 182 | |
| 183 for (int touch_id : touchids_targeted_at_current) | |
| 184 touch_id_target_[touch_id] = new_consumer; | |
| 185 } | |
| 186 | |
| 187 | |
| 188 void GestureRecognizerImpl::BeginTabDrag(GestureConsumer* current_consumer, | |
| 189 GestureConsumer* new_consumer) { | |
| 190 // Tab Drag requires that the touches on |current_consumer| not be | |
| 191 // cancelled. We transfer the gesture provider from |current_consumer| to | |
| 192 // |new_consumer| without bothering to make the event stream valid for either | |
| 193 // consumer. | |
| 134 DCHECK(current_consumer); | 194 DCHECK(current_consumer); |
| 135 DCHECK(new_consumer); | 195 DCHECK(new_consumer); |
| 136 | 196 |
| 137 CancelActiveTouchesExcept(current_consumer); | 197 CancelActiveTouchesExcept(current_consumer); |
| 138 | 198 |
| 139 TransferTouchIdToConsumerMap(current_consumer, new_consumer, | 199 TransferTouchIdToConsumerMap(current_consumer, new_consumer, |
| 140 &touch_id_target_); | 200 &touch_id_target_); |
| 141 TransferConsumer(current_consumer, new_consumer, &consumer_gesture_provider_); | 201 TransferConsumer(current_consumer, new_consumer, &consumer_gesture_provider_); |
| 142 } | 202 } |
| 143 | 203 |
| 144 bool GestureRecognizerImpl::GetLastTouchPointForTarget( | 204 bool GestureRecognizerImpl::GetLastTouchPointForTarget( |
| 145 GestureConsumer* consumer, | 205 GestureConsumer* consumer, |
| 146 gfx::PointF* point) { | 206 gfx::PointF* point) { |
| 147 if (consumer_gesture_provider_.count(consumer) == 0) | 207 if (consumer_gesture_provider_.count(consumer) == 0) |
| 148 return false; | 208 return false; |
| 149 const MotionEvent& pointer_state = | 209 const MotionEvent& pointer_state = |
| 150 consumer_gesture_provider_[consumer]->pointer_state(); | 210 consumer_gesture_provider_[consumer]->pointer_state(); |
| 151 if (!pointer_state.GetPointerCount()) | 211 if (!pointer_state.GetPointerCount()) |
| 152 return false; | 212 return false; |
| 153 *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY()); | 213 *point = gfx::PointF(pointer_state.GetX(), pointer_state.GetY()); |
| 154 return true; | 214 return true; |
| 155 } | 215 } |
| 156 | 216 |
| 157 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) { | 217 std::vector<std::unique_ptr<TouchEvent>> |
| 158 bool cancelled_touch = false; | 218 GestureRecognizerImpl::GetEventPerPointForConsumer(GestureConsumer* consumer, |
| 219 EventType type) { | |
| 220 std::vector<std::unique_ptr<TouchEvent>> cancelling_touches; | |
| 159 if (consumer_gesture_provider_.count(consumer) == 0) | 221 if (consumer_gesture_provider_.count(consumer) == 0) |
| 160 return false; | 222 return cancelling_touches; |
| 161 const MotionEventAura& pointer_state = | 223 const MotionEventAura& pointer_state = |
| 162 consumer_gesture_provider_[consumer]->pointer_state(); | 224 consumer_gesture_provider_[consumer]->pointer_state(); |
| 163 if (pointer_state.GetPointerCount() == 0) | 225 if (pointer_state.GetPointerCount() == 0) |
| 226 return cancelling_touches; | |
| 227 for (size_t i = 0; i < pointer_state.GetPointerCount(); ++i) { | |
| 228 std::unique_ptr<TouchEvent> touch_event(new TouchEvent( | |
| 229 type, gfx::Point(), EF_IS_SYNTHESIZED, pointer_state.GetPointerId(i), | |
| 230 EventTimeForNow(), 0.0f, 0.0f, 0.0f, 0.0f)); | |
| 231 gfx::PointF point(pointer_state.GetX(i), pointer_state.GetY(i)); | |
| 232 touch_event->set_location_f(point); | |
| 233 touch_event->set_root_location_f(point); | |
| 234 cancelling_touches.push_back(std::move(touch_event)); | |
| 235 } | |
| 236 return cancelling_touches; | |
| 237 } | |
| 238 | |
| 239 bool GestureRecognizerImpl::CancelActiveTouches(GestureConsumer* consumer) { | |
| 240 GestureEventHelper* helper = | |
| 241 FindDispatchHelperForConsumer(consumer); | |
| 242 | |
| 243 if (!helper) | |
| 164 return false; | 244 return false; |
| 165 // pointer_state is modified every time after DispatchCancelTouchEvent. | 245 |
| 166 std::unique_ptr<MotionEvent> pointer_state_clone = pointer_state.Clone(); | 246 std::vector<std::unique_ptr<TouchEvent>> cancelling_touches = |
| 167 for (size_t i = 0; i < pointer_state_clone->GetPointerCount(); ++i) { | 247 GetEventPerPointForConsumer(consumer, ET_TOUCH_CANCELLED); |
| 168 TouchEvent touch_event(ui::ET_TOUCH_CANCELLED, gfx::Point(), | 248 for (const std::unique_ptr<TouchEvent>& cancelling_touch : cancelling_touches) |
| 169 ui::EF_IS_SYNTHESIZED, | 249 helper->DispatchSyntheticTouchEvent(cancelling_touch.get()); |
| 170 pointer_state_clone->GetPointerId(i), | 250 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 } | 251 } |
| 183 | 252 |
| 184 //////////////////////////////////////////////////////////////////////////////// | 253 //////////////////////////////////////////////////////////////////////////////// |
| 185 // GestureRecognizerImpl, private: | 254 // GestureRecognizerImpl, private: |
| 186 | 255 |
| 187 GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer( | 256 GestureProviderAura* GestureRecognizerImpl::GetGestureProviderForConsumer( |
| 188 GestureConsumer* consumer) { | 257 GestureConsumer* consumer) { |
| 189 GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer]; | 258 GestureProviderAura* gesture_provider = consumer_gesture_provider_[consumer]; |
| 190 if (!gesture_provider) { | 259 if (!gesture_provider) { |
| 191 gesture_provider = CreateGestureProvider(consumer, this); | 260 gesture_provider = CreateGestureProvider(consumer, this); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 std::vector<GestureEventHelper*>::iterator it; | 375 std::vector<GestureEventHelper*>::iterator it; |
| 307 for (it = helpers.begin(); it != helpers.end(); ++it) | 376 for (it = helpers.begin(); it != helpers.end(); ++it) |
| 308 gesture_recognizer->AddGestureEventHelper(*it); | 377 gesture_recognizer->AddGestureEventHelper(*it); |
| 309 | 378 |
| 310 helpers.clear(); | 379 helpers.clear(); |
| 311 g_gesture_recognizer_instance = | 380 g_gesture_recognizer_instance = |
| 312 static_cast<GestureRecognizerImpl*>(gesture_recognizer); | 381 static_cast<GestureRecognizerImpl*>(gesture_recognizer); |
| 313 } | 382 } |
| 314 | 383 |
| 315 } // namespace ui | 384 } // namespace ui |
| OLD | NEW |