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

Side by Side Diff: ui/events/blink/blink_event_util.cc

Issue 2054193002: Android mouse events shouldn't appear as TouchEvents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed a test, etc. Created 4 years, 1 month 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
« no previous file with comments | « ui/events/blink/blink_event_util.h ('k') | ui/events/gesture_detection/gesture_detector.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // MSVC++ requires this to be set before any other includes to get M_PI. 5 // MSVC++ requires this to be set before any other includes to get M_PI.
6 #define _USE_MATH_DEFINES 6 #define _USE_MATH_DEFINES
7 7
8 #include "ui/events/blink/blink_event_util.h" 8 #include "ui/events/blink/blink_event_util.h"
9 9
10 #include <stddef.h> 10 #include <stddef.h>
(...skipping 15 matching lines...) Expand all
26 26
27 using blink::WebGestureEvent; 27 using blink::WebGestureEvent;
28 using blink::WebInputEvent; 28 using blink::WebInputEvent;
29 using blink::WebPointerProperties; 29 using blink::WebPointerProperties;
30 using blink::WebTouchEvent; 30 using blink::WebTouchEvent;
31 using blink::WebTouchPoint; 31 using blink::WebTouchPoint;
32 32
33 namespace ui { 33 namespace ui {
34 namespace { 34 namespace {
35 35
36 WebInputEvent::Type ToWebInputEventType(MotionEvent::Action action) { 36 WebInputEvent::Type ToWebTouchEventType(MotionEvent::Action action) {
37 switch (action) { 37 switch (action) {
38 case MotionEvent::ACTION_DOWN: 38 case MotionEvent::ACTION_DOWN:
39 return WebInputEvent::TouchStart; 39 return WebInputEvent::TouchStart;
40 case MotionEvent::ACTION_MOVE: 40 case MotionEvent::ACTION_MOVE:
41 return WebInputEvent::TouchMove; 41 return WebInputEvent::TouchMove;
42 case MotionEvent::ACTION_UP: 42 case MotionEvent::ACTION_UP:
43 return WebInputEvent::TouchEnd; 43 return WebInputEvent::TouchEnd;
44 case MotionEvent::ACTION_CANCEL: 44 case MotionEvent::ACTION_CANCEL:
45 return WebInputEvent::TouchCancel; 45 return WebInputEvent::TouchCancel;
46 case MotionEvent::ACTION_POINTER_DOWN: 46 case MotionEvent::ACTION_POINTER_DOWN:
47 return WebInputEvent::TouchStart; 47 return WebInputEvent::TouchStart;
48 case MotionEvent::ACTION_POINTER_UP: 48 case MotionEvent::ACTION_POINTER_UP:
49 return WebInputEvent::TouchEnd; 49 return WebInputEvent::TouchEnd;
50 case MotionEvent::ACTION_NONE: 50 case MotionEvent::ACTION_NONE:
51 NOTREACHED(); 51 case MotionEvent::ACTION_HOVER_ENTER:
52 return WebInputEvent::Undefined; 52 case MotionEvent::ACTION_HOVER_EXIT:
53 case MotionEvent::ACTION_HOVER_MOVE:
54 case MotionEvent::ACTION_BUTTON_PRESS:
55 case MotionEvent::ACTION_BUTTON_RELEASE:
56 break;
53 } 57 }
54 NOTREACHED() << "Invalid MotionEvent::Action."; 58 NOTREACHED() << "Invalid MotionEvent::Action = " << action;
55 return WebInputEvent::Undefined; 59 return WebInputEvent::Undefined;
56 } 60 }
57 61
58 // Note that the action index is meaningful only in the context of 62 // Note that the action index is meaningful only in the context of
59 // |ACTION_POINTER_UP| and |ACTION_POINTER_DOWN|; other actions map directly to 63 // |ACTION_POINTER_UP| and |ACTION_POINTER_DOWN|; other actions map directly to
60 // WebTouchPoint::State. 64 // WebTouchPoint::State.
61 WebTouchPoint::State ToWebTouchPointState(const MotionEvent& event, 65 WebTouchPoint::State ToWebTouchPointState(const MotionEvent& event,
62 size_t pointer_index) { 66 size_t pointer_index) {
63 switch (event.GetAction()) { 67 switch (event.GetAction()) {
64 case MotionEvent::ACTION_DOWN: 68 case MotionEvent::ACTION_DOWN:
65 return WebTouchPoint::StatePressed; 69 return WebTouchPoint::StatePressed;
66 case MotionEvent::ACTION_MOVE: 70 case MotionEvent::ACTION_MOVE:
67 return WebTouchPoint::StateMoved; 71 return WebTouchPoint::StateMoved;
68 case MotionEvent::ACTION_UP: 72 case MotionEvent::ACTION_UP:
69 return WebTouchPoint::StateReleased; 73 return WebTouchPoint::StateReleased;
70 case MotionEvent::ACTION_CANCEL: 74 case MotionEvent::ACTION_CANCEL:
71 return WebTouchPoint::StateCancelled; 75 return WebTouchPoint::StateCancelled;
72 case MotionEvent::ACTION_POINTER_DOWN: 76 case MotionEvent::ACTION_POINTER_DOWN:
73 return static_cast<int>(pointer_index) == event.GetActionIndex() 77 return static_cast<int>(pointer_index) == event.GetActionIndex()
74 ? WebTouchPoint::StatePressed 78 ? WebTouchPoint::StatePressed
75 : WebTouchPoint::StateStationary; 79 : WebTouchPoint::StateStationary;
76 case MotionEvent::ACTION_POINTER_UP: 80 case MotionEvent::ACTION_POINTER_UP:
77 return static_cast<int>(pointer_index) == event.GetActionIndex() 81 return static_cast<int>(pointer_index) == event.GetActionIndex()
78 ? WebTouchPoint::StateReleased 82 ? WebTouchPoint::StateReleased
79 : WebTouchPoint::StateStationary; 83 : WebTouchPoint::StateStationary;
80 case MotionEvent::ACTION_NONE: 84 case MotionEvent::ACTION_NONE:
81 NOTREACHED(); 85 case MotionEvent::ACTION_HOVER_ENTER:
82 return WebTouchPoint::StateUndefined; 86 case MotionEvent::ACTION_HOVER_EXIT:
87 case MotionEvent::ACTION_HOVER_MOVE:
88 case MotionEvent::ACTION_BUTTON_PRESS:
89 case MotionEvent::ACTION_BUTTON_RELEASE:
90 break;
83 } 91 }
84 NOTREACHED() << "Invalid MotionEvent::Action."; 92 NOTREACHED() << "Invalid MotionEvent::Action.";
85 return WebTouchPoint::StateUndefined; 93 return WebTouchPoint::StateUndefined;
86 } 94 }
87 95
96 WebPointerProperties::PointerType ToWebPointerType(int tool_type) {
97 switch (static_cast<MotionEvent::ToolType>(tool_type)) {
98 case MotionEvent::TOOL_TYPE_UNKNOWN:
99 return WebPointerProperties::PointerType::Unknown;
100 case MotionEvent::TOOL_TYPE_FINGER:
101 return WebPointerProperties::PointerType::Touch;
102 case MotionEvent::TOOL_TYPE_STYLUS:
103 return WebPointerProperties::PointerType::Pen;
104 case MotionEvent::TOOL_TYPE_MOUSE:
105 return WebPointerProperties::PointerType::Mouse;
106 case MotionEvent::TOOL_TYPE_ERASER:
107 return WebPointerProperties::PointerType::Eraser;
108 }
109 NOTREACHED() << "Invalid MotionEvent::ToolType = " << tool_type;
110 return WebPointerProperties::PointerType::Unknown;
111 }
112
113 WebPointerProperties::Button ToWebPointerButton(int android_button_state) {
114 if (android_button_state & MotionEvent::BUTTON_PRIMARY)
115 return WebPointerProperties::Button::Left;
116 else if (android_button_state & MotionEvent::BUTTON_SECONDARY)
117 return WebPointerProperties::Button::Right;
118 else if (android_button_state & MotionEvent::BUTTON_TERTIARY)
119 return WebPointerProperties::Button::Middle;
120 else if (android_button_state & MotionEvent::BUTTON_BACK)
121 return WebPointerProperties::Button::X1;
122 else if (android_button_state & MotionEvent::BUTTON_FORWARD)
123 return WebPointerProperties::Button::X2;
124 else if (android_button_state & MotionEvent::BUTTON_STYLUS_PRIMARY)
125 return WebPointerProperties::Button::Left;
126 else if (android_button_state & MotionEvent::BUTTON_STYLUS_SECONDARY)
127 return WebPointerProperties::Button::Right;
128 else
129 return WebPointerProperties::Button::NoButton;
130 }
131
88 WebTouchPoint CreateWebTouchPoint(const MotionEvent& event, 132 WebTouchPoint CreateWebTouchPoint(const MotionEvent& event,
89 size_t pointer_index) { 133 size_t pointer_index) {
90 WebTouchPoint touch; 134 WebTouchPoint touch;
91 touch.id = event.GetPointerId(pointer_index); 135
92 touch.pointerType = ToWebPointerType(event.GetToolType(pointer_index)); 136 SetWebPointerPropertiesFromMotionEventData(
137 touch, event.GetPointerId(pointer_index),
138 event.GetPressure(pointer_index), event.GetOrientation(pointer_index),
139 event.GetTilt(pointer_index), 0 /* no button changed */,
140 event.GetToolType(pointer_index));
141
93 touch.state = ToWebTouchPointState(event, pointer_index); 142 touch.state = ToWebTouchPointState(event, pointer_index);
94 touch.position.x = event.GetX(pointer_index); 143 touch.position.x = event.GetX(pointer_index);
95 touch.position.y = event.GetY(pointer_index); 144 touch.position.y = event.GetY(pointer_index);
96 touch.screenPosition.x = event.GetRawX(pointer_index); 145 touch.screenPosition.x = event.GetRawX(pointer_index);
97 touch.screenPosition.y = event.GetRawY(pointer_index); 146 touch.screenPosition.y = event.GetRawY(pointer_index);
98 147
99 // A note on touch ellipse specifications: 148 // A note on touch ellipse specifications:
100 // 149 //
101 // Android MotionEvent provides the major and minor axes of the touch ellipse, 150 // Android MotionEvent provides the major and minor axes of the touch ellipse,
102 // as well as the orientation of the major axis clockwise from vertical, in 151 // as well as the orientation of the major axis clockwise from vertical, in
103 // radians. See: 152 // radians. See:
104 // http://developer.android.com/reference/android/view/MotionEvent.html 153 // http://developer.android.com/reference/android/view/MotionEvent.html
105 // 154 //
106 // The proposed extension to W3C Touch Events specifies the touch ellipse 155 // The proposed extension to W3C Touch Events specifies the touch ellipse
107 // using two radii along x- & y-axes and a positive acute rotation angle in 156 // using two radii along x- & y-axes and a positive acute rotation angle in
108 // degrees. See: 157 // degrees. See:
109 // http://dvcs.w3.org/hg/webevents/raw-file/default/touchevents.html 158 // http://dvcs.w3.org/hg/webevents/raw-file/default/touchevents.html
110 159
111 float major_radius = event.GetTouchMajor(pointer_index) / 2.f; 160 float major_radius = event.GetTouchMajor(pointer_index) / 2.f;
112 float minor_radius = event.GetTouchMinor(pointer_index) / 2.f; 161 float minor_radius = event.GetTouchMinor(pointer_index) / 2.f;
162 float orientation_deg = event.GetOrientation(pointer_index) * 180.f / M_PI;
113 163
114 float orientation_rad = event.GetOrientation(pointer_index);
115 float orientation_deg = orientation_rad * 180.f / M_PI;
116 DCHECK_GE(major_radius, 0); 164 DCHECK_GE(major_radius, 0);
117 DCHECK_GE(minor_radius, 0); 165 DCHECK_GE(minor_radius, 0);
118 DCHECK_GE(major_radius, minor_radius); 166 DCHECK_GE(major_radius, minor_radius);
119 // Orientation lies in [-180, 180] for a stylus, and [-90, 90] for other 167 // Orientation lies in [-180, 180] for a stylus, and [-90, 90] for other
120 // touchscreen inputs. There are exceptions on Android when a device is 168 // touchscreen inputs. There are exceptions on Android when a device is
121 // rotated, yielding touch orientations in the range of [-180, 180]. 169 // rotated, yielding touch orientations in the range of [-180, 180].
122 // Regardless, normalise to [-90, 90), allowing a small tolerance to account 170 // Regardless, normalise to [-90, 90), allowing a small tolerance to account
123 // for floating point conversion. 171 // for floating point conversion.
124 // TODO(e_hakkinen): Also pass unaltered stylus orientation, avoiding loss of 172 // TODO(e_hakkinen): Also pass unaltered stylus orientation, avoiding loss of
125 // quadrant information, see crbug.com/493728. 173 // quadrant information, see crbug.com/493728.
(...skipping 10 matching lines...) Expand all
136 // report elliptical touches). 184 // report elliptical touches).
137 touch.radiusX = minor_radius; 185 touch.radiusX = minor_radius;
138 touch.radiusY = major_radius; 186 touch.radiusY = major_radius;
139 touch.rotationAngle = orientation_deg; 187 touch.rotationAngle = orientation_deg;
140 } else { 188 } else {
141 touch.radiusX = major_radius; 189 touch.radiusX = major_radius;
142 touch.radiusY = minor_radius; 190 touch.radiusY = minor_radius;
143 touch.rotationAngle = orientation_deg + 90; 191 touch.rotationAngle = orientation_deg + 90;
144 } 192 }
145 193
146 touch.force = event.GetPressure(pointer_index);
147
148 if (event.GetToolType(pointer_index) == MotionEvent::TOOL_TYPE_STYLUS) {
149 // A stylus points to a direction specified by orientation and tilts to
150 // the opposite direction. Coordinate system is left-handed.
151 float tilt_rad = event.GetTilt(pointer_index);
152 float r = sin(tilt_rad);
153 float z = cos(tilt_rad);
154 touch.tiltX = lround(atan2(sin(-orientation_rad) * r, z) * 180.f / M_PI);
155 touch.tiltY = lround(atan2(cos(-orientation_rad) * r, z) * 180.f / M_PI);
156 } else {
157 touch.tiltX = touch.tiltY = 0;
158 }
159
160 return touch; 194 return touch;
161 } 195 }
162 196
163 } // namespace 197 } // namespace
164 198
165 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent( 199 blink::WebTouchEvent CreateWebTouchEventFromMotionEvent(
166 const MotionEvent& event, 200 const MotionEvent& event,
167 bool moved_beyond_slop_region) { 201 bool moved_beyond_slop_region) {
168 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) == 202 static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) ==
169 static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap), 203 static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap),
170 "inconsistent maximum number of active touch points"); 204 "inconsistent maximum number of active touch points");
171 205
172 blink::WebTouchEvent result; 206 blink::WebTouchEvent result;
173 207
174 result.type = ToWebInputEventType(event.GetAction()); 208 result.type = ToWebTouchEventType(event.GetAction());
175 result.dispatchType = result.type == WebInputEvent::TouchCancel 209 result.dispatchType = result.type == WebInputEvent::TouchCancel
176 ? WebInputEvent::EventNonBlocking 210 ? WebInputEvent::EventNonBlocking
177 : WebInputEvent::Blocking; 211 : WebInputEvent::Blocking;
178 result.timeStampSeconds = ui::EventTimeStampToSeconds(event.GetEventTime()); 212 result.timeStampSeconds = ui::EventTimeStampToSeconds(event.GetEventTime());
179 result.movedBeyondSlopRegion = moved_beyond_slop_region; 213 result.movedBeyondSlopRegion = moved_beyond_slop_region;
214
180 result.modifiers = EventFlagsToWebEventModifiers(event.GetFlags()); 215 result.modifiers = EventFlagsToWebEventModifiers(event.GetFlags());
216 // TODO(mustaq): MotionEvent flags seems unrelated, should use
217 // metaState instead?
218
181 DCHECK_NE(event.GetUniqueEventId(), 0U); 219 DCHECK_NE(event.GetUniqueEventId(), 0U);
182 result.uniqueTouchEventId = event.GetUniqueEventId(); 220 result.uniqueTouchEventId = event.GetUniqueEventId();
183 result.touchesLength = 221 result.touchesLength =
184 std::min(static_cast<unsigned>(event.GetPointerCount()), 222 std::min(static_cast<unsigned>(event.GetPointerCount()),
185 static_cast<unsigned>(WebTouchEvent::kTouchesLengthCap)); 223 static_cast<unsigned>(WebTouchEvent::kTouchesLengthCap));
186 DCHECK_GT(result.touchesLength, 0U); 224 DCHECK_GT(result.touchesLength, 0U);
187 225
188 for (size_t i = 0; i < result.touchesLength; ++i) 226 for (size_t i = 0; i < result.touchesLength; ++i)
189 result.touches[i] = CreateWebTouchPoint(event, i); 227 result.touches[i] = CreateWebTouchPoint(event, i);
190 228
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 break; 511 break;
474 512
475 // TODO(oshima): Find out if ContextMenu needs to be scaled. 513 // TODO(oshima): Find out if ContextMenu needs to be scaled.
476 default: 514 default:
477 break; 515 break;
478 } 516 }
479 } 517 }
480 return scaled_event; 518 return scaled_event;
481 } 519 }
482 520
483 WebPointerProperties::PointerType ToWebPointerType( 521 WebInputEvent::Type ToWebMouseEventType(MotionEvent::Action action) {
484 MotionEvent::ToolType tool_type) { 522 switch (action) {
485 switch (tool_type) { 523 case MotionEvent::ACTION_DOWN:
486 case MotionEvent::TOOL_TYPE_UNKNOWN: 524 case MotionEvent::ACTION_BUTTON_PRESS:
487 return WebPointerProperties::PointerType::Unknown; 525 return WebInputEvent::MouseDown;
488 case MotionEvent::TOOL_TYPE_FINGER: 526 case MotionEvent::ACTION_MOVE:
489 return WebPointerProperties::PointerType::Touch; 527 case MotionEvent::ACTION_HOVER_MOVE:
490 case MotionEvent::TOOL_TYPE_STYLUS: 528 return WebInputEvent::MouseMove;
491 return WebPointerProperties::PointerType::Pen; 529 case MotionEvent::ACTION_HOVER_ENTER:
492 case MotionEvent::TOOL_TYPE_MOUSE: 530 return WebInputEvent::MouseEnter;
493 return WebPointerProperties::PointerType::Mouse; 531 case MotionEvent::ACTION_HOVER_EXIT:
494 case MotionEvent::TOOL_TYPE_ERASER: 532 return WebInputEvent::MouseLeave;
495 return WebPointerProperties::PointerType::Eraser; 533 case MotionEvent::ACTION_UP:
534 case MotionEvent::ACTION_BUTTON_RELEASE:
535 return WebInputEvent::MouseUp;
536 case MotionEvent::ACTION_NONE:
537 case MotionEvent::ACTION_CANCEL:
538 case MotionEvent::ACTION_POINTER_DOWN:
539 case MotionEvent::ACTION_POINTER_UP:
540 break;
496 } 541 }
497 NOTREACHED() << "Invalid MotionEvent::ToolType = " << tool_type; 542 NOTREACHED() << "Invalid MotionEvent::Action = " << action;
498 return WebPointerProperties::PointerType::Unknown; 543 return WebInputEvent::Undefined;
544 }
545
546 void SetWebPointerPropertiesFromMotionEventData(
547 WebPointerProperties& webPointerProperties,
548 int pointer_id,
549 float pressure,
550 float orientation_rad,
551 float tilt_rad,
552 int android_buttons_changed,
553 int tool_type) {
554
555 webPointerProperties.id = pointer_id;
556 webPointerProperties.force = pressure;
557
558 if (tool_type == MotionEvent::TOOL_TYPE_STYLUS) {
559 // A stylus points to a direction specified by orientation and tilts to
560 // the opposite direction. Coordinate system is left-handed.
561 float r = sin(tilt_rad);
562 float z = cos(tilt_rad);
563 webPointerProperties.tiltX =
564 lround(atan2(sin(-orientation_rad) * r, z) * 180.f / M_PI);
565 webPointerProperties.tiltY =
566 lround(atan2(cos(-orientation_rad) * r, z) * 180.f / M_PI);
567 } else {
568 webPointerProperties.tiltX = webPointerProperties.tiltY = 0;
569 }
570
571 webPointerProperties.button = ToWebPointerButton(android_buttons_changed);
572 webPointerProperties.pointerType = ToWebPointerType(tool_type);
499 } 573 }
500 574
501 int WebEventModifiersToEventFlags(int modifiers) { 575 int WebEventModifiersToEventFlags(int modifiers) {
502 int flags = 0; 576 int flags = 0;
503 577
504 if (modifiers & blink::WebInputEvent::ShiftKey) 578 if (modifiers & blink::WebInputEvent::ShiftKey)
505 flags |= EF_SHIFT_DOWN; 579 flags |= EF_SHIFT_DOWN;
506 if (modifiers & blink::WebInputEvent::ControlKey) 580 if (modifiers & blink::WebInputEvent::ControlKey)
507 flags |= EF_CONTROL_DOWN; 581 flags |= EF_CONTROL_DOWN;
508 if (modifiers & blink::WebInputEvent::AltKey) 582 if (modifiers & blink::WebInputEvent::AltKey)
(...skipping 26 matching lines...) Expand all
535 return blink::WebInputEvent::IsRight; 609 return blink::WebInputEvent::IsRight;
536 case DomKeyLocation::NUMPAD: 610 case DomKeyLocation::NUMPAD:
537 return blink::WebInputEvent::IsKeyPad; 611 return blink::WebInputEvent::IsKeyPad;
538 case DomKeyLocation::STANDARD: 612 case DomKeyLocation::STANDARD:
539 break; 613 break;
540 } 614 }
541 return static_cast<blink::WebInputEvent::Modifiers>(0); 615 return static_cast<blink::WebInputEvent::Modifiers>(0);
542 } 616 }
543 617
544 } // namespace ui 618 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/blink/blink_event_util.h ('k') | ui/events/gesture_detection/gesture_detector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698