mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
d32e0125e8
Differential Revision: https://phabricator.services.mozilla.com/D160437
837 lines
30 KiB
C++
837 lines
30 KiB
C++
/* -*- 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 in milliseconds that this data is relevant to. This only really
|
|
// matters when this data is used as an event. We use uint32_t instead of
|
|
// TimeStamp because it is easier to convert from WidgetInputEvent. The time
|
|
// is platform-specific but it in the case of B2G and Fennec it is since
|
|
// startup.
|
|
uint32_t mTime;
|
|
// Set in parallel to mTime until we determine it is safe to drop
|
|
// platform-specific event times (see bug 77992).
|
|
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, uint32_t aTime, 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;
|
|
|
|
uint32_t mTiltX = 0;
|
|
uint32_t mTiltY = 0;
|
|
uint32_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, uint32_t aTime,
|
|
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, uint32_t aTime, TimeStamp aTimeStamp,
|
|
const ScreenPoint& aPanStartPoint,
|
|
const ScreenPoint& aPanDisplacement, Modifiers aModifiers);
|
|
|
|
enum class IsEligibleForSwipe : bool { No, Yes };
|
|
PanGestureInput(PanGestureType aType, uint32_t aTime, 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,
|
|
uint32_t aTime, 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, uint32_t aTime, 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, uint32_t aTime, 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(uint32_t aTime, 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__
|