| /* |
| * Copyright (C) 2009 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #ifndef THIRD_PARTY_BLINK_PUBLIC_COMMON_INPUT_WEB_INPUT_EVENT_H_ |
| #define THIRD_PARTY_BLINK_PUBLIC_COMMON_INPUT_WEB_INPUT_EVENT_H_ |
| |
| #include <string.h> |
| |
| #include <memory> |
| |
| #include "base/notreached.h" |
| #include "base/time/time.h" |
| #include "third_party/blink/public/common/common_export.h" |
| #include "third_party/blink/public/mojom/input/input_event.mojom-shared.h" |
| #include "ui/events/types/event_type.h" |
| #include "ui/events/types/scroll_input_type.h" |
| #include "ui/gfx/geometry/point_f.h" |
| #include "ui/gfx/geometry/vector2d_f.h" |
| |
| namespace blink { |
| |
| // WebInputEvent -------------------------------------------------------------- |
| |
| class BLINK_COMMON_EXPORT WebInputEvent { |
| public: |
| // When we use an input method (or an input method editor), we receive |
| // two events for a keypress. The former event is a keydown, which |
| // provides a keycode, and the latter is a textinput, which provides |
| // a character processed by an input method. (The mapping from a |
| // keycode to a character code is not trivial for non-English |
| // keyboards.) |
| // To support input methods, Safari sends keydown events to WebKit for |
| // filtering. WebKit sends filtered keydown events back to Safari, |
| // which sends them to input methods. |
| // Unfortunately, it is hard to apply this design to Chrome because of |
| // our multiprocess architecture. An input method is running in a |
| // browser process. On the other hand, WebKit is running in a renderer |
| // process. So, this design results in increasing IPC messages. |
| // To support input methods without increasing IPC messages, Chrome |
| // handles keyboard events in a browser process and send asynchronous |
| // input events (to be translated to DOM events) to a renderer |
| // process. |
| // This design is mostly the same as the one of Windows and Mac Carbon. |
| // So, for what it's worth, our Linux and Mac front-ends emulate our |
| // Windows front-end. To emulate our Windows front-end, we can share |
| // our back-end code among Windows, Linux, and Mac. |
| // TODO(hbono): Issue 18064: remove the KeyDown type since it isn't |
| // used in Chrome any longer. |
| |
| using Type = blink::mojom::EventType; |
| |
| // The modifier constants cannot change their values since pepper |
| // does a 1-1 mapping of its values; see |
| // content/renderer/pepper/event_conversion.cc |
| // |
| // A Java counterpart will be generated for this enum. |
| // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.blink_public.web |
| // GENERATED_JAVA_CLASS_NAME_OVERRIDE: WebInputEventModifier |
| enum Modifiers { |
| // modifiers for all events: |
| kShiftKey = 1 << 0, |
| kControlKey = 1 << 1, |
| kAltKey = 1 << 2, |
| kMetaKey = 1 << 3, |
| |
| // modifiers for keyboard events: |
| kIsKeyPad = 1 << 4, |
| kIsAutoRepeat = 1 << 5, |
| |
| // modifiers for mouse events: |
| kLeftButtonDown = 1 << 6, |
| kMiddleButtonDown = 1 << 7, |
| kRightButtonDown = 1 << 8, |
| |
| // Toggle modifers for all events. |
| kCapsLockOn = 1 << 9, |
| kNumLockOn = 1 << 10, |
| |
| kIsLeft = 1 << 11, |
| kIsRight = 1 << 12, |
| |
| // Indicates that an event was generated on the touch screen while |
| // touch accessibility is enabled, so the event should be handled |
| // by accessibility code first before normal input event processing. |
| kIsTouchAccessibility = 1 << 13, |
| |
| kIsComposing = 1 << 14, |
| |
| kAltGrKey = 1 << 15, |
| kFnKey = 1 << 16, |
| kSymbolKey = 1 << 17, |
| |
| kScrollLockOn = 1 << 18, |
| |
| // Whether this is a compatibility event generated due to a |
| // native touch event. Mouse events generated from touch |
| // events will set this. |
| kIsCompatibilityEventForTouch = 1 << 19, |
| |
| kBackButtonDown = 1 << 20, |
| kForwardButtonDown = 1 << 21, |
| |
| // Represents movement as a result of content changing under the cursor, |
| // not actual physical movement of the pointer |
| kRelativeMotionEvent = 1 << 22, |
| |
| // Indication this event was injected by the devtools. |
| // TODO(dtapuska): Remove this flag once we are able to bind callbacks |
| // in event sending. |
| kFromDebugger = 1 << 23, |
| |
| // Indicates this event is targeting an OOPIF, and the iframe or one of its |
| // ancestor frames moved within its embedding page's viewport recently. |
| kTargetFrameMovedRecently = 1 << 24, |
| |
| // When an event is forwarded to the main thread, this modifier will tell if |
| // the event was already handled by the compositor thread or not. Based on |
| // this, the decision of whether or not the main thread should handle this |
| // event for the scrollbar can then be made. |
| kScrollbarManipulationHandledOnCompositorThread = 1 << 25, |
| |
| // The set of non-stateful modifiers that specifically change the |
| // interpretation of the key being pressed. For example; IsLeft, |
| // IsRight, IsComposing don't change the meaning of the key |
| // being pressed. NumLockOn, ScrollLockOn, CapsLockOn are stateful |
| // and don't indicate explicit depressed state. |
| kKeyModifiers = kSymbolKey | kFnKey | kAltGrKey | kMetaKey | kAltKey | |
| kControlKey | kShiftKey, |
| |
| kNoModifiers = 0, |
| }; |
| |
| using DispatchType = mojom::DispatchType; |
| |
| // The rail mode for a wheel event specifies the axis on which scrolling is |
| // expected to stick. If this axis is set to Free, then scrolling is not |
| // stuck to any axis. |
| enum RailsMode { |
| kRailsModeFree = 0, |
| kRailsModeHorizontal = 1, |
| kRailsModeVertical = 2, |
| }; |
| |
| static const int kInputModifiers = |
| kShiftKey | kControlKey | kAltKey | kMetaKey; |
| |
| static constexpr base::TimeTicks GetStaticTimeStampForTests() { |
| // Note: intentionally use a relatively large delta from base::TimeTicks == |
| // 0. Otherwise, code that tracks the time ticks of the last event that |
| // happened and computes a delta might get confused when the testing |
| // timestamp is near 0, as the computed delta may very well be under the |
| // delta threshhold. |
| // |
| // TODO(dcheng): This really shouldn't use FromInternalValue(), but |
| // constexpr support for time operations is a bit busted... |
| return base::TimeTicks::FromInternalValue(123'000'000); |
| } |
| |
| // Returns true if the WebInputEvent |type| is a mouse event. |
| static bool IsMouseEventType(WebInputEvent::Type type) { |
| return Type::kMouseTypeFirst <= type && type <= Type::kMouseTypeLast; |
| } |
| |
| // Returns true if the WebInputEvent |type| is a keyboard event. |
| static bool IsKeyboardEventType(WebInputEvent::Type type) { |
| return Type::kKeyboardTypeFirst <= type && type <= Type::kKeyboardTypeLast; |
| } |
| |
| // Returns true if the WebInputEvent |type| is a touch event. |
| static bool IsTouchEventType(WebInputEvent::Type type) { |
| return Type::kTouchTypeFirst <= type && type <= Type::kTouchTypeLast; |
| } |
| |
| // Returns true if the WebInputEvent is a gesture event. |
| static bool IsGestureEventType(WebInputEvent::Type type) { |
| return Type::kGestureTypeFirst <= type && type <= Type::kGestureTypeLast; |
| } |
| |
| // Returns true if the WebInputEvent |type| is a pointer event. |
| static bool IsPointerEventType(WebInputEvent::Type type) { |
| return Type::kPointerTypeFirst <= type && type <= Type::kPointerTypeLast; |
| } |
| |
| bool IsSameEventClass(const WebInputEvent& other) const { |
| if (IsMouseEventType(type_)) |
| return IsMouseEventType(other.type_); |
| if (IsGestureEventType(type_)) |
| return IsGestureEventType(other.type_); |
| if (IsTouchEventType(type_)) |
| return IsTouchEventType(other.type_); |
| if (IsKeyboardEventType(type_)) |
| return IsKeyboardEventType(other.type_); |
| if (IsPointerEventType(type_)) |
| return IsPointerEventType(other.type_); |
| return type_ == other.type_; |
| } |
| |
| bool IsGestureScroll() const { |
| switch (type_) { |
| case Type::kGestureScrollBegin: |
| case Type::kGestureScrollUpdate: |
| case Type::kGestureScrollEnd: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| // Returns true if the WebInputEvent |type| is a pinch gesture event. |
| static bool IsPinchGestureEventType(WebInputEvent::Type type) { |
| return Type::kGesturePinchTypeFirst <= type && |
| type <= Type::kGesturePinchTypeLast; |
| } |
| |
| // Returns true if the WebInputEvent |type| is a fling gesture event. |
| static bool IsFlingGestureEventType(WebInputEvent::Type type) { |
| return Type::kGestureFlingStart <= type && |
| type <= Type::kGestureFlingCancel; |
| } |
| |
| static const char* GetName(WebInputEvent::Type type) { |
| #define CASE_TYPE(t) \ |
| case WebInputEvent::Type::k##t: \ |
| return #t |
| switch (type) { |
| CASE_TYPE(Undefined); |
| CASE_TYPE(MouseDown); |
| CASE_TYPE(MouseUp); |
| CASE_TYPE(MouseMove); |
| CASE_TYPE(MouseEnter); |
| CASE_TYPE(MouseLeave); |
| CASE_TYPE(ContextMenu); |
| CASE_TYPE(MouseWheel); |
| CASE_TYPE(RawKeyDown); |
| CASE_TYPE(KeyDown); |
| CASE_TYPE(KeyUp); |
| CASE_TYPE(Char); |
| CASE_TYPE(GestureScrollBegin); |
| CASE_TYPE(GestureScrollEnd); |
| CASE_TYPE(GestureScrollUpdate); |
| CASE_TYPE(GestureFlingStart); |
| CASE_TYPE(GestureFlingCancel); |
| CASE_TYPE(GestureShowPress); |
| CASE_TYPE(GestureTap); |
| CASE_TYPE(GestureTapUnconfirmed); |
| CASE_TYPE(GestureTapDown); |
| CASE_TYPE(GestureTapCancel); |
| CASE_TYPE(GestureDoubleTap); |
| CASE_TYPE(GestureTwoFingerTap); |
| CASE_TYPE(GestureLongPress); |
| CASE_TYPE(GestureLongTap); |
| CASE_TYPE(GesturePinchBegin); |
| CASE_TYPE(GesturePinchEnd); |
| CASE_TYPE(GesturePinchUpdate); |
| CASE_TYPE(TouchStart); |
| CASE_TYPE(TouchMove); |
| CASE_TYPE(TouchEnd); |
| CASE_TYPE(TouchCancel); |
| CASE_TYPE(TouchScrollStarted); |
| CASE_TYPE(PointerDown); |
| CASE_TYPE(PointerUp); |
| CASE_TYPE(PointerMove); |
| CASE_TYPE(PointerRawUpdate); |
| CASE_TYPE(PointerCancel); |
| CASE_TYPE(PointerCausedUaAction); |
| } |
| #undef CASE_TYPE |
| NOTREACHED(); |
| return ""; |
| } |
| |
| float FrameScale() const { return frame_scale_; } |
| void SetFrameScale(float scale) { frame_scale_ = scale; } |
| |
| gfx::Vector2dF FrameTranslate() const { return frame_translate_; } |
| void SetFrameTranslate(const gfx::Vector2dF& translate) { |
| frame_translate_ = translate; |
| } |
| |
| Type GetType() const { return type_; } |
| void SetType(Type type_param) { type_ = type_param; } |
| |
| int GetModifiers() const { return modifiers_; } |
| void SetModifiers(int modifiers_param) { modifiers_ = modifiers_param; } |
| |
| base::TimeTicks TimeStamp() const { return time_stamp_; } |
| void SetTimeStamp(base::TimeTicks time_stamp) { time_stamp_ = time_stamp; } |
| |
| void SetTargetFrameMovedRecently() { |
| modifiers_ |= kTargetFrameMovedRecently; |
| } |
| |
| void SetScrollbarManipulationHandledOnCompositorThread() { |
| modifiers_ |= kScrollbarManipulationHandledOnCompositorThread; |
| } |
| |
| virtual ~WebInputEvent() = default; |
| |
| virtual std::unique_ptr<WebInputEvent> Clone() const = 0; |
| |
| // Returns whether the current event can be merged with the provided |
| // |event|. |
| virtual bool CanCoalesce(const blink::WebInputEvent& event) const = 0; |
| |
| // Merge the current event with attributes from |event|. |
| virtual void Coalesce(const WebInputEvent& event) = 0; |
| |
| // Returns the scroll input type if this is a scroll event; otherwise, |
| // returns base::nullopt. |
| virtual base::Optional<ui::ScrollInputType> GetScrollInputType() const; |
| |
| // Convert this WebInputEvent::Type to a ui::EventType. Note that this is |
| // not a 1:1 relationship. Multiple blink types convert to the same |
| // ui::EventType and not all types do convert. |
| ui::EventType GetTypeAsUiEventType() const; |
| |
| protected: |
| // The root frame scale. |
| float frame_scale_ = 1; |
| |
| // The root frame translation (applied post scale). |
| gfx::Vector2dF frame_translate_; |
| |
| WebInputEvent(Type type, int modifiers, base::TimeTicks time_stamp) |
| : time_stamp_(time_stamp), type_(type), modifiers_(modifiers) {} |
| |
| WebInputEvent() { time_stamp_ = base::TimeTicks(); } |
| |
| static DispatchType MergeDispatchTypes(DispatchType type_1, |
| DispatchType type_2); |
| |
| // Event time since platform start with microsecond resolution. |
| base::TimeTicks time_stamp_; |
| Type type_ = Type::kUndefined; |
| int modifiers_ = kNoModifiers; |
| }; |
| |
| } // namespace blink |
| |
| #endif |