summaryrefslogtreecommitdiffstats
path: root/widget/InputData.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/InputData.h828
1 files changed, 828 insertions, 0 deletions
diff --git a/widget/InputData.h b/widget/InputData.h
new file mode 100644
index 0000000000..4b36b58cec
--- /dev/null
+++ b/widget/InputData.h
@@ -0,0 +1,828 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef InputData_h__
+#define InputData_h__
+
+#include "nsDebug.h"
+#include "nsPoint.h"
+#include "nsTArray.h"
+#include "Units.h"
+#include "mozilla/ScrollTypes.h"
+#include "mozilla/DefineEnum.h"
+#include "mozilla/EventForwards.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/WheelHandlingHelper.h" // for WheelDeltaAdjustmentStrategy
+#include "mozilla/gfx/MatrixFwd.h"
+#include "mozilla/layers/APZPublicUtils.h"
+#include "mozilla/layers/KeyboardScrollAction.h"
+#include "mozilla/TextEvents.h"
+
+template <class E>
+struct already_AddRefed;
+class nsIWidget;
+
+namespace mozilla {
+
+namespace layers {
+class APZInputBridgeChild;
+class PAPZInputBridgeParent;
+} // namespace layers
+
+namespace dom {
+class Touch;
+} // namespace dom
+
+// clang-format off
+MOZ_DEFINE_ENUM(
+ InputType, (
+ MULTITOUCH_INPUT,
+ MOUSE_INPUT,
+ PANGESTURE_INPUT,
+ PINCHGESTURE_INPUT,
+ TAPGESTURE_INPUT,
+ SCROLLWHEEL_INPUT,
+ KEYBOARD_INPUT
+));
+// clang-format on
+
+class MultiTouchInput;
+class MouseInput;
+class PanGestureInput;
+class PinchGestureInput;
+class TapGestureInput;
+class ScrollWheelInput;
+class KeyboardInput;
+
+// This looks unnecessary now, but as we add more and more classes that derive
+// from InputType (eventually probably almost as many as *Events.h has), it
+// will be more and more clear what's going on with a macro that shortens the
+// definition of the RTTI functions.
+#define INPUTDATA_AS_CHILD_TYPE(type, enumID) \
+ const type& As##type() const { \
+ MOZ_ASSERT(mInputType == enumID, "Invalid cast of InputData."); \
+ return (const type&)*this; \
+ } \
+ type& As##type() { \
+ MOZ_ASSERT(mInputType == enumID, "Invalid cast of InputData."); \
+ return (type&)*this; \
+ }
+
+/** Base input data class. Should never be instantiated. */
+class InputData {
+ public:
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ InputType mInputType;
+ // Time that this data is relevant to. This only really matters when this data
+ // is used as an event.
+ TimeStamp mTimeStamp;
+ // The sequence number of the last potentially focus changing event handled
+ // by APZ. This is used to track when that event has been processed by
+ // content, and focus can be reconfirmed for async keyboard scrolling.
+ uint64_t mFocusSequenceNumber;
+
+ // The LayersId of the content process that the corresponding WidgetEvent
+ // should be dispatched to.
+ layers::LayersId mLayersId;
+
+ Modifiers modifiers;
+
+ INPUTDATA_AS_CHILD_TYPE(MultiTouchInput, MULTITOUCH_INPUT)
+ INPUTDATA_AS_CHILD_TYPE(MouseInput, MOUSE_INPUT)
+ INPUTDATA_AS_CHILD_TYPE(PanGestureInput, PANGESTURE_INPUT)
+ INPUTDATA_AS_CHILD_TYPE(PinchGestureInput, PINCHGESTURE_INPUT)
+ INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT)
+ INPUTDATA_AS_CHILD_TYPE(ScrollWheelInput, SCROLLWHEEL_INPUT)
+ INPUTDATA_AS_CHILD_TYPE(KeyboardInput, KEYBOARD_INPUT)
+
+ virtual ~InputData();
+ explicit InputData(InputType aInputType);
+
+ protected:
+ InputData(InputType aInputType, TimeStamp aTimeStamp, Modifiers aModifiers);
+};
+
+/**
+ * Data container for a single touch input. Similar to dom::Touch, but used in
+ * off-main-thread situations. This is more for just storing touch data, whereas
+ * dom::Touch is more useful for dispatching through the DOM (which can only
+ * happen on the main thread). dom::Touch also bears the problem of storing
+ * pointers to nsIWidget instances which can only be used on the main thread,
+ * so if instead we used dom::Touch and ever set these pointers
+ * off-main-thread, Bad Things Can Happen(tm).
+ *
+ * Note that this doesn't inherit from InputData because this itself is not an
+ * event. It is only a container/struct that should have any number of instances
+ * within a MultiTouchInput.
+ *
+ * fixme/bug 775746: Make dom::Touch inherit from this class.
+ */
+class SingleTouchData {
+ public:
+ // Construct a SingleTouchData from a Screen point.
+ // mLocalScreenPoint remains (0,0) unless it's set later.
+ SingleTouchData(int32_t aIdentifier, ScreenIntPoint aScreenPoint,
+ ScreenSize aRadius, float aRotationAngle, float aForce);
+
+ // Construct a SingleTouchData from a ParentLayer point.
+ // mScreenPoint remains (0,0) unless it's set later.
+ // Note: if APZ starts using the radius for anything, we should add a local
+ // version of that too, and have this constructor take it as a
+ // ParentLayerSize.
+ SingleTouchData(int32_t aIdentifier, ParentLayerPoint aLocalScreenPoint,
+ ScreenSize aRadius, float aRotationAngle, float aForce);
+
+ SingleTouchData();
+
+ already_AddRefed<dom::Touch> ToNewDOMTouch() const;
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+
+ // Historical data of this touch, which was coalesced into this event.
+ // Touch event coalescing can happen at the system level when the touch
+ // screen's sampling frequency is higher than the vsync rate, or when the
+ // UI thread is busy. When multiple "samples" of touch data are coalesced into
+ // one touch event, the touch event's regular position information is the
+ // information from the last sample. And the previous, "coalesced-away"
+ // samples are stored in mHistoricalData.
+
+ struct HistoricalTouchData {
+ // The timestamp at which the information in this "sample" was originally
+ // sampled.
+ TimeStamp mTimeStamp;
+
+ // The touch data of this historical sample.
+ ScreenIntPoint mScreenPoint;
+ ParentLayerPoint mLocalScreenPoint;
+ ScreenSize mRadius;
+ float mRotationAngle = 0.0f;
+ float mForce = 0.0f;
+ };
+ CopyableTArray<HistoricalTouchData> mHistoricalData;
+
+ // A unique number assigned to each SingleTouchData within a MultiTouchInput
+ // so that they can be easily distinguished when handling a touch
+ // start/move/end.
+ int32_t mIdentifier;
+
+ // Point on the screen that the touch hit, in device pixels. They are
+ // coordinates on the screen.
+ ScreenIntPoint mScreenPoint;
+
+ // |mScreenPoint| transformed to the local coordinates of the APZC targeted
+ // by the hit. This is set and used by APZ.
+ ParentLayerPoint mLocalScreenPoint;
+
+ // Radius that the touch covers, i.e. if you're using your thumb it will
+ // probably be larger than using your pinky, even with the same force.
+ // Radius can be different along x and y. For example, if you press down with
+ // your entire finger vertically, the y radius will be much larger than the x
+ // radius.
+ ScreenSize mRadius;
+
+ float mRotationAngle;
+
+ // How hard the screen is being pressed.
+ float mForce;
+
+ int32_t mTiltX = 0;
+ int32_t mTiltY = 0;
+ int32_t mTwist = 0;
+};
+
+/**
+ * Similar to WidgetTouchEvent, but for use off-main-thread. Also only stores a
+ * screen touch point instead of the many different coordinate spaces
+ * WidgetTouchEvent stores its touch point in. This includes a way to initialize
+ * itself from a WidgetTouchEvent by copying all relevant data over. Note that
+ * this copying from WidgetTouchEvent functionality can only be used on the main
+ * thread.
+ *
+ * Stores an array of SingleTouchData.
+ */
+class MultiTouchInput : public InputData {
+ public:
+ // clang-format off
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ MultiTouchType, (
+ MULTITOUCH_START,
+ MULTITOUCH_MOVE,
+ MULTITOUCH_END,
+ MULTITOUCH_CANCEL
+ ));
+ // clang-format on
+
+ MultiTouchInput(MultiTouchType aType, uint32_t aTime, TimeStamp aTimeStamp,
+ Modifiers aModifiers);
+ MultiTouchInput();
+ MultiTouchInput(MultiTouchInput&&) = default;
+ MultiTouchInput(const MultiTouchInput&) = default;
+ explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent);
+
+ MultiTouchInput& operator=(MultiTouchInput&&) = default;
+ MultiTouchInput& operator=(const MultiTouchInput&) = default;
+
+ void Translate(const ScreenPoint& aTranslation);
+
+ WidgetTouchEvent ToWidgetEvent(
+ nsIWidget* aWidget,
+ uint16_t aInputSource =
+ /* MouseEvent_Binding::MOZ_SOURCE_TOUCH = */ 5) const;
+
+ // Return the index into mTouches of the SingleTouchData with the given
+ // identifier, or -1 if there is no such SingleTouchData.
+ int32_t IndexOfTouch(int32_t aTouchIdentifier);
+
+ bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ MultiTouchType mType;
+ CopyableTArray<SingleTouchData> mTouches;
+ // The screen offset of the root widget. This can be changing along with
+ // the touch interaction, so we sstore it in the event.
+ ExternalPoint mScreenOffset;
+ bool mHandledByAPZ;
+ // These button fields match to the corresponding fields in
+ // WidgetMouseEventBase, except mButton defaults to -1 to follow PointerEvent.
+ int16_t mButton = eNotPressed;
+ int16_t mButtons = 0;
+};
+
+class MouseInput : public InputData {
+ protected:
+ friend mozilla::layers::APZInputBridgeChild;
+ friend mozilla::layers::PAPZInputBridgeParent;
+
+ MouseInput();
+
+ public:
+ // clang-format off
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ MouseType, (
+ MOUSE_NONE,
+ MOUSE_MOVE,
+ MOUSE_DOWN,
+ MOUSE_UP,
+ MOUSE_DRAG_START,
+ MOUSE_DRAG_END,
+ MOUSE_WIDGET_ENTER,
+ MOUSE_WIDGET_EXIT,
+ MOUSE_HITTEST,
+ MOUSE_EXPLORE_BY_TOUCH
+ ));
+
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ ButtonType, (
+ PRIMARY_BUTTON,
+ MIDDLE_BUTTON,
+ SECONDARY_BUTTON,
+ NONE
+ ));
+ // clang-format on
+
+ MouseInput(MouseType aType, ButtonType aButtonType, uint16_t aInputSource,
+ int16_t aButtons, const ScreenPoint& aPoint, TimeStamp aTimeStamp,
+ Modifiers aModifiers);
+ explicit MouseInput(const WidgetMouseEventBase& aMouseEvent);
+
+ bool IsLeftButton() const;
+
+ bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
+ WidgetMouseEvent ToWidgetEvent(nsIWidget* aWidget) const;
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ MouseType mType;
+ ButtonType mButtonType;
+ uint16_t mInputSource;
+ int16_t mButtons;
+ ScreenPoint mOrigin;
+ ParentLayerPoint mLocalOrigin;
+ bool mHandledByAPZ;
+ /**
+ * If click event should not be fired in the content after the "mousedown"
+ * event or following "mouseup", set to true.
+ */
+ bool mPreventClickEvent;
+};
+
+/**
+ * Encapsulation class for pan events, can be used off-main-thread.
+ * These events are currently only used for scrolling on desktop.
+ */
+class PanGestureInput : public InputData {
+ friend struct IPC::ParamTraits<PanGestureInput>;
+
+ protected:
+ friend mozilla::layers::APZInputBridgeChild;
+ friend mozilla::layers::PAPZInputBridgeParent;
+
+ PanGestureInput();
+
+ public:
+ // clang-format off
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ PanGestureType, (
+ // MayStart: Dispatched before any actual panning has occurred but when a
+ // pan gesture is probably about to start, for example when the user
+ // starts touching the touchpad. Should interrupt any ongoing APZ
+ // animation and can be used to trigger scrollability indicators (e.g.
+ // flashing overlay scrollbars).
+ PANGESTURE_MAYSTART,
+
+ // Cancelled: Dispatched after MayStart when no pan gesture is going to
+ // happen after all, for example when the user lifts their fingers from a
+ // touchpad without having done any scrolling.
+ PANGESTURE_CANCELLED,
+
+ // Start: A pan gesture is starting.
+ // For devices that do not support the MayStart event type, this event can
+ // be used to interrupt ongoing APZ animations.
+ PANGESTURE_START,
+
+ // Pan: The actual pan motion by mPanDisplacement.
+ PANGESTURE_PAN,
+
+ // End: The pan gesture has ended, for example because the user has lifted
+ // their fingers from a touchpad after scrolling.
+ // Any potential momentum events fire after this event.
+ PANGESTURE_END,
+
+ // The following momentum event types are used in order to control the pan
+ // momentum animation. Using these instead of our own animation ensures
+ // that the animation curve is OS native and that the animation stops
+ // reliably if it is cancelled by the user.
+
+ // MomentumStart: Dispatched between the End event of the actual
+ // user-controlled pan, and the first MomentumPan event of the momentum
+ // animation.
+ PANGESTURE_MOMENTUMSTART,
+
+ // MomentumPan: The actual momentum motion by mPanDisplacement.
+ PANGESTURE_MOMENTUMPAN,
+
+ // MomentumEnd: The momentum animation has ended, for example because the
+ // momentum velocity has gone below the stopping threshold, or because the
+ // user has stopped the animation by putting their fingers on a touchpad.
+ PANGESTURE_MOMENTUMEND,
+
+ // Interrupted:: A pan gesture started being handled by an APZC but
+ // subsequent pan events might have been consumed by other operations
+ // which haven't been handled by the APZC (e.g. full zoom).
+ PANGESTURE_INTERRUPTED
+ ));
+
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ PanDeltaType, (
+ // There are three kinds of scroll delta modes in Gecko: "page", "line"
+ // and "pixel". Touchpad pan gestures only support "page" and "pixel".
+ //
+ // NOTE: PANDELTA_PAGE currently replicates Gtk behavior
+ // (see AsyncPanZoomController::OnPan).
+ PANDELTA_PAGE,
+ PANDELTA_PIXEL
+ ));
+ // clang-format on
+
+ PanGestureInput(PanGestureType aType, TimeStamp aTimeStamp,
+ const ScreenPoint& aPanStartPoint,
+ const ScreenPoint& aPanDisplacement, Modifiers aModifiers);
+
+ enum class IsEligibleForSwipe : bool { No, Yes };
+ PanGestureInput(PanGestureType aType, TimeStamp aTimeStamp,
+ const ScreenPoint& aPanStartPoint,
+ const ScreenPoint& aPanDisplacement, Modifiers aModifiers,
+ IsEligibleForSwipe aIsEligibleForSwipe);
+
+ void SetLineOrPageDeltas(int32_t aLineOrPageDeltaX,
+ int32_t aLineOrPageDeltaY);
+
+ bool IsMomentum() const;
+
+ WidgetWheelEvent ToWidgetEvent(nsIWidget* aWidget) const;
+
+ bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
+
+ ScreenPoint UserMultipliedPanDisplacement() const;
+ ParentLayerPoint UserMultipliedLocalPanDisplacement() const;
+
+ void SetHandledByAPZ(bool aHandled) { mHandledByAPZ = aHandled; }
+ void SetOverscrollBehaviorAllowsSwipe(bool aAllows) {
+ mOverscrollBehaviorAllowsSwipe = aAllows;
+ }
+ void SetSimulateMomentum(bool aSimulate) { mSimulateMomentum = aSimulate; }
+ void SetIsNoLineOrPageDelta(bool aIsNoLineOrPageDelta) {
+ mIsNoLineOrPageDelta = aIsNoLineOrPageDelta;
+ }
+
+ // Returns true if this pan gesture event is elligible for browser swipe
+ // gesture considering the overscroll-behavior property of the target
+ // scroll container.
+ bool AllowsSwipe() const {
+ MOZ_ASSERT(mHandledByAPZ);
+ return mMayTriggerSwipe && mOverscrollBehaviorAllowsSwipe;
+ }
+
+ // Similar to above AllowsSwipe() but this doesn't care the
+ // overscroll-behavior property, this function should be only used for cases
+ // where APZ isn't involved.
+ bool MayTriggerSwipe() const { return mMayTriggerSwipe; }
+ bool RequiresContentResponseIfCannotScrollHorizontallyInStartDirection();
+
+ static gfx::IntPoint GetIntegerDeltaForEvent(bool aIsStart, float x, float y);
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ PanGestureType mType;
+ ScreenPoint mPanStartPoint;
+
+ // The delta. This can be non-zero on any type of event.
+ ScreenPoint mPanDisplacement;
+
+ // Versions of |mPanStartPoint| and |mPanDisplacement| in the local
+ // coordinates of the APZC receiving the pan. These are set and used by APZ.
+ ParentLayerPoint mLocalPanStartPoint;
+ ParentLayerPoint mLocalPanDisplacement;
+
+ // See lineOrPageDeltaX/Y on WidgetWheelEvent.
+ int32_t mLineOrPageDeltaX;
+ int32_t mLineOrPageDeltaY;
+
+ // User-set delta multipliers.
+ double mUserDeltaMultiplierX;
+ double mUserDeltaMultiplierY;
+
+ PanDeltaType mDeltaType = PANDELTA_PIXEL;
+
+ bool mHandledByAPZ : 1;
+
+ // This is used by APZ to communicate to widget code whether the
+ // overscroll-behavior of the scroll frame handling this swipe allows
+ // non-local overscroll behaviors in the horizontal direction (such as
+ // swipe navigation).
+ bool mOverscrollBehaviorAllowsSwipe : 1;
+
+ // true if APZ should do a fling animation after this pan ends, like
+ // it would with touchscreens. (For platforms that don't emit momentum
+ // events.)
+ bool mSimulateMomentum : 1;
+
+ // true if the creator of this object does not set the mLineOrPageDeltaX/Y
+ // fields and when/if WidgetWheelEvent's are generated from this object wants
+ // the corresponding mLineOrPageDeltaX/Y fields in the WidgetWheelEvent to be
+ // automatically calculated (upon event dispatch by the EventStateManager
+ // code).
+ bool mIsNoLineOrPageDelta : 1;
+
+ private:
+ // If this is true, and this event started a new input block that couldn't
+ // find a scrollable target which is scrollable in the horizontal component
+ // of the scroll start direction, then this input block needs to be put on
+ // hold until a content response has arrived, even if the block has a
+ // confirmed target.
+ // This is used by events that can result in a swipe instead of a scroll.
+ bool mMayTriggerSwipe : 1;
+ void SetMayTriggerSwipe(bool aValue) { mMayTriggerSwipe = aValue; }
+};
+
+/**
+ * Encapsulation class for pinch events. In general, these will be generated by
+ * a gesture listener by looking at SingleTouchData/MultiTouchInput instances
+ * and determining whether or not the user was trying to do a gesture.
+ */
+class PinchGestureInput : public InputData {
+ protected:
+ friend mozilla::layers::APZInputBridgeChild;
+ friend mozilla::layers::PAPZInputBridgeParent;
+
+ PinchGestureInput();
+
+ public:
+ // clang-format off
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ PinchGestureType, (
+ PINCHGESTURE_START,
+ PINCHGESTURE_SCALE,
+ // The FINGERLIFTED state is used when a touch-based pinch gesture is
+ // terminated by lifting one of the two fingers. The position of the
+ // finger that's still down is populated as the focus point.
+ PINCHGESTURE_FINGERLIFTED,
+ // The END state is used when the pinch gesture is completely terminated.
+ // In this state, the focus point should not be relied upon for having
+ // meaningful data.
+ PINCHGESTURE_END
+ ));
+
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ PinchGestureSource, (
+ UNKNOWN, // Default initialization value. Should never actually be used.
+ TOUCH, // From two-finger pinch gesture
+ ONE_TOUCH, // From one-finger pinch gesture
+ TRACKPAD, // From trackpad pinch gesture
+ MOUSEWHEEL // Synthesized from modifier+mousewheel
+
+ // If adding more items here, increase n_values for the
+ // APZ_ZOOM_PINCHSOURCE Telemetry metric.
+ ));
+ // clang-format on
+
+ // Construct a pinch gesture from a Screen point.
+ PinchGestureInput(PinchGestureType aType, PinchGestureSource aSource,
+ TimeStamp aTimeStamp, const ExternalPoint& aScreenOffset,
+ const ScreenPoint& aFocusPoint, ScreenCoord aCurrentSpan,
+ ScreenCoord aPreviousSpan, Modifiers aModifiers);
+
+ bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
+
+ WidgetWheelEvent ToWidgetEvent(nsIWidget* aWidget) const;
+
+ double ComputeDeltaY(nsIWidget* aWidget) const;
+
+ // Set mLineOrPageDeltaY based on ComputeDeltaY().
+ // Return false if the caller should drop this event to ensure
+ // that preventDefault() is respected. (More specifically, this will be
+ // true for event types other than PINCHGESTURE_END if the computed
+ // mLineOrPageDeltaY is zero. In such cases, the resulting DOMMouseScroll
+ // event will not be dispatched, which is a problem if the page is relying
+ // on DOMMouseScroll to prevent browser zooming).
+ // Note that even if the function returns false, the delta from the event
+ // is accumulated and available to be sent in a later event.
+ bool SetLineOrPageDeltaY(nsIWidget* aWidget);
+
+ static gfx::IntPoint GetIntegerDeltaForEvent(bool aIsStart, float x, float y);
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ PinchGestureType mType;
+
+ // Some indication of the input device that generated this pinch gesture.
+ PinchGestureSource mSource;
+
+ // Center point of the pinch gesture. That is, if there are two fingers on the
+ // screen, it is their midpoint. In the case of more than two fingers, the
+ // point is implementation-specific, but can for example be the midpoint
+ // between the very first and very last touch. This is in device pixels and
+ // are the coordinates on the screen of this midpoint.
+ // For PINCHGESTURE_END events, this may hold the last known focus point or
+ // just be empty; in any case for END events it should not be relied upon.
+ // For PINCHGESTURE_FINGERLIFTED events, this holds the point of the finger
+ // that is still down.
+ ScreenPoint mFocusPoint;
+
+ // The screen offset of the root widget. This can be changing along with
+ // the touch interaction, so we sstore it in the event.
+ ExternalPoint mScreenOffset;
+
+ // |mFocusPoint| transformed to the local coordinates of the APZC targeted
+ // by the hit. This is set and used by APZ.
+ ParentLayerPoint mLocalFocusPoint;
+
+ // The distance between the touches responsible for the pinch gesture.
+ ScreenCoord mCurrentSpan;
+
+ // The previous |mCurrentSpan| in the PinchGestureInput preceding this one.
+ // This is only really relevant during a PINCHGESTURE_SCALE because when it is
+ // of this type then there must have been a history of spans.
+ ScreenCoord mPreviousSpan;
+
+ // We accumulate (via GetIntegerDeltaForEvent) the deltaY that would be
+ // computed by ToWidgetEvent, and then whenever we get a whole integer
+ // value we put it in mLineOrPageDeltaY. Since we only ever use deltaY we
+ // don't need a mLineOrPageDeltaX. This field is used to dispatch legacy mouse
+ // events which are only dispatched when the corresponding field on
+ // WidgetWheelEvent is non-zero.
+ int32_t mLineOrPageDeltaY;
+
+ bool mHandledByAPZ;
+};
+
+/**
+ * Encapsulation class for tap events. In general, these will be generated by
+ * a gesture listener by looking at SingleTouchData/MultiTouchInput instances
+ * and determining whether or not the user was trying to do a gesture.
+ */
+class TapGestureInput : public InputData {
+ protected:
+ friend mozilla::layers::APZInputBridgeChild;
+ friend mozilla::layers::PAPZInputBridgeParent;
+
+ TapGestureInput();
+
+ public:
+ // clang-format off
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ TapGestureType, (
+ TAPGESTURE_LONG,
+ TAPGESTURE_LONG_UP,
+ TAPGESTURE_UP,
+ TAPGESTURE_CONFIRMED,
+ TAPGESTURE_DOUBLE,
+ TAPGESTURE_SECOND, // See GeckoContentController::TapType::eSecondTap
+ TAPGESTURE_CANCEL
+ ));
+ // clang-format on
+
+ // Construct a tap gesture from a Screen point.
+ // mLocalPoint remains (0,0) unless it's set later.
+ TapGestureInput(TapGestureType aType, TimeStamp aTimeStamp,
+ const ScreenIntPoint& aPoint, Modifiers aModifiers);
+
+ // Construct a tap gesture from a ParentLayer point.
+ // mPoint remains (0,0) unless it's set later.
+ TapGestureInput(TapGestureType aType, TimeStamp aTimeStamp,
+ const ParentLayerPoint& aLocalPoint, Modifiers aModifiers);
+
+ bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
+
+ WidgetSimpleGestureEvent ToWidgetEvent(nsIWidget* aWidget) const;
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ TapGestureType mType;
+
+ // The location of the tap in screen pixels.
+ ScreenIntPoint mPoint;
+
+ // The location of the tap in the local coordinates of the APZC receiving it.
+ // This is set and used by APZ.
+ ParentLayerPoint mLocalPoint;
+};
+
+// Encapsulation class for scroll-wheel events. These are generated by mice
+// with physical scroll wheels, and on Windows by most touchpads when using
+// scroll gestures.
+class ScrollWheelInput : public InputData {
+ protected:
+ friend mozilla::layers::APZInputBridgeChild;
+ friend mozilla::layers::PAPZInputBridgeParent;
+
+ typedef mozilla::layers::APZWheelAction APZWheelAction;
+
+ ScrollWheelInput();
+
+ public:
+ // clang-format off
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ ScrollDeltaType, (
+ // There are three kinds of scroll delta modes in Gecko: "page", "line"
+ // and "pixel".
+ SCROLLDELTA_LINE,
+ SCROLLDELTA_PAGE,
+ SCROLLDELTA_PIXEL
+ ));
+
+ MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
+ ScrollMode, (
+ SCROLLMODE_INSTANT,
+ SCROLLMODE_SMOOTH
+ )
+ );
+ // clang-format on
+
+ ScrollWheelInput(TimeStamp aTimeStamp, Modifiers aModifiers,
+ ScrollMode aScrollMode, ScrollDeltaType aDeltaType,
+ const ScreenPoint& aOrigin, double aDeltaX, double aDeltaY,
+ bool aAllowToOverrideSystemScrollSpeed,
+ WheelDeltaAdjustmentStrategy aWheelDeltaAdjustmentStrategy);
+ explicit ScrollWheelInput(const WidgetWheelEvent& aEvent);
+
+ static ScrollDeltaType DeltaTypeForDeltaMode(uint32_t aDeltaMode);
+ static uint32_t DeltaModeForDeltaType(ScrollDeltaType aDeltaType);
+ static mozilla::ScrollUnit ScrollUnitForDeltaType(ScrollDeltaType aDeltaType);
+
+ WidgetWheelEvent ToWidgetEvent(nsIWidget* aWidget) const;
+ bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
+
+ bool IsCustomizedByUserPrefs() const;
+
+ // The following two functions are for auto-dir scrolling. For detailed
+ // information on auto-dir, @see mozilla::WheelDeltaAdjustmentStrategy
+ bool IsAutoDir(bool aForce = false) const {
+ if (aForce) {
+ return true;
+ }
+
+ switch (mWheelDeltaAdjustmentStrategy) {
+ case WheelDeltaAdjustmentStrategy::eAutoDir:
+ case WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour:
+ return true;
+ default:
+ // Prevent compilation errors generated by -Werror=switch
+ break;
+ }
+ return false;
+ }
+ // Indicates which element this scroll honours if it's an auto-dir scroll.
+ // If true, honour the root element; otherwise, honour the currently scrolling
+ // target.
+ // Note that if IsAutoDir() returns false, then this function also returns
+ // false, but false in this case is meaningless as IsAutoDir() indicates it's
+ // not an auto-dir scroll.
+ // For detailed information on auto-dir,
+ // @see mozilla::WheelDeltaAdjustmentStrategy
+ bool HonoursRoot(bool aForce = false) const {
+ return WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour ==
+ mWheelDeltaAdjustmentStrategy ||
+ aForce;
+ }
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+ ScrollDeltaType mDeltaType;
+ ScrollMode mScrollMode;
+ ScreenPoint mOrigin;
+
+ bool mHandledByAPZ;
+
+ // Deltas are in units corresponding to the delta type. For line deltas, they
+ // are the number of line units to scroll. The number of device pixels for a
+ // horizontal and vertical line unit are in FrameMetrics::mLineScrollAmount.
+ // For pixel deltas, these values are in ScreenCoords.
+ //
+ // The horizontal (X) delta is > 0 for scrolling right and < 0 for scrolling
+ // left. The vertical (Y) delta is < 0 for scrolling up and > 0 for
+ // scrolling down.
+ double mDeltaX;
+ double mDeltaY;
+
+ // The number of scroll wheel ticks.
+ double mWheelTicksX = 0.0;
+ double mWheelTicksY = 0.0;
+
+ // The location of the scroll in local coordinates. This is set and used by
+ // APZ.
+ ParentLayerPoint mLocalOrigin;
+
+ // See lineOrPageDeltaX/Y on WidgetWheelEvent.
+ int32_t mLineOrPageDeltaX;
+ int32_t mLineOrPageDeltaY;
+
+ // Indicates the order in which this event was added to a transaction. The
+ // first event is 1; if not a member of a transaction, this is 0.
+ uint32_t mScrollSeriesNumber;
+
+ // User-set delta multipliers.
+ double mUserDeltaMultiplierX;
+ double mUserDeltaMultiplierY;
+
+ bool mMayHaveMomentum;
+ bool mIsMomentum;
+ bool mAllowToOverrideSystemScrollSpeed;
+
+ // Sometimes a wheel event input's wheel delta should be adjusted. This member
+ // specifies how to adjust the wheel delta.
+ WheelDeltaAdjustmentStrategy mWheelDeltaAdjustmentStrategy;
+
+ APZWheelAction mAPZAction;
+};
+
+class KeyboardInput : public InputData {
+ public:
+ typedef mozilla::layers::KeyboardScrollAction KeyboardScrollAction;
+
+ // Note that if you change the first member in this enum(I.e. KEY_DOWN) to one
+ // other member, don't forget to update the minimum value in
+ // ContiguousEnumSerializer for KeyboardEventType in widget/nsGUIEventIPC
+ // accordingly.
+ enum KeyboardEventType {
+ KEY_DOWN,
+ KEY_PRESS,
+ KEY_UP,
+ // Any other key event such as eAccessKeyNotFound
+ KEY_OTHER,
+
+ // Used as an upper bound for ContiguousEnumSerializer
+ KEY_SENTINEL,
+ };
+
+ explicit KeyboardInput(const WidgetKeyboardEvent& aEvent);
+
+ // Warning, this class is serialized and sent over IPC. Any change to its
+ // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
+
+ KeyboardEventType mType;
+ uint32_t mKeyCode;
+ uint32_t mCharCode;
+ CopyableTArray<ShortcutKeyCandidate> mShortcutCandidates;
+
+ bool mHandledByAPZ;
+
+ // The scroll action to perform on a layer for this keyboard input. This is
+ // only used in APZ and is NOT serialized over IPC.
+ KeyboardScrollAction mAction;
+
+ protected:
+ friend mozilla::layers::APZInputBridgeChild;
+ friend mozilla::layers::PAPZInputBridgeParent;
+
+ KeyboardInput();
+};
+
+} // namespace mozilla
+
+#endif // InputData_h__