1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INPUT_WEB_INPUT_EVENT_H_ 32 #define THIRD_PARTY_BLINK_PUBLIC_COMMON_INPUT_WEB_INPUT_EVENT_H_ 33 34 #include <string.h> 35 36 #include <memory> 37 38 #include "base/time/time.h" 39 #include "third_party/blink/public/common/common_export.h" 40 #include "ui/gfx/geometry/point_f.h" 41 #include "ui/gfx/geometry/vector2d_f.h" 42 43 namespace blink { 44 45 // WebInputEvent -------------------------------------------------------------- 46 47 class BLINK_COMMON_EXPORT WebInputEvent { 48 public: 49 // When we use an input method (or an input method editor), we receive 50 // two events for a keypress. The former event is a keydown, which 51 // provides a keycode, and the latter is a textinput, which provides 52 // a character processed by an input method. (The mapping from a 53 // keycode to a character code is not trivial for non-English 54 // keyboards.) 55 // To support input methods, Safari sends keydown events to WebKit for 56 // filtering. WebKit sends filtered keydown events back to Safari, 57 // which sends them to input methods. 58 // Unfortunately, it is hard to apply this design to Chrome because of 59 // our multiprocess architecture. An input method is running in a 60 // browser process. On the other hand, WebKit is running in a renderer 61 // process. So, this design results in increasing IPC messages. 62 // To support input methods without increasing IPC messages, Chrome 63 // handles keyboard events in a browser process and send asynchronous 64 // input events (to be translated to DOM events) to a renderer 65 // process. 66 // This design is mostly the same as the one of Windows and Mac Carbon. 67 // So, for what it's worth, our Linux and Mac front-ends emulate our 68 // Windows front-end. To emulate our Windows front-end, we can share 69 // our back-end code among Windows, Linux, and Mac. 70 // TODO(hbono): Issue 18064: remove the KeyDown type since it isn't 71 // used in Chrome any longer. 72 73 // A Java counterpart will be generated for this enum. 74 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blink_public.web 75 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: WebInputEventType 76 enum Type { 77 kUndefined = -1, 78 kTypeFirst = kUndefined, 79 80 // WebMouseEvent 81 kMouseDown, 82 kMouseTypeFirst = kMouseDown, 83 kMouseUp, 84 kMouseMove, 85 kMouseEnter, 86 kMouseLeave, 87 kContextMenu, 88 kMouseTypeLast = kContextMenu, 89 90 // WebMouseWheelEvent 91 kMouseWheel, 92 93 // WebKeyboardEvent 94 kRawKeyDown, 95 kKeyboardTypeFirst = kRawKeyDown, 96 // KeyDown is a single event combining RawKeyDown and Char. If KeyDown is 97 // sent for a given keystroke, those two other events will not be sent. 98 // Platforms tend to prefer sending in one format (Android uses KeyDown, 99 // Windows uses RawKeyDown+Char, for example), but this is a weakly held 100 // property as tools like WebDriver/DevTools might still send the other 101 // format. 102 kKeyDown, 103 kKeyUp, 104 kChar, 105 kKeyboardTypeLast = kChar, 106 107 // WebGestureEvent - input interpreted semi-semantically, most commonly from 108 // touchscreen but also used for touchpad, mousewheel, and gamepad 109 // scrolling. 110 kGestureScrollBegin, 111 kGestureTypeFirst = kGestureScrollBegin, 112 kGestureScrollEnd, 113 kGestureScrollUpdate, 114 // Fling is a high-velocity and quickly released finger movement. 115 // FlingStart is sent once and kicks off a scroll animation. 116 kGestureFlingStart, 117 kGestureFlingCancel, 118 // Pinch is two fingers moving closer or farther apart. 119 kGesturePinchBegin, 120 kGesturePinchTypeFirst = kGesturePinchBegin, 121 kGesturePinchEnd, 122 kGesturePinchUpdate, 123 kGesturePinchTypeLast = kGesturePinchUpdate, 124 125 // The following types are variations and subevents of single-taps. 126 // 127 // Sent the moment the user's finger hits the screen. 128 kGestureTapDown, 129 // Sent a short interval later, after it seems the finger is staying in 130 // place. It's used to activate the link highlight ("show the press"). 131 kGestureShowPress, 132 // Sent on finger lift for a simple, static, quick finger tap. This is the 133 // "main" event which maps to a synthetic mouse click event. 134 kGestureTap, 135 // Sent when a GestureTapDown didn't turn into any variation of GestureTap 136 // (likely it turned into a scroll instead). 137 kGestureTapCancel, 138 // Sent as soon as the long-press timeout fires, while the finger is still 139 // down. 140 kGestureLongPress, 141 // Sent when the finger is lifted following a GestureLongPress. 142 kGestureLongTap, 143 // Sent on finger lift when two fingers tapped at the same time without 144 // moving. 145 kGestureTwoFingerTap, 146 // A rare event sent in place of GestureTap on desktop pages viewed on an 147 // Android phone. This tap could not yet be resolved into a GestureTap 148 // because it may still turn into a GestureDoubleTap. 149 kGestureTapUnconfirmed, 150 151 // On Android, double-tap is two single-taps spread apart in time, like a 152 // double-click. This event is only sent on desktop pages, and is always 153 // preceded by GestureTapUnconfirmed. It's an instruction to Blink to 154 // perform a PageScaleAnimation zoom onto the double-tapped content. (It's 155 // treated differently from GestureTap with tapCount=2, which can also 156 // happen.) 157 // On desktop, this event may be used for a double-tap with two fingers on 158 // a touchpad, as the desired effect is similar to Android's double-tap. 159 kGestureDoubleTap, 160 161 kGestureTypeLast = kGestureDoubleTap, 162 163 // WebTouchEvent - raw touch pointers not yet classified into gestures. 164 kTouchStart, 165 kTouchTypeFirst = kTouchStart, 166 kTouchMove, 167 kTouchEnd, 168 kTouchCancel, 169 // TODO(nzolghadr): This event should be replaced with 170 // kPointerCausedUaAction 171 kTouchScrollStarted, 172 kTouchTypeLast = kTouchScrollStarted, 173 174 // WebPointerEvent: work in progress 175 kPointerDown, 176 kPointerTypeFirst = kPointerDown, 177 kPointerUp, 178 kPointerMove, 179 kPointerRawUpdate, // To be only used within blink. 180 kPointerCancel, 181 kPointerCausedUaAction, 182 kPointerTypeLast = kPointerCausedUaAction, 183 184 kTypeLast = kPointerTypeLast 185 }; 186 187 // The modifier constants cannot change their values since pepper 188 // does a 1-1 mapping of its values; see 189 // content/renderer/pepper/event_conversion.cc 190 // 191 // A Java counterpart will be generated for this enum. 192 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blink_public.web 193 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: WebInputEventModifier 194 enum Modifiers { 195 // modifiers for all events: 196 kShiftKey = 1 << 0, 197 kControlKey = 1 << 1, 198 kAltKey = 1 << 2, 199 kMetaKey = 1 << 3, 200 201 // modifiers for keyboard events: 202 kIsKeyPad = 1 << 4, 203 kIsAutoRepeat = 1 << 5, 204 205 // modifiers for mouse events: 206 kLeftButtonDown = 1 << 6, 207 kMiddleButtonDown = 1 << 7, 208 kRightButtonDown = 1 << 8, 209 210 // Toggle modifers for all events. 211 kCapsLockOn = 1 << 9, 212 kNumLockOn = 1 << 10, 213 214 kIsLeft = 1 << 11, 215 kIsRight = 1 << 12, 216 217 // Indicates that an event was generated on the touch screen while 218 // touch accessibility is enabled, so the event should be handled 219 // by accessibility code first before normal input event processing. 220 kIsTouchAccessibility = 1 << 13, 221 222 kIsComposing = 1 << 14, 223 224 kAltGrKey = 1 << 15, 225 kFnKey = 1 << 16, 226 kSymbolKey = 1 << 17, 227 228 kScrollLockOn = 1 << 18, 229 230 // Whether this is a compatibility event generated due to a 231 // native touch event. Mouse events generated from touch 232 // events will set this. 233 kIsCompatibilityEventForTouch = 1 << 19, 234 235 kBackButtonDown = 1 << 20, 236 kForwardButtonDown = 1 << 21, 237 238 // Represents movement as a result of content changing under the cursor, 239 // not actual physical movement of the pointer 240 kRelativeMotionEvent = 1 << 22, 241 242 // Indication this event was injected by the devtools. 243 // TODO(dtapuska): Remove this flag once we are able to bind callbacks 244 // in event sending. 245 kFromDebugger = 1 << 23, 246 247 // Indicates this event is targeting an OOPIF, and the iframe or one of its 248 // ancestor frames moved within its embedding page's viewport recently. 249 kTargetFrameMovedRecently = 1 << 24, 250 251 // When an event is forwarded to the main thread, this modifier will tell if 252 // the event was already handled by the compositor thread or not. Based on 253 // this, the decision of whether or not the main thread should handle this 254 // event for the scrollbar can then be made. 255 kScrollbarManipulationHandledOnCompositorThread = 1 << 25, 256 257 // The set of non-stateful modifiers that specifically change the 258 // interpretation of the key being pressed. For example; IsLeft, 259 // IsRight, IsComposing don't change the meaning of the key 260 // being pressed. NumLockOn, ScrollLockOn, CapsLockOn are stateful 261 // and don't indicate explicit depressed state. 262 kKeyModifiers = kSymbolKey | kFnKey | kAltGrKey | kMetaKey | kAltKey | 263 kControlKey | kShiftKey, 264 265 kNoModifiers = 0, 266 }; 267 268 // Indicates whether the browser needs to block on the ACK result for 269 // this event, and if not, why (for metrics/diagnostics purposes). 270 // These values are direct mappings of the values in PlatformEvent 271 // so the values can be cast between the enumerations. static_asserts 272 // checking this are in web/WebInputEventConversion.cpp. 273 enum DispatchType { 274 // Event can be canceled. 275 kBlocking, 276 // Event can not be canceled. 277 kEventNonBlocking, 278 // All listeners are passive; not cancelable. 279 kListenersNonBlockingPassive, 280 // This value represents a state which would have normally blocking 281 // but was forced to be non-blocking during fling; not cancelable. 282 kListenersForcedNonBlockingDueToFling, 283 kLastDispatchType = kListenersForcedNonBlockingDueToFling, 284 }; 285 286 // The rail mode for a wheel event specifies the axis on which scrolling is 287 // expected to stick. If this axis is set to Free, then scrolling is not 288 // stuck to any axis. 289 enum RailsMode { 290 kRailsModeFree = 0, 291 kRailsModeHorizontal = 1, 292 kRailsModeVertical = 2, 293 }; 294 295 static const int kInputModifiers = 296 kShiftKey | kControlKey | kAltKey | kMetaKey; 297 GetStaticTimeStampForTests()298 static constexpr base::TimeTicks GetStaticTimeStampForTests() { 299 // Note: intentionally use a relatively large delta from base::TimeTicks == 300 // 0. Otherwise, code that tracks the time ticks of the last event that 301 // happened and computes a delta might get confused when the testing 302 // timestamp is near 0, as the computed delta may very well be under the 303 // delta threshhold. 304 // 305 // TODO(dcheng): This really shouldn't use FromInternalValue(), but 306 // constexpr support for time operations is a bit busted... 307 return base::TimeTicks::FromInternalValue(123'000'000); 308 } 309 310 // Returns true if the WebInputEvent |type| is a mouse event. IsMouseEventType(WebInputEvent::Type type)311 static bool IsMouseEventType(WebInputEvent::Type type) { 312 return kMouseTypeFirst <= type && type <= kMouseTypeLast; 313 } 314 315 // Returns true if the WebInputEvent |type| is a keyboard event. IsKeyboardEventType(WebInputEvent::Type type)316 static bool IsKeyboardEventType(WebInputEvent::Type type) { 317 return kKeyboardTypeFirst <= type && type <= kKeyboardTypeLast; 318 } 319 320 // Returns true if the WebInputEvent |type| is a touch event. IsTouchEventType(WebInputEvent::Type type)321 static bool IsTouchEventType(WebInputEvent::Type type) { 322 return kTouchTypeFirst <= type && type <= kTouchTypeLast; 323 } 324 325 // Returns true if the WebInputEvent is a gesture event. IsGestureEventType(WebInputEvent::Type type)326 static bool IsGestureEventType(WebInputEvent::Type type) { 327 return kGestureTypeFirst <= type && type <= kGestureTypeLast; 328 } 329 330 // Returns true if the WebInputEvent |type| is a pointer event. IsPointerEventType(WebInputEvent::Type type)331 static bool IsPointerEventType(WebInputEvent::Type type) { 332 return kPointerTypeFirst <= type && type <= kPointerTypeLast; 333 } 334 IsSameEventClass(const WebInputEvent & other)335 bool IsSameEventClass(const WebInputEvent& other) const { 336 if (IsMouseEventType(type_)) 337 return IsMouseEventType(other.type_); 338 if (IsGestureEventType(type_)) 339 return IsGestureEventType(other.type_); 340 if (IsTouchEventType(type_)) 341 return IsTouchEventType(other.type_); 342 if (IsKeyboardEventType(type_)) 343 return IsKeyboardEventType(other.type_); 344 if (IsPointerEventType(type_)) 345 return IsPointerEventType(other.type_); 346 return type_ == other.type_; 347 } 348 IsGestureScroll()349 bool IsGestureScroll() const { 350 switch (type_) { 351 case Type::kGestureScrollBegin: 352 case Type::kGestureScrollUpdate: 353 case Type::kGestureScrollEnd: 354 return true; 355 default: 356 return false; 357 } 358 } 359 360 // Returns true if the WebInputEvent |type| is a pinch gesture event. IsPinchGestureEventType(WebInputEvent::Type type)361 static bool IsPinchGestureEventType(WebInputEvent::Type type) { 362 return kGesturePinchTypeFirst <= type && type <= kGesturePinchTypeLast; 363 } 364 365 // Returns true if the WebInputEvent |type| is a fling gesture event. IsFlingGestureEventType(WebInputEvent::Type type)366 static bool IsFlingGestureEventType(WebInputEvent::Type type) { 367 return kGestureFlingStart <= type && type <= kGestureFlingCancel; 368 } 369 GetName(WebInputEvent::Type type)370 static const char* GetName(WebInputEvent::Type type) { 371 #define CASE_TYPE(t) \ 372 case WebInputEvent::k##t: \ 373 return #t 374 switch (type) { 375 CASE_TYPE(Undefined); 376 CASE_TYPE(MouseDown); 377 CASE_TYPE(MouseUp); 378 CASE_TYPE(MouseMove); 379 CASE_TYPE(MouseEnter); 380 CASE_TYPE(MouseLeave); 381 CASE_TYPE(ContextMenu); 382 CASE_TYPE(MouseWheel); 383 CASE_TYPE(RawKeyDown); 384 CASE_TYPE(KeyDown); 385 CASE_TYPE(KeyUp); 386 CASE_TYPE(Char); 387 CASE_TYPE(GestureScrollBegin); 388 CASE_TYPE(GestureScrollEnd); 389 CASE_TYPE(GestureScrollUpdate); 390 CASE_TYPE(GestureFlingStart); 391 CASE_TYPE(GestureFlingCancel); 392 CASE_TYPE(GestureShowPress); 393 CASE_TYPE(GestureTap); 394 CASE_TYPE(GestureTapUnconfirmed); 395 CASE_TYPE(GestureTapDown); 396 CASE_TYPE(GestureTapCancel); 397 CASE_TYPE(GestureDoubleTap); 398 CASE_TYPE(GestureTwoFingerTap); 399 CASE_TYPE(GestureLongPress); 400 CASE_TYPE(GestureLongTap); 401 CASE_TYPE(GesturePinchBegin); 402 CASE_TYPE(GesturePinchEnd); 403 CASE_TYPE(GesturePinchUpdate); 404 CASE_TYPE(TouchStart); 405 CASE_TYPE(TouchMove); 406 CASE_TYPE(TouchEnd); 407 CASE_TYPE(TouchCancel); 408 CASE_TYPE(TouchScrollStarted); 409 CASE_TYPE(PointerDown); 410 CASE_TYPE(PointerUp); 411 CASE_TYPE(PointerMove); 412 CASE_TYPE(PointerRawUpdate); 413 CASE_TYPE(PointerCancel); 414 CASE_TYPE(PointerCausedUaAction); 415 } 416 #undef CASE_TYPE 417 NOTREACHED(); 418 return ""; 419 } 420 FrameScale()421 float FrameScale() const { return frame_scale_; } SetFrameScale(float scale)422 void SetFrameScale(float scale) { frame_scale_ = scale; } 423 FrameTranslate()424 gfx::Vector2dF FrameTranslate() const { return frame_translate_; } SetFrameTranslate(const gfx::Vector2dF & translate)425 void SetFrameTranslate(const gfx::Vector2dF& translate) { 426 frame_translate_ = translate; 427 } 428 GetType()429 Type GetType() const { return type_; } SetType(Type type_param)430 void SetType(Type type_param) { type_ = type_param; } 431 GetModifiers()432 int GetModifiers() const { return modifiers_; } SetModifiers(int modifiers_param)433 void SetModifiers(int modifiers_param) { modifiers_ = modifiers_param; } 434 TimeStamp()435 base::TimeTicks TimeStamp() const { return time_stamp_; } SetTimeStamp(base::TimeTicks time_stamp)436 void SetTimeStamp(base::TimeTicks time_stamp) { time_stamp_ = time_stamp; } 437 SetTargetFrameMovedRecently()438 void SetTargetFrameMovedRecently() { 439 modifiers_ |= kTargetFrameMovedRecently; 440 } 441 SetScrollbarManipulationHandledOnCompositorThread()442 void SetScrollbarManipulationHandledOnCompositorThread() { 443 modifiers_ |= kScrollbarManipulationHandledOnCompositorThread; 444 } 445 446 virtual ~WebInputEvent() = default; 447 448 virtual std::unique_ptr<WebInputEvent> Clone() const = 0; 449 450 protected: 451 // The root frame scale. 452 float frame_scale_ = 1; 453 454 // The root frame translation (applied post scale). 455 gfx::Vector2dF frame_translate_; 456 WebInputEvent(Type type,int modifiers,base::TimeTicks time_stamp)457 WebInputEvent(Type type, int modifiers, base::TimeTicks time_stamp) 458 : time_stamp_(time_stamp), type_(type), modifiers_(modifiers) {} 459 WebInputEvent()460 WebInputEvent() { time_stamp_ = base::TimeTicks(); } 461 462 // Event time since platform start with microsecond resolution. 463 base::TimeTicks time_stamp_; 464 Type type_ = kUndefined; 465 int modifiers_ = kNoModifiers; 466 }; 467 468 } // namespace blink 469 470 #endif 471