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

Side by Side Diff: content/browser/renderer_host/input/touch_emulator.cc

Issue 820053002: Touch emulator: create/destroy gesture provider on the fly. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 12 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/input/touch_emulator.h" 5 #include "content/browser/renderer_host/input/touch_emulator.h"
6 6
7 #include "content/browser/renderer_host/input/motion_event_web.h" 7 #include "content/browser/renderer_host/input/motion_event_web.h"
8 #include "content/browser/renderer_host/input/web_input_event_util.h" 8 #include "content/browser/renderer_host/input/web_input_event_util.h"
9 #include "content/common/input/web_touch_event_traits.h" 9 #include "content/common/input/web_touch_event_traits.h"
10 #include "content/grit/content_resources.h" 10 #include "content/grit/content_resources.h"
(...skipping 28 matching lines...) Expand all
39 } 39 }
40 40
41 // Time between two consecutive mouse moves, during which second mouse move 41 // Time between two consecutive mouse moves, during which second mouse move
42 // is not converted to touch. 42 // is not converted to touch.
43 const double kMouseMoveDropIntervalSeconds = 5.f / 1000; 43 const double kMouseMoveDropIntervalSeconds = 5.f / 1000;
44 44
45 } // namespace 45 } // namespace
46 46
47 TouchEmulator::TouchEmulator(TouchEmulatorClient* client) 47 TouchEmulator::TouchEmulator(TouchEmulatorClient* client)
48 : client_(client), 48 : client_(client),
49 gesture_provider_(GetGestureProviderConfig(), this),
50 enabled_(false),
51 emulated_stream_active_sequence_count_(0), 49 emulated_stream_active_sequence_count_(0),
52 native_stream_active_sequence_count_(0) { 50 native_stream_active_sequence_count_(0) {
53 DCHECK(client_); 51 DCHECK(client_);
54 ResetState(); 52 ResetState();
55 53
56 bool use_2x = gfx::Screen::GetNativeScreen()-> 54 bool use_2x = gfx::Screen::GetNativeScreen()->
57 GetPrimaryDisplay().device_scale_factor() > 1.5f; 55 GetPrimaryDisplay().device_scale_factor() > 1.5f;
58 float cursor_scale_factor = use_2x ? 2.f : 1.f; 56 float cursor_scale_factor = use_2x ? 2.f : 1.f;
59 cursor_size_ = InitCursorFromResource(&touch_cursor_, 57 cursor_size_ = InitCursorFromResource(&touch_cursor_,
60 cursor_scale_factor, 58 cursor_scale_factor,
61 use_2x ? IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X : 59 use_2x ? IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X :
62 IDR_DEVTOOLS_TOUCH_CURSOR_ICON); 60 IDR_DEVTOOLS_TOUCH_CURSOR_ICON);
63 InitCursorFromResource(&pinch_cursor_, 61 InitCursorFromResource(&pinch_cursor_,
64 cursor_scale_factor, 62 cursor_scale_factor,
65 use_2x ? IDR_DEVTOOLS_PINCH_CURSOR_ICON_2X : 63 use_2x ? IDR_DEVTOOLS_PINCH_CURSOR_ICON_2X :
66 IDR_DEVTOOLS_PINCH_CURSOR_ICON); 64 IDR_DEVTOOLS_PINCH_CURSOR_ICON);
67 65
68 WebCursor::CursorInfo cursor_info; 66 WebCursor::CursorInfo cursor_info;
69 cursor_info.type = blink::WebCursorInfo::TypePointer; 67 cursor_info.type = blink::WebCursorInfo::TypePointer;
70 pointer_cursor_.InitFromCursorInfo(cursor_info); 68 pointer_cursor_.InitFromCursorInfo(cursor_info);
71
72 // TODO(dgozman): Use synthetic secondary touch to support multi-touch.
73 gesture_provider_.SetMultiTouchZoomSupportEnabled(false);
74 // TODO(dgozman): Enable double tap if requested by the renderer.
75 // TODO(dgozman): Don't break double-tap-based pinch with shift handling.
76 gesture_provider_.SetDoubleTapSupportForPlatformEnabled(false);
77 } 69 }
78 70
79 TouchEmulator::~TouchEmulator() { 71 TouchEmulator::~TouchEmulator() {
80 // We cannot cleanup properly in destructor, as we need roundtrip to the 72 // We cannot cleanup properly in destructor, as we need roundtrip to the
81 // renderer for ack. Instead, the owner should call Disable, and only 73 // renderer for ack. Instead, the owner should call Disable, and only
82 // destroy this object when renderer is dead. 74 // destroy this object when renderer is dead.
83 } 75 }
84 76
85 void TouchEmulator::ResetState() { 77 void TouchEmulator::ResetState() {
86 last_mouse_event_was_move_ = false; 78 last_mouse_event_was_move_ = false;
87 last_mouse_move_timestamp_ = 0; 79 last_mouse_move_timestamp_ = 0;
88 mouse_pressed_ = false; 80 mouse_pressed_ = false;
89 shift_pressed_ = false; 81 shift_pressed_ = false;
90 suppress_next_fling_cancel_ = false; 82 suppress_next_fling_cancel_ = false;
91 pinch_scale_ = 1.f; 83 pinch_scale_ = 1.f;
92 pinch_gesture_active_ = false; 84 pinch_gesture_active_ = false;
93 } 85 }
94 86
95 void TouchEmulator::Enable() { 87 void TouchEmulator::Enable() {
96 if (!enabled_) { 88 if (!gesture_provider_) {
97 enabled_ = true; 89 gesture_provider_.reset(new ui::FilteredGestureProvider(
90 GetGestureProviderConfig(), this));
91 // TODO(dgozman): Use synthetic secondary touch to support multi-touch.
92 gesture_provider_->SetMultiTouchZoomSupportEnabled(false);
93 // TODO(dgozman): Enable double tap if requested by the renderer.
94 // TODO(dgozman): Don't break double-tap-based pinch with shift handling.
95 gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
96
98 ResetState(); 97 ResetState();
99 } 98 }
100 UpdateCursor(); 99 UpdateCursor();
101 } 100 }
102 101
103 void TouchEmulator::Disable() { 102 void TouchEmulator::Disable() {
104 if (!enabled_) 103 if (!gesture_provider_)
jdduke (slow) 2014/12/30 16:37:19 In these early returns, would it make sense to use
dgozman 2015/01/14 14:14:27 Great idea! Done.
105 return; 104 return;
106 105
107 enabled_ = false;
108 UpdateCursor(); 106 UpdateCursor();
109 CancelTouch(); 107 CancelTouch();
108 gesture_provider_.reset();
110 } 109 }
111 110
112 gfx::SizeF TouchEmulator::InitCursorFromResource( 111 gfx::SizeF TouchEmulator::InitCursorFromResource(
113 WebCursor* cursor, float scale, int resource_id) { 112 WebCursor* cursor, float scale, int resource_id) {
114 gfx::Image& cursor_image = 113 gfx::Image& cursor_image =
115 content::GetContentClient()->GetNativeImageNamed(resource_id); 114 content::GetContentClient()->GetNativeImageNamed(resource_id);
116 WebCursor::CursorInfo cursor_info; 115 WebCursor::CursorInfo cursor_info;
117 cursor_info.type = blink::WebCursorInfo::TypeCustom; 116 cursor_info.type = blink::WebCursorInfo::TypeCustom;
118 cursor_info.image_scale_factor = scale; 117 cursor_info.image_scale_factor = scale;
119 cursor_info.custom_image = cursor_image.AsBitmap(); 118 cursor_info.custom_image = cursor_image.AsBitmap();
120 cursor_info.hotspot = 119 cursor_info.hotspot =
121 gfx::Point(cursor_image.Width() / 2, cursor_image.Height() / 2); 120 gfx::Point(cursor_image.Width() / 2, cursor_image.Height() / 2);
122 #if defined(OS_WIN) 121 #if defined(OS_WIN)
123 cursor_info.external_handle = 0; 122 cursor_info.external_handle = 0;
124 #endif 123 #endif
125 124
126 cursor->InitFromCursorInfo(cursor_info); 125 cursor->InitFromCursorInfo(cursor_info);
127 return gfx::ScaleSize(cursor_image.Size(), 1.f / scale); 126 return gfx::ScaleSize(cursor_image.Size(), 1.f / scale);
128 } 127 }
129 128
130 bool TouchEmulator::HandleMouseEvent(const WebMouseEvent& mouse_event) { 129 bool TouchEmulator::HandleMouseEvent(const WebMouseEvent& mouse_event) {
131 if (!enabled_) 130 if (!gesture_provider_)
132 return false; 131 return false;
133 132
134 if (mouse_event.button == WebMouseEvent::ButtonRight && 133 if (mouse_event.button == WebMouseEvent::ButtonRight &&
135 mouse_event.type == WebInputEvent::MouseDown) { 134 mouse_event.type == WebInputEvent::MouseDown) {
136 client_->ShowContextMenuAtPoint(gfx::Point(mouse_event.x, mouse_event.y)); 135 client_->ShowContextMenuAtPoint(gfx::Point(mouse_event.x, mouse_event.y));
137 } 136 }
138 137
139 if (mouse_event.button != WebMouseEvent::ButtonLeft) 138 if (mouse_event.button != WebMouseEvent::ButtonLeft)
140 return true; 139 return true;
141 140
(...skipping 23 matching lines...) Expand all
165 } 164 }
166 165
167 FillTouchEventAndPoint(mouse_event); 166 FillTouchEventAndPoint(mouse_event);
168 HandleEmulatedTouchEvent(touch_event_); 167 HandleEmulatedTouchEvent(touch_event_);
169 168
170 // Do not pass mouse events to the renderer. 169 // Do not pass mouse events to the renderer.
171 return true; 170 return true;
172 } 171 }
173 172
174 bool TouchEmulator::HandleMouseWheelEvent(const WebMouseWheelEvent& event) { 173 bool TouchEmulator::HandleMouseWheelEvent(const WebMouseWheelEvent& event) {
175 if (!enabled_) 174 if (!gesture_provider_)
176 return false; 175 return false;
177 176
178 // Send mouse wheel for easy scrolling when there is no active touch. 177 // Send mouse wheel for easy scrolling when there is no active touch.
179 return emulated_stream_active_sequence_count_ > 0; 178 return emulated_stream_active_sequence_count_ > 0;
180 } 179 }
181 180
182 bool TouchEmulator::HandleKeyboardEvent(const WebKeyboardEvent& event) { 181 bool TouchEmulator::HandleKeyboardEvent(const WebKeyboardEvent& event) {
183 if (!enabled_) 182 if (!gesture_provider_)
184 return false; 183 return false;
185 184
186 if (!UpdateShiftPressed((event.modifiers & WebInputEvent::ShiftKey) != 0)) 185 if (!UpdateShiftPressed((event.modifiers & WebInputEvent::ShiftKey) != 0))
187 return false; 186 return false;
188 187
189 if (!mouse_pressed_) 188 if (!mouse_pressed_)
190 return false; 189 return false;
191 190
192 // Note: The necessary pinch events will be lazily inserted by 191 // Note: The necessary pinch events will be lazily inserted by
193 // |OnGestureEvent| depending on the state of |shift_pressed_|, using the 192 // |OnGestureEvent| depending on the state of |shift_pressed_|, using the
(...skipping 17 matching lines...) Expand all
211 // Do not allow middle-sequence event to pass through, if start was blocked. 210 // Do not allow middle-sequence event to pass through, if start was blocked.
212 if (!native_stream_active_sequence_count_ && !is_sequence_start) 211 if (!native_stream_active_sequence_count_ && !is_sequence_start)
213 return true; 212 return true;
214 213
215 if (is_sequence_start) 214 if (is_sequence_start)
216 native_stream_active_sequence_count_++; 215 native_stream_active_sequence_count_++;
217 return false; 216 return false;
218 } 217 }
219 218
220 void TouchEmulator::HandleEmulatedTouchEvent(blink::WebTouchEvent event) { 219 void TouchEmulator::HandleEmulatedTouchEvent(blink::WebTouchEvent event) {
221 auto result = gesture_provider_.OnTouchEvent(MotionEventWeb(event)); 220 DCHECK(gesture_provider_.get());
jdduke (slow) 2014/12/30 16:37:19 Do you need the ".get()" (also below)?
dgozman 2015/01/14 14:14:27 Removed.
221 auto result = gesture_provider_->OnTouchEvent(MotionEventWeb(event));
222 if (!result.succeeded) 222 if (!result.succeeded)
223 return; 223 return;
224 224
225 const bool event_consumed = true; 225 const bool event_consumed = true;
226 // Block emulated event when emulated native stream is active. 226 // Block emulated event when emulated native stream is active.
227 if (native_stream_active_sequence_count_) { 227 if (native_stream_active_sequence_count_) {
228 gesture_provider_.OnSyncTouchEventAck(event_consumed); 228 gesture_provider_->OnSyncTouchEventAck(event_consumed);
229 return; 229 return;
230 } 230 }
231 231
232 bool is_sequence_start = WebTouchEventTraits::IsTouchSequenceStart(event); 232 bool is_sequence_start = WebTouchEventTraits::IsTouchSequenceStart(event);
233 // Do not allow middle-sequence event to pass through, if start was blocked. 233 // Do not allow middle-sequence event to pass through, if start was blocked.
234 if (!emulated_stream_active_sequence_count_ && !is_sequence_start) { 234 if (!emulated_stream_active_sequence_count_ && !is_sequence_start) {
235 gesture_provider_.OnSyncTouchEventAck(event_consumed); 235 gesture_provider_->OnSyncTouchEventAck(event_consumed);
236 return; 236 return;
237 } 237 }
238 238
239 if (is_sequence_start) 239 if (is_sequence_start)
240 emulated_stream_active_sequence_count_++; 240 emulated_stream_active_sequence_count_++;
241 241
242 event.causesScrollingIfUncanceled = result.did_generate_scroll; 242 event.causesScrollingIfUncanceled = result.did_generate_scroll;
243 client_->ForwardEmulatedTouchEvent(event); 243 client_->ForwardEmulatedTouchEvent(event);
244 } 244 }
245 245
246 bool TouchEmulator::HandleTouchEventAck( 246 bool TouchEmulator::HandleTouchEventAck(
247 const blink::WebTouchEvent& event, InputEventAckState ack_result) { 247 const blink::WebTouchEvent& event, InputEventAckState ack_result) {
248 bool is_sequence_end = WebTouchEventTraits::IsTouchSequenceEnd(event); 248 bool is_sequence_end = WebTouchEventTraits::IsTouchSequenceEnd(event);
249 if (emulated_stream_active_sequence_count_) { 249 if (emulated_stream_active_sequence_count_) {
250 if (is_sequence_end) 250 if (is_sequence_end)
251 emulated_stream_active_sequence_count_--; 251 emulated_stream_active_sequence_count_--;
252 252
253 const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; 253 const bool event_consumed = ack_result == INPUT_EVENT_ACK_STATE_CONSUMED;
254 gesture_provider_.OnAsyncTouchEventAck(event_consumed); 254 if (gesture_provider_)
255 gesture_provider_->OnAsyncTouchEventAck(event_consumed);
255 return true; 256 return true;
256 } 257 }
257 258
258 // We may have not seen native touch sequence start (when created in the 259 // We may have not seen native touch sequence start (when created in the
259 // middle of a sequence), so don't decrement sequence count below zero. 260 // middle of a sequence), so don't decrement sequence count below zero.
260 if (is_sequence_end && native_stream_active_sequence_count_) 261 if (is_sequence_end && native_stream_active_sequence_count_)
261 native_stream_active_sequence_count_--; 262 native_stream_active_sequence_count_--;
262 return false; 263 return false;
263 } 264 }
264 265
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 } 330 }
330 331
331 void TouchEmulator::CancelTouch() { 332 void TouchEmulator::CancelTouch() {
332 if (!emulated_stream_active_sequence_count_) 333 if (!emulated_stream_active_sequence_count_)
333 return; 334 return;
334 335
335 WebTouchEventTraits::ResetTypeAndTouchStates( 336 WebTouchEventTraits::ResetTypeAndTouchStates(
336 WebInputEvent::TouchCancel, 337 WebInputEvent::TouchCancel,
337 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(), 338 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(),
338 &touch_event_); 339 &touch_event_);
339 if (gesture_provider_.GetCurrentDownEvent()) 340 DCHECK(gesture_provider_.get());
341 if (gesture_provider_->GetCurrentDownEvent())
340 HandleEmulatedTouchEvent(touch_event_); 342 HandleEmulatedTouchEvent(touch_event_);
341 } 343 }
342 344
343 void TouchEmulator::UpdateCursor() { 345 void TouchEmulator::UpdateCursor() {
344 if (!enabled_) 346 if (!gesture_provider_)
345 client_->SetCursor(pointer_cursor_); 347 client_->SetCursor(pointer_cursor_);
346 else 348 else
347 client_->SetCursor(InPinchGestureMode() ? pinch_cursor_ : touch_cursor_); 349 client_->SetCursor(InPinchGestureMode() ? pinch_cursor_ : touch_cursor_);
348 } 350 }
349 351
350 bool TouchEmulator::UpdateShiftPressed(bool shift_pressed) { 352 bool TouchEmulator::UpdateShiftPressed(bool shift_pressed) {
351 if (shift_pressed_ == shift_pressed) 353 if (shift_pressed_ == shift_pressed)
352 return false; 354 return false;
353 shift_pressed_ = shift_pressed; 355 shift_pressed_ = shift_pressed;
354 UpdateCursor(); 356 UpdateCursor();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 point.screenPosition.x = mouse_event.globalX; 435 point.screenPosition.x = mouse_event.globalX;
434 point.position.y = mouse_event.y; 436 point.position.y = mouse_event.y;
435 point.screenPosition.y = mouse_event.globalY; 437 point.screenPosition.y = mouse_event.globalY;
436 } 438 }
437 439
438 bool TouchEmulator::InPinchGestureMode() const { 440 bool TouchEmulator::InPinchGestureMode() const {
439 return shift_pressed_; 441 return shift_pressed_;
440 } 442 }
441 443
442 } // namespace content 444 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698