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

Side by Side Diff: content/browser/renderer_host/render_widget_host_input_event_router.cc

Issue 2034213002: Reland: Fix touchpad gesture routing to renderers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed review comments Created 4 years, 6 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 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
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
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
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
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
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_input_event_router.h ('k') | content/browser/site_per_process_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698