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/notreached.h" 39 #include "base/time/time.h" 40 #include "third_party/blink/public/common/common_export.h" 41 #include "third_party/blink/public/mojom/input/input_event.mojom-shared.h" 42 #include "ui/events/types/event_type.h" 43 #include "ui/events/types/scroll_input_type.h" 44 #include "ui/gfx/geometry/point_f.h" 45 #include "ui/gfx/geometry/vector2d_f.h" 46 47 namespace blink { 48 49 // WebInputEvent -------------------------------------------------------------- 50 51 class BLINK_COMMON_EXPORT WebInputEvent { 52 public: 53 // When we use an input method (or an input method editor), we receive 54 // two events for a keypress. The former event is a keydown, which 55 // provides a keycode, and the latter is a textinput, which provides 56 // a character processed by an input method. (The mapping from a 57 // keycode to a character code is not trivial for non-English 58 // keyboards.) 59 // To support input methods, Safari sends keydown events to WebKit for 60 // filtering. WebKit sends filtered keydown events back to Safari, 61 // which sends them to input methods. 62 // Unfortunately, it is hard to apply this design to Chrome because of 63 // our multiprocess architecture. An input method is running in a 64 // browser process. On the other hand, WebKit is running in a renderer 65 // process. So, this design results in increasing IPC messages. 66 // To support input methods without increasing IPC messages, Chrome 67 // handles keyboard events in a browser process and send asynchronous 68 // input events (to be translated to DOM events) to a renderer 69 // process. 70 // This design is mostly the same as the one of Windows and Mac Carbon. 71 // So, for what it's worth, our Linux and Mac front-ends emulate our 72 // Windows front-end. To emulate our Windows front-end, we can share 73 // our back-end code among Windows, Linux, and Mac. 74 // TODO(hbono): Issue 18064: remove the KeyDown type since it isn't 75 // used in Chrome any longer. 76 77 using Type = blink::mojom::EventType; 78 79 // The modifier constants cannot change their values since pepper 80 // does a 1-1 mapping of its values; see 81 // content/renderer/pepper/event_conversion.cc 82 // 83 // A Java counterpart will be generated for this enum. 84 // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blink_public.web 85 // GENERATED_JAVA_CLASS_NAME_OVERRIDE: WebInputEventModifier 86 enum Modifiers { 87 // modifiers for all events: 88 kShiftKey = 1 << 0, 89 kControlKey = 1 << 1, 90 kAltKey = 1 << 2, 91 kMetaKey = 1 << 3, 92 93 // modifiers for keyboard events: 94 kIsKeyPad = 1 << 4, 95 kIsAutoRepeat = 1 << 5, 96 97 // modifiers for mouse events: 98 kLeftButtonDown = 1 << 6, 99 kMiddleButtonDown = 1 << 7, 100 kRightButtonDown = 1 << 8, 101 102 // Toggle modifers for all events. 103 kCapsLockOn = 1 << 9, 104 kNumLockOn = 1 << 10, 105 106 kIsLeft = 1 << 11, 107 kIsRight = 1 << 12, 108 109 // Indicates that an event was generated on the touch screen while 110 // touch accessibility is enabled, so the event should be handled 111 // by accessibility code first before normal input event processing. 112 kIsTouchAccessibility = 1 << 13, 113 114 kIsComposing = 1 << 14, 115 116 kAltGrKey = 1 << 15, 117 kFnKey = 1 << 16, 118 kSymbolKey = 1 << 17, 119 120 kScrollLockOn = 1 << 18, 121 122 // Whether this is a compatibility event generated due to a 123 // native touch event. Mouse events generated from touch 124 // events will set this. 125 kIsCompatibilityEventForTouch = 1 << 19, 126 127 kBackButtonDown = 1 << 20, 128 kForwardButtonDown = 1 << 21, 129 130 // Represents movement as a result of content changing under the cursor, 131 // not actual physical movement of the pointer 132 kRelativeMotionEvent = 1 << 22, 133 134 // Indication this event was injected by the devtools. 135 // TODO(dtapuska): Remove this flag once we are able to bind callbacks 136 // in event sending. 137 kFromDebugger = 1 << 23, 138 139 // Indicates this event is targeting an OOPIF, and the iframe or one of its 140 // ancestor frames moved within its embedding page's viewport recently. 141 kTargetFrameMovedRecently = 1 << 24, 142 143 // When an event is forwarded to the main thread, this modifier will tell if 144 // the event was already handled by the compositor thread or not. Based on 145 // this, the decision of whether or not the main thread should handle this 146 // event for the scrollbar can then be made. 147 kScrollbarManipulationHandledOnCompositorThread = 1 << 25, 148 149 // The set of non-stateful modifiers that specifically change the 150 // interpretation of the key being pressed. For example; IsLeft, 151 // IsRight, IsComposing don't change the meaning of the key 152 // being pressed. NumLockOn, ScrollLockOn, CapsLockOn are stateful 153 // and don't indicate explicit depressed state. 154 kKeyModifiers = kSymbolKey | kFnKey | kAltGrKey | kMetaKey | kAltKey | 155 kControlKey | kShiftKey, 156 157 kNoModifiers = 0, 158 }; 159 160 using DispatchType = mojom::DispatchType; 161 162 // The rail mode for a wheel event specifies the axis on which scrolling is 163 // expected to stick. If this axis is set to Free, then scrolling is not 164 // stuck to any axis. 165 enum RailsMode { 166 kRailsModeFree = 0, 167 kRailsModeHorizontal = 1, 168 kRailsModeVertical = 2, 169 }; 170 171 static const int kInputModifiers = 172 kShiftKey | kControlKey | kAltKey | kMetaKey; 173 GetStaticTimeStampForTests()174 static constexpr base::TimeTicks GetStaticTimeStampForTests() { 175 // Note: intentionally use a relatively large delta from base::TimeTicks == 176 // 0. Otherwise, code that tracks the time ticks of the last event that 177 // happened and computes a delta might get confused when the testing 178 // timestamp is near 0, as the computed delta may very well be under the 179 // delta threshhold. 180 // 181 // TODO(dcheng): This really shouldn't use FromInternalValue(), but 182 // constexpr support for time operations is a bit busted... 183 return base::TimeTicks::FromInternalValue(123'000'000); 184 } 185 186 // Returns true if the WebInputEvent |type| is a mouse event. IsMouseEventType(WebInputEvent::Type type)187 static bool IsMouseEventType(WebInputEvent::Type type) { 188 return Type::kMouseTypeFirst <= type && type <= Type::kMouseTypeLast; 189 } 190 191 // Returns true if the WebInputEvent |type| is a keyboard event. IsKeyboardEventType(WebInputEvent::Type type)192 static bool IsKeyboardEventType(WebInputEvent::Type type) { 193 return Type::kKeyboardTypeFirst <= type && type <= Type::kKeyboardTypeLast; 194 } 195 196 // Returns true if the WebInputEvent |type| is a touch event. IsTouchEventType(WebInputEvent::Type type)197 static bool IsTouchEventType(WebInputEvent::Type type) { 198 return Type::kTouchTypeFirst <= type && type <= Type::kTouchTypeLast; 199 } 200 201 // Returns true if the WebInputEvent is a gesture event. IsGestureEventType(WebInputEvent::Type type)202 static bool IsGestureEventType(WebInputEvent::Type type) { 203 return Type::kGestureTypeFirst <= type && type <= Type::kGestureTypeLast; 204 } 205 206 // Returns true if the WebInputEvent |type| is a pointer event. IsPointerEventType(WebInputEvent::Type type)207 static bool IsPointerEventType(WebInputEvent::Type type) { 208 return Type::kPointerTypeFirst <= type && type <= Type::kPointerTypeLast; 209 } 210 IsSameEventClass(const WebInputEvent & other)211 bool IsSameEventClass(const WebInputEvent& other) const { 212 if (IsMouseEventType(type_)) 213 return IsMouseEventType(other.type_); 214 if (IsGestureEventType(type_)) 215 return IsGestureEventType(other.type_); 216 if (IsTouchEventType(type_)) 217 return IsTouchEventType(other.type_); 218 if (IsKeyboardEventType(type_)) 219 return IsKeyboardEventType(other.type_); 220 if (IsPointerEventType(type_)) 221 return IsPointerEventType(other.type_); 222 return type_ == other.type_; 223 } 224 IsGestureScroll()225 bool IsGestureScroll() const { 226 switch (type_) { 227 case Type::kGestureScrollBegin: 228 case Type::kGestureScrollUpdate: 229 case Type::kGestureScrollEnd: 230 return true; 231 default: 232 return false; 233 } 234 } 235 236 // Returns true if the WebInputEvent |type| is a pinch gesture event. IsPinchGestureEventType(WebInputEvent::Type type)237 static bool IsPinchGestureEventType(WebInputEvent::Type type) { 238 return Type::kGesturePinchTypeFirst <= type && 239 type <= Type::kGesturePinchTypeLast; 240 } 241 242 // Returns true if the WebInputEvent |type| is a fling gesture event. IsFlingGestureEventType(WebInputEvent::Type type)243 static bool IsFlingGestureEventType(WebInputEvent::Type type) { 244 return Type::kGestureFlingStart <= type && 245 type <= Type::kGestureFlingCancel; 246 } 247 GetName(WebInputEvent::Type type)248 static const char* GetName(WebInputEvent::Type type) { 249 #define CASE_TYPE(t) \ 250 case WebInputEvent::Type::k##t: \ 251 return #t 252 switch (type) { 253 CASE_TYPE(Undefined); 254 CASE_TYPE(MouseDown); 255 CASE_TYPE(MouseUp); 256 CASE_TYPE(MouseMove); 257 CASE_TYPE(MouseEnter); 258 CASE_TYPE(MouseLeave); 259 CASE_TYPE(ContextMenu); 260 CASE_TYPE(MouseWheel); 261 CASE_TYPE(RawKeyDown); 262 CASE_TYPE(KeyDown); 263 CASE_TYPE(KeyUp); 264 CASE_TYPE(Char); 265 CASE_TYPE(GestureScrollBegin); 266 CASE_TYPE(GestureScrollEnd); 267 CASE_TYPE(GestureScrollUpdate); 268 CASE_TYPE(GestureFlingStart); 269 CASE_TYPE(GestureFlingCancel); 270 CASE_TYPE(GestureShowPress); 271 CASE_TYPE(GestureTap); 272 CASE_TYPE(GestureTapUnconfirmed); 273 CASE_TYPE(GestureTapDown); 274 CASE_TYPE(GestureTapCancel); 275 CASE_TYPE(GestureDoubleTap); 276 CASE_TYPE(GestureTwoFingerTap); 277 CASE_TYPE(GestureLongPress); 278 CASE_TYPE(GestureLongTap); 279 CASE_TYPE(GesturePinchBegin); 280 CASE_TYPE(GesturePinchEnd); 281 CASE_TYPE(GesturePinchUpdate); 282 CASE_TYPE(TouchStart); 283 CASE_TYPE(TouchMove); 284 CASE_TYPE(TouchEnd); 285 CASE_TYPE(TouchCancel); 286 CASE_TYPE(TouchScrollStarted); 287 CASE_TYPE(PointerDown); 288 CASE_TYPE(PointerUp); 289 CASE_TYPE(PointerMove); 290 CASE_TYPE(PointerRawUpdate); 291 CASE_TYPE(PointerCancel); 292 CASE_TYPE(PointerCausedUaAction); 293 } 294 #undef CASE_TYPE 295 NOTREACHED(); 296 return ""; 297 } 298 FrameScale()299 float FrameScale() const { return frame_scale_; } SetFrameScale(float scale)300 void SetFrameScale(float scale) { frame_scale_ = scale; } 301 FrameTranslate()302 gfx::Vector2dF FrameTranslate() const { return frame_translate_; } SetFrameTranslate(const gfx::Vector2dF & translate)303 void SetFrameTranslate(const gfx::Vector2dF& translate) { 304 frame_translate_ = translate; 305 } 306 GetType()307 Type GetType() const { return type_; } SetType(Type type_param)308 void SetType(Type type_param) { type_ = type_param; } 309 GetModifiers()310 int GetModifiers() const { return modifiers_; } SetModifiers(int modifiers_param)311 void SetModifiers(int modifiers_param) { modifiers_ = modifiers_param; } 312 TimeStamp()313 base::TimeTicks TimeStamp() const { return time_stamp_; } SetTimeStamp(base::TimeTicks time_stamp)314 void SetTimeStamp(base::TimeTicks time_stamp) { time_stamp_ = time_stamp; } 315 SetTargetFrameMovedRecently()316 void SetTargetFrameMovedRecently() { 317 modifiers_ |= kTargetFrameMovedRecently; 318 } 319 SetScrollbarManipulationHandledOnCompositorThread()320 void SetScrollbarManipulationHandledOnCompositorThread() { 321 modifiers_ |= kScrollbarManipulationHandledOnCompositorThread; 322 } 323 324 virtual ~WebInputEvent() = default; 325 326 virtual std::unique_ptr<WebInputEvent> Clone() const = 0; 327 328 // Returns whether the current event can be merged with the provided 329 // |event|. 330 virtual bool CanCoalesce(const blink::WebInputEvent& event) const = 0; 331 332 // Merge the current event with attributes from |event|. 333 virtual void Coalesce(const WebInputEvent& event) = 0; 334 335 // Returns the scroll input type if this is a scroll event; otherwise, 336 // returns base::nullopt. 337 virtual base::Optional<ui::ScrollInputType> GetScrollInputType() const; 338 339 // Convert this WebInputEvent::Type to a ui::EventType. Note that this is 340 // not a 1:1 relationship. Multiple blink types convert to the same 341 // ui::EventType and not all types do convert. 342 ui::EventType GetTypeAsUiEventType() const; 343 344 protected: 345 // The root frame scale. 346 float frame_scale_ = 1; 347 348 // The root frame translation (applied post scale). 349 gfx::Vector2dF frame_translate_; 350 WebInputEvent(Type type,int modifiers,base::TimeTicks time_stamp)351 WebInputEvent(Type type, int modifiers, base::TimeTicks time_stamp) 352 : time_stamp_(time_stamp), type_(type), modifiers_(modifiers) {} 353 WebInputEvent()354 WebInputEvent() { time_stamp_ = base::TimeTicks(); } 355 356 static DispatchType MergeDispatchTypes(DispatchType type_1, 357 DispatchType type_2); 358 359 // Event time since platform start with microsecond resolution. 360 base::TimeTicks time_stamp_; 361 Type type_ = Type::kUndefined; 362 int modifiers_ = kNoModifiers; 363 }; 364 365 } // namespace blink 366 367 #endif 368