Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "content/browser/renderer_host/render_widget_host_input_event_router.h" | 5 #include "content/browser/renderer_host/render_widget_host_input_event_router.h" |
| 6 | 6 |
| 7 #include "base/debug/dump_without_crashing.h" | 7 #include "base/debug/dump_without_crashing.h" |
| 8 #include "cc/quads/surface_draw_quad.h" | 8 #include "cc/quads/surface_draw_quad.h" |
| 9 #include "cc/surfaces/surface_id_allocator.h" | 9 #include "cc/surfaces/surface_id_allocator.h" |
| 10 #include "cc/surfaces/surface_manager.h" | 10 #include "cc/surfaces/surface_manager.h" |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 // Remove this view from the owner_map. | 33 // Remove this view from the owner_map. |
| 34 for (auto entry : owner_map_) { | 34 for (auto entry : owner_map_) { |
| 35 if (entry.second == view) { | 35 if (entry.second == view) { |
| 36 owner_map_.erase(entry.first); | 36 owner_map_.erase(entry.first); |
| 37 // There will only be one instance of a particular view in the map. | 37 // There will only be one instance of a particular view in the map. |
| 38 break; | 38 break; |
| 39 } | 39 } |
| 40 } | 40 } |
| 41 | 41 |
| 42 if (view == touch_target_) { | 42 if (view == touch_target_.target) { |
|
tdresser
2016/06/09 12:42:24
I was envisioning getting a pointer to the appropr
| |
| 43 touch_target_ = nullptr; | 43 touch_target_.target = nullptr; |
| 44 touch_delta_ = gfx::Vector2d(); | |
| 45 active_touches_ = 0; | 44 active_touches_ = 0; |
| 46 } | 45 } |
| 47 | 46 |
| 48 // If the target that's being destroyed is in the gesture target queue, we | 47 // If the target that's being destroyed is in the gesture target queue, we |
| 49 // replace it with nullptr so that we maintain the 1:1 correspondence between | 48 // replace it with nullptr so that we maintain the 1:1 correspondence between |
| 50 // queue entries and the touch sequences that underly them. | 49 // queue entries and the touch sequences that underly them. |
| 51 for (size_t i = 0; i < gesture_target_queue_.size(); ++i) { | 50 for (size_t i = 0; i < touchscreen_gesture_target_queue_.size(); ++i) { |
| 52 if (gesture_target_queue_[i].target == view) | 51 if (touchscreen_gesture_target_queue_[i].target == view) |
| 53 gesture_target_queue_[i].target = nullptr; | 52 touchscreen_gesture_target_queue_[i].target = nullptr; |
| 54 } | 53 } |
| 55 | 54 |
| 56 if (view == gesture_target_) { | 55 if (view == touchscreen_gesture_target_.target) |
| 57 gesture_target_ = nullptr; | 56 touchscreen_gesture_target_.target = nullptr; |
| 58 gesture_delta_ = gfx::Vector2d(); | 57 |
| 59 } | 58 if (view == touchpad_gesture_target_.target) |
| 59 touchpad_gesture_target_.target = nullptr; | |
| 60 } | 60 } |
| 61 | 61 |
| 62 void RenderWidgetHostInputEventRouter::ClearAllObserverRegistrations() { | 62 void RenderWidgetHostInputEventRouter::ClearAllObserverRegistrations() { |
| 63 for (auto entry : owner_map_) | 63 for (auto entry : owner_map_) |
| 64 entry.second->RemoveObserver(this); | 64 entry.second->RemoveObserver(this); |
| 65 owner_map_.clear(); | 65 owner_map_.clear(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate( | 68 RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate( |
| 69 const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>& | 69 const std::unordered_map<cc::SurfaceId, HittestData, cc::SurfaceIdHash>& |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 82 bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget( | 82 bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget( |
| 83 const cc::SurfaceDrawQuad* surface_quad, | 83 const cc::SurfaceDrawQuad* surface_quad, |
| 84 const gfx::Point& point_in_quad_space) { | 84 const gfx::Point& point_in_quad_space) { |
| 85 auto it = hittest_data_.find(surface_quad->surface_id); | 85 auto it = hittest_data_.find(surface_quad->surface_id); |
| 86 if (it != hittest_data_.end() && !it->second.ignored_for_hittest) | 86 if (it != hittest_data_.end() && !it->second.ignored_for_hittest) |
| 87 return true; | 87 return true; |
| 88 return false; | 88 return false; |
| 89 } | 89 } |
| 90 | 90 |
| 91 RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter() | 91 RenderWidgetHostInputEventRouter::RenderWidgetHostInputEventRouter() |
| 92 : touch_target_(nullptr), | 92 : active_touches_(0) {} |
| 93 gesture_target_(nullptr), | |
| 94 active_touches_(0) {} | |
| 95 | 93 |
| 96 RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() { | 94 RenderWidgetHostInputEventRouter::~RenderWidgetHostInputEventRouter() { |
| 97 // We may be destroyed before some of the owners in the map, so we must | 95 // We may be destroyed before some of the owners in the map, so we must |
| 98 // remove ourself from their observer lists. | 96 // remove ourself from their observer lists. |
| 99 ClearAllObserverRegistrations(); | 97 ClearAllObserverRegistrations(); |
| 100 } | 98 } |
| 101 | 99 |
| 102 RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget( | 100 RenderWidgetHostViewBase* RenderWidgetHostInputEventRouter::FindEventTarget( |
| 103 RenderWidgetHostViewBase* root_view, | 101 RenderWidgetHostViewBase* root_view, |
| 104 const gfx::Point& point, | 102 const gfx::Point& point, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 158 event->x = transformed_point.x(); | 156 event->x = transformed_point.x(); |
| 159 event->y = transformed_point.y(); | 157 event->y = transformed_point.y(); |
| 160 | 158 |
| 161 target->ProcessMouseWheelEvent(*event); | 159 target->ProcessMouseWheelEvent(*event); |
| 162 } | 160 } |
| 163 | 161 |
| 164 void RenderWidgetHostInputEventRouter::RouteGestureEvent( | 162 void RenderWidgetHostInputEventRouter::RouteGestureEvent( |
| 165 RenderWidgetHostViewBase* root_view, | 163 RenderWidgetHostViewBase* root_view, |
| 166 blink::WebGestureEvent* event, | 164 blink::WebGestureEvent* event, |
| 167 const ui::LatencyInfo& latency) { | 165 const ui::LatencyInfo& latency) { |
| 168 // We use GestureTapDown to detect the start of a gesture sequence since there | 166 switch (event->sourceDevice) { |
| 169 // is no WebGestureEvent equivalent for ET_GESTURE_BEGIN. Note that this | 167 case blink::WebGestureDeviceUninitialized: |
| 170 // means the GestureFlingCancel that always comes between ET_GESTURE_BEGIN and | 168 NOTREACHED() << "Uninitialized device type is not allowed"; |
| 171 // GestureTapDown is sent to the previous target, in case it is still in a | 169 break; |
| 172 // fling. | 170 case blink::WebGestureDeviceTouchpad: |
| 173 if (event->type == blink::WebInputEvent::GestureTapDown) { | 171 RouteTouchpadGestureEvent(root_view, event, latency); |
| 174 if (gesture_target_queue_.empty()) { | 172 break; |
| 175 LOG(ERROR) << "Gesture sequence start detected with no target available."; | 173 case blink::WebGestureDeviceTouchscreen: |
| 176 // Ignore this gesture sequence as no target is available. | 174 RouteTouchscreenGestureEvent(root_view, event, latency); |
| 177 // TODO(wjmaclean): this only happens on Windows, and should not happen. | 175 break; |
| 178 // https://crbug.com/595422 | 176 }; |
| 179 gesture_target_ = nullptr; | |
| 180 base::debug::DumpWithoutCrashing(); | |
| 181 return; | |
| 182 } | |
| 183 | |
| 184 const GestureTargetData& data = gesture_target_queue_.front(); | |
| 185 gesture_target_ = data.target; | |
| 186 gesture_delta_ = data.delta; | |
| 187 gesture_target_queue_.pop_front(); | |
| 188 } | |
| 189 | |
| 190 if (!gesture_target_) | |
| 191 return; | |
| 192 | |
| 193 event->x += gesture_delta_.x(); | |
| 194 event->y += gesture_delta_.y(); | |
| 195 gesture_target_->ProcessGestureEvent(*event, latency); | |
| 196 } | 177 } |
| 197 | 178 |
| 198 void RenderWidgetHostInputEventRouter::RouteTouchEvent( | 179 void RenderWidgetHostInputEventRouter::RouteTouchEvent( |
| 199 RenderWidgetHostViewBase* root_view, | 180 RenderWidgetHostViewBase* root_view, |
| 200 blink::WebTouchEvent* event, | 181 blink::WebTouchEvent* event, |
| 201 const ui::LatencyInfo& latency) { | 182 const ui::LatencyInfo& latency) { |
| 202 switch (event->type) { | 183 switch (event->type) { |
| 203 case blink::WebInputEvent::TouchStart: { | 184 case blink::WebInputEvent::TouchStart: { |
| 204 if (!active_touches_) { | 185 if (!active_touches_) { |
| 205 // Since this is the first touch, it defines the target for the rest | 186 // Since this is the first touch, it defines the target for the rest |
| 206 // of this sequence. | 187 // of this sequence. |
| 207 DCHECK(!touch_target_); | 188 DCHECK(!touch_target_.target); |
| 208 gfx::Point transformed_point; | 189 gfx::Point transformed_point; |
| 209 gfx::Point original_point(event->touches[0].position.x, | 190 gfx::Point original_point(event->touches[0].position.x, |
| 210 event->touches[0].position.y); | 191 event->touches[0].position.y); |
| 211 touch_target_ = | 192 touch_target_.target = |
| 212 FindEventTarget(root_view, original_point, &transformed_point); | 193 FindEventTarget(root_view, original_point, &transformed_point); |
| 213 | 194 |
| 214 // TODO(wjmaclean): Instead of just computing a delta, we should extract | 195 // TODO(wjmaclean): Instead of just computing a delta, we should extract |
| 215 // the complete transform. We assume it doesn't change for the duration | 196 // the complete transform. We assume it doesn't change for the duration |
| 216 // of the touch sequence, though this could be wrong; a better approach | 197 // of the touch sequence, though this could be wrong; a better approach |
| 217 // might be to always transform each point to the touch_target_ | 198 // might be to always transform each point to the |touch_target_.target| |
| 218 // for the duration of the sequence. | 199 // for the duration of the sequence. |
| 219 touch_delta_ = transformed_point - original_point; | 200 touch_target_.delta = transformed_point - original_point; |
| 220 gesture_target_queue_.emplace_back(touch_target_, touch_delta_); | 201 touchscreen_gesture_target_queue_.push_back(touch_target_); |
| 221 | 202 |
| 222 if (!touch_target_) | 203 if (!touch_target_.target) |
| 223 return; | 204 return; |
| 224 } | 205 } |
| 225 ++active_touches_; | 206 ++active_touches_; |
| 226 if (touch_target_) { | 207 if (touch_target_.target) { |
| 227 TransformEventTouchPositions(event, touch_delta_); | 208 TransformEventTouchPositions(event, touch_target_.delta); |
| 228 touch_target_->ProcessTouchEvent(*event, latency); | 209 touch_target_.target->ProcessTouchEvent(*event, latency); |
| 229 } | 210 } |
| 230 break; | 211 break; |
| 231 } | 212 } |
| 232 case blink::WebInputEvent::TouchMove: | 213 case blink::WebInputEvent::TouchMove: |
| 233 if (touch_target_) { | 214 if (touch_target_.target) { |
| 234 TransformEventTouchPositions(event, touch_delta_); | 215 TransformEventTouchPositions(event, touch_target_.delta); |
| 235 touch_target_->ProcessTouchEvent(*event, latency); | 216 touch_target_.target->ProcessTouchEvent(*event, latency); |
| 236 } | 217 } |
| 237 break; | 218 break; |
| 238 case blink::WebInputEvent::TouchEnd: | 219 case blink::WebInputEvent::TouchEnd: |
| 239 case blink::WebInputEvent::TouchCancel: | 220 case blink::WebInputEvent::TouchCancel: |
| 240 if (!touch_target_) | 221 if (!touch_target_.target) |
| 241 break; | 222 break; |
| 242 | 223 |
| 243 DCHECK(active_touches_); | 224 DCHECK(active_touches_); |
| 244 TransformEventTouchPositions(event, touch_delta_); | 225 TransformEventTouchPositions(event, touch_target_.delta); |
| 245 touch_target_->ProcessTouchEvent(*event, latency); | 226 touch_target_.target->ProcessTouchEvent(*event, latency); |
| 246 --active_touches_; | 227 --active_touches_; |
| 247 if (!active_touches_) { | 228 if (!active_touches_) |
| 248 touch_target_ = nullptr; | 229 touch_target_.target = nullptr; |
| 249 touch_delta_ = gfx::Vector2d(); | |
| 250 } | |
| 251 break; | 230 break; |
| 252 default: | 231 default: |
| 253 NOTREACHED(); | 232 NOTREACHED(); |
| 254 } | 233 } |
| 255 } | 234 } |
| 256 | 235 |
| 257 void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner( | 236 void RenderWidgetHostInputEventRouter::AddSurfaceIdNamespaceOwner( |
| 258 uint32_t id, | 237 uint32_t id, |
| 259 RenderWidgetHostViewBase* owner) { | 238 RenderWidgetHostViewBase* owner) { |
| 260 DCHECK(owner_map_.find(id) == owner_map_.end()); | 239 DCHECK(owner_map_.find(id) == owner_map_.end()); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 283 void RenderWidgetHostInputEventRouter::OnHittestData( | 262 void RenderWidgetHostInputEventRouter::OnHittestData( |
| 284 const FrameHostMsg_HittestData_Params& params) { | 263 const FrameHostMsg_HittestData_Params& params) { |
| 285 if (owner_map_.find(params.surface_id.id_namespace()) == owner_map_.end()) { | 264 if (owner_map_.find(params.surface_id.id_namespace()) == owner_map_.end()) { |
| 286 return; | 265 return; |
| 287 } | 266 } |
| 288 HittestData data; | 267 HittestData data; |
| 289 data.ignored_for_hittest = params.ignored_for_hittest; | 268 data.ignored_for_hittest = params.ignored_for_hittest; |
| 290 hittest_data_[params.surface_id] = data; | 269 hittest_data_[params.surface_id] = data; |
| 291 } | 270 } |
| 292 | 271 |
| 272 void RenderWidgetHostInputEventRouter::RouteTouchscreenGestureEvent( | |
| 273 RenderWidgetHostViewBase* root_view, | |
| 274 blink::WebGestureEvent* event, | |
| 275 const ui::LatencyInfo& latency) { | |
| 276 DCHECK_EQ(blink::WebGestureDeviceTouchscreen, event->sourceDevice); | |
| 277 | |
| 278 // We use GestureTapDown to detect the start of a gesture sequence since there | |
| 279 // is no WebGestureEvent equivalent for ET_GESTURE_BEGIN. Note that this | |
| 280 // means the GestureFlingCancel that always comes between ET_GESTURE_BEGIN and | |
| 281 // GestureTapDown is sent to the previous target, in case it is still in a | |
| 282 // fling. | |
| 283 if (event->type == blink::WebInputEvent::GestureTapDown) { | |
| 284 if (touchscreen_gesture_target_queue_.empty()) { | |
| 285 LOG(ERROR) << "Gesture sequence start detected with no target available."; | |
| 286 // Ignore this gesture sequence as no target is available. | |
| 287 // TODO(wjmaclean): this only happens on Windows, and should not happen. | |
| 288 // https://crbug.com/595422 | |
| 289 touchscreen_gesture_target_.target = nullptr; | |
| 290 base::debug::DumpWithoutCrashing(); | |
| 291 return; | |
| 292 } | |
| 293 | |
| 294 touchscreen_gesture_target_ = touchscreen_gesture_target_queue_.front(); | |
| 295 touchscreen_gesture_target_queue_.pop_front(); | |
| 296 } | |
| 297 | |
| 298 if (!touchscreen_gesture_target_.target) | |
| 299 return; | |
| 300 | |
| 301 event->x += touchscreen_gesture_target_.delta.x(); | |
| 302 event->y += touchscreen_gesture_target_.delta.y(); | |
| 303 touchscreen_gesture_target_.target->ProcessGestureEvent(*event, latency); | |
| 304 } | |
| 305 | |
| 306 void RenderWidgetHostInputEventRouter::RouteTouchpadGestureEvent( | |
| 307 RenderWidgetHostViewBase* root_view, | |
| 308 blink::WebGestureEvent* event, | |
| 309 const ui::LatencyInfo& latency) { | |
| 310 DCHECK_EQ(blink::WebGestureDeviceTouchpad, event->sourceDevice); | |
| 311 DCHECK(event->type == blink::WebInputEvent::GesturePinchBegin || | |
| 312 event->type == blink::WebInputEvent::GesturePinchUpdate || | |
| 313 event->type == blink::WebInputEvent::GesturePinchEnd); | |
| 314 | |
| 315 if (event->type == blink::WebInputEvent::GesturePinchBegin) { | |
| 316 gfx::Point transformed_point; | |
| 317 gfx::Point original_point(event->x, event->y); | |
| 318 touchpad_gesture_target_.target = | |
| 319 FindEventTarget(root_view, original_point, &transformed_point); | |
| 320 // TODO(mohsen): Instead of just computing a delta, we should extract the | |
| 321 // complete transform. We assume it doesn't change for the duration of the | |
| 322 // touchpad gesture sequence, though this could be wrong; a better approach | |
| 323 // might be to always transform each point to the | |
| 324 // |touchpad_gesture_target_.target| for the duration of the sequence. | |
| 325 touchpad_gesture_target_.delta = transformed_point - original_point; | |
| 326 } | |
| 327 | |
| 328 if (!touchpad_gesture_target_.target) | |
| 329 return; | |
| 330 | |
| 331 event->x += touchpad_gesture_target_.delta.x(); | |
| 332 event->y += touchpad_gesture_target_.delta.y(); | |
| 333 touchpad_gesture_target_.target->ProcessGestureEvent(*event, latency); | |
| 334 } | |
| 335 | |
| 293 } // namespace content | 336 } // namespace content |
| OLD | NEW |