1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef InputData_h__
7 #define InputData_h__
8 
9 #include "nsDebug.h"
10 #include "nsIDOMWheelEvent.h"
11 #include "nsIScrollableFrame.h"
12 #include "nsPoint.h"
13 #include "nsTArray.h"
14 #include "Units.h"
15 #include "mozilla/DefineEnum.h"
16 #include "mozilla/EventForwards.h"
17 #include "mozilla/TimeStamp.h"
18 #include "mozilla/gfx/MatrixFwd.h"
19 #include "mozilla/layers/KeyboardScrollAction.h"
20 
21 template <class E>
22 struct already_AddRefed;
23 class nsIWidget;
24 
25 namespace mozilla {
26 
27 namespace layers {
28 class PAPZCTreeManagerParent;
29 class APZCTreeManagerChild;
30 }  // namespace layers
31 
32 namespace dom {
33 class Touch;
34 }  // namespace dom
35 
36 // clang-format off
37 MOZ_DEFINE_ENUM(
38   InputType, (
39     MULTITOUCH_INPUT,
40     MOUSE_INPUT,
41     PANGESTURE_INPUT,
42     PINCHGESTURE_INPUT,
43     TAPGESTURE_INPUT,
44     SCROLLWHEEL_INPUT,
45     KEYBOARD_INPUT
46 ));
47 // clang-format on
48 
49 class MultiTouchInput;
50 class MouseInput;
51 class PanGestureInput;
52 class PinchGestureInput;
53 class TapGestureInput;
54 class ScrollWheelInput;
55 class KeyboardInput;
56 
57 // This looks unnecessary now, but as we add more and more classes that derive
58 // from InputType (eventually probably almost as many as *Events.h has), it
59 // will be more and more clear what's going on with a macro that shortens the
60 // definition of the RTTI functions.
61 #define INPUTDATA_AS_CHILD_TYPE(type, enumID)                       \
62   const type& As##type() const {                                    \
63     MOZ_ASSERT(mInputType == enumID, "Invalid cast of InputData."); \
64     return (const type&)*this;                                      \
65   }                                                                 \
66   type& As##type() {                                                \
67     MOZ_ASSERT(mInputType == enumID, "Invalid cast of InputData."); \
68     return (type&)*this;                                            \
69   }
70 
71 /** Base input data class. Should never be instantiated. */
72 class InputData {
73  public:
74   // Warning, this class is serialized and sent over IPC. Any change to its
75   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
76   InputType mInputType;
77   // Time in milliseconds that this data is relevant to. This only really
78   // matters when this data is used as an event. We use uint32_t instead of
79   // TimeStamp because it is easier to convert from WidgetInputEvent. The time
80   // is platform-specific but it in the case of B2G and Fennec it is since
81   // startup.
82   uint32_t mTime;
83   // Set in parallel to mTime until we determine it is safe to drop
84   // platform-specific event times (see bug 77992).
85   TimeStamp mTimeStamp;
86   // The sequence number of the last potentially focus changing event handled
87   // by APZ. This is used to track when that event has been processed by
88   // content, and focus can be reconfirmed for async keyboard scrolling.
89   uint64_t mFocusSequenceNumber;
90 
91   Modifiers modifiers;
92 
93   INPUTDATA_AS_CHILD_TYPE(MultiTouchInput, MULTITOUCH_INPUT)
94   INPUTDATA_AS_CHILD_TYPE(MouseInput, MOUSE_INPUT)
95   INPUTDATA_AS_CHILD_TYPE(PanGestureInput, PANGESTURE_INPUT)
96   INPUTDATA_AS_CHILD_TYPE(PinchGestureInput, PINCHGESTURE_INPUT)
97   INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT)
98   INPUTDATA_AS_CHILD_TYPE(ScrollWheelInput, SCROLLWHEEL_INPUT)
99   INPUTDATA_AS_CHILD_TYPE(KeyboardInput, KEYBOARD_INPUT)
100 
101   virtual ~InputData();
102   explicit InputData(InputType aInputType);
103 
104  protected:
105   InputData(InputType aInputType, uint32_t aTime, TimeStamp aTimeStamp,
106             Modifiers aModifiers);
107 };
108 
109 /**
110  * Data container for a single touch input. Similar to dom::Touch, but used in
111  * off-main-thread situations. This is more for just storing touch data, whereas
112  * dom::Touch is more useful for dispatching through the DOM (which can only
113  * happen on the main thread). dom::Touch also bears the problem of storing
114  * pointers to nsIWidget instances which can only be used on the main thread,
115  * so if instead we used dom::Touch and ever set these pointers
116  * off-main-thread, Bad Things Can Happen(tm).
117  *
118  * Note that this doesn't inherit from InputData because this itself is not an
119  * event. It is only a container/struct that should have any number of instances
120  * within a MultiTouchInput.
121  *
122  * fixme/bug 775746: Make dom::Touch inherit from this class.
123  */
124 class SingleTouchData {
125  public:
126   // Construct a SingleTouchData from a Screen point.
127   // mLocalScreenPoint remains (0,0) unless it's set later.
128   SingleTouchData(int32_t aIdentifier, ScreenIntPoint aScreenPoint,
129                   ScreenSize aRadius, float aRotationAngle, float aForce);
130 
131   // Construct a SingleTouchData from a ParentLayer point.
132   // mScreenPoint remains (0,0) unless it's set later.
133   // Note: if APZ starts using the radius for anything, we should add a local
134   // version of that too, and have this constructor take it as a
135   // ParentLayerSize.
136   SingleTouchData(int32_t aIdentifier, ParentLayerPoint aLocalScreenPoint,
137                   ScreenSize aRadius, float aRotationAngle, float aForce);
138 
139   SingleTouchData();
140 
141   already_AddRefed<dom::Touch> ToNewDOMTouch() const;
142 
143   // Warning, this class is serialized and sent over IPC. Any change to its
144   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
145 
146   // A unique number assigned to each SingleTouchData within a MultiTouchInput
147   // so that they can be easily distinguished when handling a touch
148   // start/move/end.
149   int32_t mIdentifier;
150 
151   // Point on the screen that the touch hit, in device pixels. They are
152   // coordinates on the screen.
153   ScreenIntPoint mScreenPoint;
154 
155   // |mScreenPoint| transformed to the local coordinates of the APZC targeted
156   // by the hit. This is set and used by APZ.
157   ParentLayerPoint mLocalScreenPoint;
158 
159   // Radius that the touch covers, i.e. if you're using your thumb it will
160   // probably be larger than using your pinky, even with the same force.
161   // Radius can be different along x and y. For example, if you press down with
162   // your entire finger vertically, the y radius will be much larger than the x
163   // radius.
164   ScreenSize mRadius;
165 
166   float mRotationAngle;
167 
168   // How hard the screen is being pressed.
169   float mForce;
170 };
171 
172 /**
173  * Similar to WidgetTouchEvent, but for use off-main-thread. Also only stores a
174  * screen touch point instead of the many different coordinate spaces
175  * WidgetTouchEvent stores its touch point in. This includes a way to initialize
176  * itself from a WidgetTouchEvent by copying all relevant data over. Note that
177  * this copying from WidgetTouchEvent functionality can only be used on the main
178  * thread.
179  *
180  * Stores an array of SingleTouchData.
181  */
182 class MultiTouchInput : public InputData {
183  public:
184   // clang-format off
185   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
186     MultiTouchType, (
187       MULTITOUCH_START,
188       MULTITOUCH_MOVE,
189       MULTITOUCH_END,
190       MULTITOUCH_CANCEL
191   ));
192   // clang-format on
193 
194   MultiTouchInput(MultiTouchType aType, uint32_t aTime, TimeStamp aTimeStamp,
195                   Modifiers aModifiers);
196   MultiTouchInput();
197   MultiTouchInput(const MultiTouchInput& aOther);
198   explicit MultiTouchInput(const WidgetTouchEvent& aTouchEvent);
199   // This conversion from WidgetMouseEvent to MultiTouchInput is needed because
200   // on the B2G emulator we can only receive mouse events, but we need to be
201   // able to pan correctly. To do this, we convert the events into a format that
202   // the panning code can handle. This code is very limited and only supports
203   // SingleTouchData. It also sends garbage for the identifier, radius, force
204   // and rotation angle.
205   explicit MultiTouchInput(const WidgetMouseEvent& aMouseEvent);
206   void Translate(const ScreenPoint& aTranslation);
207 
208   WidgetTouchEvent ToWidgetTouchEvent(nsIWidget* aWidget) const;
209   WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
210 
211   // Return the index into mTouches of the SingleTouchData with the given
212   // identifier, or -1 if there is no such SingleTouchData.
213   int32_t IndexOfTouch(int32_t aTouchIdentifier);
214 
215   bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
216 
217   // Warning, this class is serialized and sent over IPC. Any change to its
218   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
219   MultiTouchType mType;
220   nsTArray<SingleTouchData> mTouches;
221   bool mHandledByAPZ;
222 };
223 
224 class MouseInput : public InputData {
225  protected:
226   friend mozilla::layers::PAPZCTreeManagerParent;
227   friend mozilla::layers::APZCTreeManagerChild;
228 
229   MouseInput();
230 
231  public:
232   // clang-format off
233   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
234     MouseType, (
235       MOUSE_NONE,
236       MOUSE_MOVE,
237       MOUSE_DOWN,
238       MOUSE_UP,
239       MOUSE_DRAG_START,
240       MOUSE_DRAG_END,
241       MOUSE_WIDGET_ENTER,
242       MOUSE_WIDGET_EXIT,
243       MOUSE_HITTEST
244   ));
245 
246   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
247     ButtonType, (
248       LEFT_BUTTON,
249       MIDDLE_BUTTON,
250       RIGHT_BUTTON,
251       NONE
252   ));
253   // clang-format on
254 
255   MouseInput(MouseType aType, ButtonType aButtonType, uint16_t aInputSource,
256              int16_t aButtons, const ScreenPoint& aPoint, uint32_t aTime,
257              TimeStamp aTimeStamp, Modifiers aModifiers);
258   explicit MouseInput(const WidgetMouseEventBase& aMouseEvent);
259 
260   bool IsLeftButton() const;
261 
262   bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
263   WidgetMouseEvent ToWidgetMouseEvent(nsIWidget* aWidget) const;
264 
265   // Warning, this class is serialized and sent over IPC. Any change to its
266   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
267   MouseType mType;
268   ButtonType mButtonType;
269   uint16_t mInputSource;
270   int16_t mButtons;
271   ScreenPoint mOrigin;
272   ParentLayerPoint mLocalOrigin;
273   bool mHandledByAPZ;
274 };
275 
276 /**
277  * Encapsulation class for pan events, can be used off-main-thread.
278  * These events are currently only used for scrolling on desktop.
279  */
280 class PanGestureInput : public InputData {
281  protected:
282   friend mozilla::layers::PAPZCTreeManagerParent;
283   friend mozilla::layers::APZCTreeManagerChild;
284 
285   PanGestureInput();
286 
287  public:
288   // clang-format off
289   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
290     PanGestureType, (
291       // MayStart: Dispatched before any actual panning has occurred but when a
292       // pan gesture is probably about to start, for example when the user
293       // starts touching the touchpad. Should interrupt any ongoing APZ
294       // animation and can be used to trigger scrollability indicators (e.g.
295       // flashing overlay scrollbars).
296       PANGESTURE_MAYSTART,
297 
298       // Cancelled: Dispatched after MayStart when no pan gesture is going to
299       // happen after all, for example when the user lifts their fingers from a
300       // touchpad without having done any scrolling.
301       PANGESTURE_CANCELLED,
302 
303       // Start: A pan gesture is starting.
304       // For devices that do not support the MayStart event type, this event can
305       // be used to interrupt ongoing APZ animations.
306       PANGESTURE_START,
307 
308       // Pan: The actual pan motion by mPanDisplacement.
309       PANGESTURE_PAN,
310 
311       // End: The pan gesture has ended, for example because the user has lifted
312       // their fingers from a touchpad after scrolling.
313       // Any potential momentum events fire after this event.
314       PANGESTURE_END,
315 
316       // The following momentum event types are used in order to control the pan
317       // momentum animation. Using these instead of our own animation ensures
318       // that the animation curve is OS native and that the animation stops
319       // reliably if it is cancelled by the user.
320 
321       // MomentumStart: Dispatched between the End event of the actual
322       // user-controlled pan, and the first MomentumPan event of the momentum
323       // animation.
324       PANGESTURE_MOMENTUMSTART,
325 
326       // MomentumPan: The actual momentum motion by mPanDisplacement.
327       PANGESTURE_MOMENTUMPAN,
328 
329       // MomentumEnd: The momentum animation has ended, for example because the
330       // momentum velocity has gone below the stopping threshold, or because the
331       // user has stopped the animation by putting their fingers on a touchpad.
332       PANGESTURE_MOMENTUMEND
333   ));
334   // clang-format on
335 
336   PanGestureInput(PanGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
337                   const ScreenPoint& aPanStartPoint,
338                   const ScreenPoint& aPanDisplacement, Modifiers aModifiers);
339 
340   bool IsMomentum() const;
341 
342   WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
343 
344   bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
345 
346   ScreenPoint UserMultipliedPanDisplacement() const;
347   ParentLayerPoint UserMultipliedLocalPanDisplacement() const;
348 
349   // Warning, this class is serialized and sent over IPC. Any change to its
350   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
351   PanGestureType mType;
352   ScreenPoint mPanStartPoint;
353 
354   // The delta. This can be non-zero on any type of event.
355   ScreenPoint mPanDisplacement;
356 
357   // Versions of |mPanStartPoint| and |mPanDisplacement| in the local
358   // coordinates of the APZC receiving the pan. These are set and used by APZ.
359   ParentLayerPoint mLocalPanStartPoint;
360   ParentLayerPoint mLocalPanDisplacement;
361 
362   // See lineOrPageDeltaX/Y on WidgetWheelEvent.
363   int32_t mLineOrPageDeltaX;
364   int32_t mLineOrPageDeltaY;
365 
366   // User-set delta multipliers.
367   double mUserDeltaMultiplierX;
368   double mUserDeltaMultiplierY;
369 
370   bool mHandledByAPZ;
371 
372   // true if this is a PANGESTURE_END event that will be followed by a
373   // PANGESTURE_MOMENTUMSTART event.
374   bool mFollowedByMomentum;
375 
376   // If this is true, and this event started a new input block that couldn't
377   // find a scrollable target which is scrollable in the horizontal component
378   // of the scroll start direction, then this input block needs to be put on
379   // hold until a content response has arrived, even if the block has a
380   // confirmed target.
381   // This is used by events that can result in a swipe instead of a scroll.
382   bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection;
383 
384   // This is used by APZ to communicate to the macOS widget code whether
385   // the overscroll-behavior of the scroll frame handling this swipe allows
386   // non-local overscroll behaviors in the horizontal direction (such as
387   // swipe navigation).
388   bool mOverscrollBehaviorAllowsSwipe;
389 
390   // XXX: If adding any more bools, switch to using bitfields instead.
391 };
392 
393 /**
394  * Encapsulation class for pinch events. In general, these will be generated by
395  * a gesture listener by looking at SingleTouchData/MultiTouchInput instances
396  * and determining whether or not the user was trying to do a gesture.
397  */
398 class PinchGestureInput : public InputData {
399  protected:
400   friend mozilla::layers::PAPZCTreeManagerParent;
401   friend mozilla::layers::APZCTreeManagerChild;
402 
403   PinchGestureInput();
404 
405  public:
406   // clang-format off
407   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
408     PinchGestureType, (
409       PINCHGESTURE_START,
410       PINCHGESTURE_SCALE,
411       PINCHGESTURE_END
412   ));
413   // clang-format on
414 
415   // Construct a pinch gesture from a ParentLayer point.
416   // mFocusPoint remains (0,0) unless it's set later.
417   PinchGestureInput(PinchGestureType aType, uint32_t aTime,
418                     TimeStamp aTimeStamp,
419                     const ParentLayerPoint& aLocalFocusPoint,
420                     ParentLayerCoord aCurrentSpan,
421                     ParentLayerCoord aPreviousSpan, Modifiers aModifiers);
422 
423   bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
424 
425   // Warning, this class is serialized and sent over IPC. Any change to its
426   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
427   PinchGestureType mType;
428 
429   // Center point of the pinch gesture. That is, if there are two fingers on the
430   // screen, it is their midpoint. In the case of more than two fingers, the
431   // point is implementation-specific, but can for example be the midpoint
432   // between the very first and very last touch. This is in device pixels and
433   // are the coordinates on the screen of this midpoint.
434   // For PINCHGESTURE_END events, this instead will hold the coordinates of
435   // the remaining finger, if there is one. If there isn't one then it will
436   // store -1, -1.
437   ScreenPoint mFocusPoint;
438 
439   // |mFocusPoint| transformed to the local coordinates of the APZC targeted
440   // by the hit. This is set and used by APZ.
441   ParentLayerPoint mLocalFocusPoint;
442 
443   // The distance between the touches responsible for the pinch gesture.
444   ParentLayerCoord mCurrentSpan;
445 
446   // The previous |mCurrentSpan| in the PinchGestureInput preceding this one.
447   // This is only really relevant during a PINCHGESTURE_SCALE because when it is
448   // of this type then there must have been a history of spans.
449   ParentLayerCoord mPreviousSpan;
450 };
451 
452 /**
453  * Encapsulation class for tap events. In general, these will be generated by
454  * a gesture listener by looking at SingleTouchData/MultiTouchInput instances
455  * and determining whether or not the user was trying to do a gesture.
456  */
457 class TapGestureInput : public InputData {
458  protected:
459   friend mozilla::layers::PAPZCTreeManagerParent;
460   friend mozilla::layers::APZCTreeManagerChild;
461 
462   TapGestureInput();
463 
464  public:
465   // clang-format off
466   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
467     TapGestureType, (
468       TAPGESTURE_LONG,
469       TAPGESTURE_LONG_UP,
470       TAPGESTURE_UP,
471       TAPGESTURE_CONFIRMED,
472       TAPGESTURE_DOUBLE,
473       TAPGESTURE_SECOND, // See GeckoContentController::TapType::eSecondTap
474       TAPGESTURE_CANCEL
475   ));
476   // clang-format on
477 
478   // Construct a tap gesture from a Screen point.
479   // mLocalPoint remains (0,0) unless it's set later.
480   TapGestureInput(TapGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
481                   const ScreenIntPoint& aPoint, Modifiers aModifiers);
482 
483   // Construct a tap gesture from a ParentLayer point.
484   // mPoint remains (0,0) unless it's set later.
485   TapGestureInput(TapGestureType aType, uint32_t aTime, TimeStamp aTimeStamp,
486                   const ParentLayerPoint& aLocalPoint, Modifiers aModifiers);
487 
488   bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
489 
490   // Warning, this class is serialized and sent over IPC. Any change to its
491   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
492   TapGestureType mType;
493 
494   // The location of the tap in screen pixels.
495   ScreenIntPoint mPoint;
496 
497   // The location of the tap in the local coordinates of the APZC receiving it.
498   // This is set and used by APZ.
499   ParentLayerPoint mLocalPoint;
500 };
501 
502 // Encapsulation class for scroll-wheel events. These are generated by mice
503 // with physical scroll wheels, and on Windows by most touchpads when using
504 // scroll gestures.
505 class ScrollWheelInput : public InputData {
506  protected:
507   friend mozilla::layers::PAPZCTreeManagerParent;
508   friend mozilla::layers::APZCTreeManagerChild;
509 
510   ScrollWheelInput();
511 
512  public:
513   // clang-format off
514   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
515     ScrollDeltaType, (
516       // There are three kinds of scroll delta modes in Gecko: "page", "line"
517       // and "pixel".
518       SCROLLDELTA_LINE,
519       SCROLLDELTA_PAGE,
520       SCROLLDELTA_PIXEL
521   ));
522 
523   MOZ_DEFINE_ENUM_AT_CLASS_SCOPE(
524     ScrollMode, (
525       SCROLLMODE_INSTANT,
526       SCROLLMODE_SMOOTH
527     )
528   );
529   // clang-format on
530 
531   ScrollWheelInput(uint32_t aTime, TimeStamp aTimeStamp, Modifiers aModifiers,
532                    ScrollMode aScrollMode, ScrollDeltaType aDeltaType,
533                    const ScreenPoint& aOrigin, double aDeltaX, double aDeltaY,
534                    bool aAllowToOverrideSystemScrollSpeed);
535   explicit ScrollWheelInput(const WidgetWheelEvent& aEvent);
536 
537   static ScrollDeltaType DeltaTypeForDeltaMode(uint32_t aDeltaMode);
538   static uint32_t DeltaModeForDeltaType(ScrollDeltaType aDeltaType);
539   static nsIScrollableFrame::ScrollUnit ScrollUnitForDeltaType(
540       ScrollDeltaType aDeltaType);
541 
542   WidgetWheelEvent ToWidgetWheelEvent(nsIWidget* aWidget) const;
543   bool TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform);
544 
545   bool IsCustomizedByUserPrefs() const;
546 
547   // Warning, this class is serialized and sent over IPC. Any change to its
548   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
549   ScrollDeltaType mDeltaType;
550   ScrollMode mScrollMode;
551   ScreenPoint mOrigin;
552 
553   bool mHandledByAPZ;
554 
555   // Deltas are in units corresponding to the delta type. For line deltas, they
556   // are the number of line units to scroll. The number of device pixels for a
557   // horizontal and vertical line unit are in FrameMetrics::mLineScrollAmount.
558   // For pixel deltas, these values are in ScreenCoords.
559   //
560   // The horizontal (X) delta is > 0 for scrolling right and < 0 for scrolling
561   // left. The vertical (Y) delta is < 0 for scrolling up and > 0 for
562   // scrolling down.
563   double mDeltaX;
564   double mDeltaY;
565 
566   // The location of the scroll in local coordinates. This is set and used by
567   // APZ.
568   ParentLayerPoint mLocalOrigin;
569 
570   // See lineOrPageDeltaX/Y on WidgetWheelEvent.
571   int32_t mLineOrPageDeltaX;
572   int32_t mLineOrPageDeltaY;
573 
574   // Indicates the order in which this event was added to a transaction. The
575   // first event is 1; if not a member of a transaction, this is 0.
576   uint32_t mScrollSeriesNumber;
577 
578   // User-set delta multipliers.
579   double mUserDeltaMultiplierX;
580   double mUserDeltaMultiplierY;
581 
582   bool mMayHaveMomentum;
583   bool mIsMomentum;
584   bool mAllowToOverrideSystemScrollSpeed;
585 };
586 
587 class KeyboardInput : public InputData {
588  public:
589   typedef mozilla::layers::KeyboardScrollAction KeyboardScrollAction;
590 
591   enum KeyboardEventType {
592     KEY_DOWN,
593     KEY_PRESS,
594     KEY_UP,
595     // Any other key event such as eKeyDownOnPlugin
596     KEY_OTHER,
597 
598     // Used as an upper bound for ContiguousEnumSerializer
599     KEY_SENTINEL,
600   };
601 
602   explicit KeyboardInput(const WidgetKeyboardEvent& aEvent);
603 
604   // Warning, this class is serialized and sent over IPC. Any change to its
605   // fields must be reflected in its ParamTraits<>, in nsGUIEventIPC.h
606 
607   KeyboardEventType mType;
608   uint32_t mKeyCode;
609   uint32_t mCharCode;
610   nsTArray<ShortcutKeyCandidate> mShortcutCandidates;
611 
612   bool mHandledByAPZ;
613 
614   // The scroll action to perform on a layer for this keyboard input. This is
615   // only used in APZ and is NOT serialized over IPC.
616   KeyboardScrollAction mAction;
617 
618  protected:
619   friend mozilla::layers::PAPZCTreeManagerParent;
620   friend mozilla::layers::APZCTreeManagerChild;
621 
622   KeyboardInput();
623 };
624 
625 }  // namespace mozilla
626 
627 #endif  // InputData_h__
628