gecko-dev/widget/InputData.h
2019-01-31 16:46:10 +00:00

680 lines
24 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 "nsIScrollableFrame.h"
#include "nsPoint.h"
#include "nsTArray.h"
#include "Units.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/APZUtils.h"
#include "mozilla/layers/KeyboardScrollAction.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;
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
// 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;
};
/**
* 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(const MultiTouchInput& aOther);
explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent);
void Translate(const ScreenPoint& aTranslation);
WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) 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;
nsTArray<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;
};
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
));
MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
ButtonType, (
LEFT_BUTTON,
MIDDLE_BUTTON,
RIGHT_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 ToWidgetMouseEvent(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;
};
/**
* 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 {
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
));
// clang-format on
PanGestureInput(PanGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
const ScreenPoint& aPanStartPoint,
const ScreenPoint& aPanDisplacement, Modifiers aModifiers);
bool IsMomentum() const;
WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
ScreenPoint UserMultipliedPanDisplacement() const;
ParentLayerPoint UserMultipliedLocalPanDisplacement() const;
// 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;
bool mHandledByAPZ;
// true if this is a PANGESTURE_END event that will be followed by a
// PANGESTURE_MOMENTUMSTART event.
bool mFollowedByMomentum;
// 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 mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection;
// This is used by APZ to communicate to the macOS 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;
// XXX: If adding any more bools, switch to using bitfields instead.
};
/**
* 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,
PINCHGESTURE_END
));
// clang-format on
// Construct a pinch gesture from a Screen point.
PinchGestureInput(PinchGestureType aType, uint32_t aTime,
TimeStamp aTimeStamp, const ExternalPoint& aScreenOffset,
const ScreenPoint& aFocusPoint, ScreenCoord aCurrentSpan,
ScreenCoord aPreviousSpan, Modifiers aModifiers);
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
PinchGestureType mType;
// 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 instead will hold the coordinates of
// the remaining finger, if there is one. If there isn't one then it will
// store |BothFingersLifted()|.
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;
// A special value for mFocusPoint used in PINCHGESTURE_END events to
// indicate that both fingers have been lifted. If only one finger has
// been lifted, the coordinates of the remaining finger are expected to
// be stored in mFocusPoint.
// For pinch events that were not triggered by touch gestures, the
// value of mFocusPoint in a PINCHGESTURE_END event is always expected
// to be this value.
// For convenience, we allow retrieving this value in any coordinate system.
// Since it's a special value, no conversion is needed.
template <typename Units = ParentLayerPixel>
static gfx::PointTyped<Units> BothFingersLifted() {
return gfx::PointTyped<Units>{-1, -1};
}
};
/**
* 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);
// 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 nsIScrollableFrame::ScrollUnit ScrollUnitForDeltaType(
ScrollDeltaType aDeltaType);
WidgetWheelEvent ToWidgetWheelEvent(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() const {
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() const {
return WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour ==
mWheelDeltaAdjustmentStrategy;
}
// 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 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 eKeyDownOnPlugin
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;
nsTArray<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__