Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/MouseEvents.h
Line
Count
Source (jump to first uncovered line)
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 mozilla_MouseEvents_h__
7
#define mozilla_MouseEvents_h__
8
9
#include <stdint.h>
10
11
#include "mozilla/BasicEvents.h"
12
#include "mozilla/MathAlgorithms.h"
13
#include "mozilla/dom/DataTransfer.h"
14
#include "nsCOMPtr.h"
15
16
namespace mozilla {
17
18
namespace dom {
19
  class PBrowserParent;
20
  class PBrowserChild;
21
} // namespace dom
22
23
class WidgetPointerEvent;
24
class WidgetPointerEventHolder final
25
{
26
public:
27
  nsTArray<WidgetPointerEvent> mEvents;
28
  NS_INLINE_DECL_REFCOUNTING(WidgetPointerEventHolder)
29
30
private:
31
0
  virtual ~WidgetPointerEventHolder() {}
32
};
33
34
/******************************************************************************
35
 * mozilla::WidgetPointerHelper
36
 ******************************************************************************/
37
38
class WidgetPointerHelper
39
{
40
public:
41
  uint32_t pointerId;
42
  uint32_t tiltX;
43
  uint32_t tiltY;
44
  uint32_t twist;
45
  float tangentialPressure;
46
  bool convertToPointer;
47
  RefPtr<WidgetPointerEventHolder> mCoalescedWidgetEvents;
48
49
  WidgetPointerHelper()
50
    : pointerId(0)
51
    , tiltX(0)
52
    , tiltY(0)
53
    , twist(0)
54
    , tangentialPressure(0)
55
    , convertToPointer(true)
56
0
  {
57
0
  }
58
59
  WidgetPointerHelper(uint32_t aPointerId, uint32_t aTiltX, uint32_t aTiltY,
60
                      uint32_t aTwist = 0, float aTangentialPressure = 0)
61
    : pointerId(aPointerId)
62
    , tiltX(aTiltX)
63
    , tiltY(aTiltY)
64
    , twist(aTwist)
65
    , tangentialPressure(aTangentialPressure)
66
    , convertToPointer(true)
67
0
  {
68
0
  }
69
70
  explicit WidgetPointerHelper(const WidgetPointerHelper& aHelper)
71
    : pointerId(aHelper.pointerId)
72
    , tiltX(aHelper.tiltX)
73
    , tiltY(aHelper.tiltY)
74
    , twist(aHelper.twist)
75
    , tangentialPressure(aHelper.tangentialPressure)
76
    , convertToPointer(aHelper.convertToPointer)
77
    , mCoalescedWidgetEvents(aHelper.mCoalescedWidgetEvents)
78
0
  {
79
0
  }
80
81
  void AssignPointerHelperData(const WidgetPointerHelper& aEvent,
82
                               bool aCopyCoalescedEvents = false)
83
0
  {
84
0
    pointerId = aEvent.pointerId;
85
0
    tiltX = aEvent.tiltX;
86
0
    tiltY = aEvent.tiltY;
87
0
    twist = aEvent.twist;
88
0
    tangentialPressure = aEvent.tangentialPressure;
89
0
    convertToPointer = aEvent.convertToPointer;
90
0
    if (aCopyCoalescedEvents) {
91
0
      mCoalescedWidgetEvents = aEvent.mCoalescedWidgetEvents;
92
0
    }
93
0
  }
94
};
95
96
/******************************************************************************
97
 * mozilla::WidgetMouseEventBase
98
 ******************************************************************************/
99
100
class WidgetMouseEventBase : public WidgetInputEvent
101
{
102
private:
103
  friend class dom::PBrowserParent;
104
  friend class dom::PBrowserChild;
105
106
protected:
107
  WidgetMouseEventBase()
108
    : button(0)
109
    , buttons(0)
110
    , pressure(0)
111
    , hitCluster(false)
112
    // Including MouseEventBinding.h here leads to an include loop, so
113
    // we have to hardcode MouseEvent_Binding::MOZ_SOURCE_MOUSE.
114
    , inputSource(/* MouseEvent_Binding::MOZ_SOURCE_MOUSE = */ 1)
115
0
  {
116
0
  }
117
118
  WidgetMouseEventBase(bool aIsTrusted, EventMessage aMessage,
119
                       nsIWidget* aWidget, EventClassID aEventClassID)
120
    : WidgetInputEvent(aIsTrusted, aMessage, aWidget, aEventClassID)
121
    , button(0)
122
    , buttons(0)
123
    , pressure(0)
124
    , hitCluster(false)
125
    // Including MouseEventBinding.h here leads to an include loop, so
126
    // we have to hardcode MouseEvent_Binding::MOZ_SOURCE_MOUSE.
127
    , inputSource(/* MouseEvent_Binding::MOZ_SOURCE_MOUSE = */ 1)
128
0
 {
129
0
 }
130
131
public:
132
0
  virtual WidgetMouseEventBase* AsMouseEventBase() override { return this; }
133
134
  virtual WidgetEvent* Duplicate() const override
135
0
  {
136
0
    MOZ_CRASH("WidgetMouseEventBase must not be most-subclass");
137
0
  }
138
139
  enum buttonType
140
  {
141
    eNoButton     = -1,
142
    eLeftButton   = 0,
143
    eMiddleButton = 1,
144
    eRightButton  = 2
145
  };
146
  // Pressed button ID of mousedown or mouseup event.
147
  // This is set only when pressing a button causes the event.
148
  int16_t button;
149
150
  enum buttonsFlag {
151
    eNoButtonFlag     = 0x00,
152
    eLeftButtonFlag   = 0x01,
153
    eRightButtonFlag  = 0x02,
154
    eMiddleButtonFlag = 0x04,
155
    // typicall, "back" button being left side of 5-button
156
    // mice, see "buttons" attribute document of DOM3 Events.
157
    e4thButtonFlag    = 0x08,
158
    // typicall, "forward" button being right side of 5-button
159
    // mice, see "buttons" attribute document of DOM3 Events.
160
    e5thButtonFlag    = 0x10
161
  };
162
163
  // Flags of all pressed buttons at the event fired.
164
  // This is set at any mouse event, don't be confused with |button|.
165
  int16_t buttons;
166
167
  // Finger or touch pressure of event. It ranges between 0.0 and 1.0.
168
  float pressure;
169
  // Touch near a cluster of links (true)
170
  bool hitCluster;
171
172
  // Possible values a in MouseEvent
173
  uint16_t inputSource;
174
175
  // ID of the canvas HitRegion
176
  nsString region;
177
178
0
  bool IsLeftButtonPressed() const { return !!(buttons & eLeftButtonFlag); }
179
0
  bool IsRightButtonPressed() const { return !!(buttons & eRightButtonFlag); }
180
0
  bool IsMiddleButtonPressed() const { return !!(buttons & eMiddleButtonFlag); }
181
0
  bool Is4thButtonPressed() const { return !!(buttons & e4thButtonFlag); }
182
0
  bool Is5thButtonPressed() const { return !!(buttons & e5thButtonFlag); }
183
184
  void AssignMouseEventBaseData(const WidgetMouseEventBase& aEvent,
185
                                bool aCopyTargets)
186
0
  {
187
0
    AssignInputEventData(aEvent, aCopyTargets);
188
0
189
0
    button = aEvent.button;
190
0
    buttons = aEvent.buttons;
191
0
    pressure = aEvent.pressure;
192
0
    hitCluster = aEvent.hitCluster;
193
0
    inputSource = aEvent.inputSource;
194
0
  }
195
196
  /**
197
   * Returns true if left click event.
198
   */
199
  bool IsLeftClickEvent() const
200
0
  {
201
0
    return mMessage == eMouseClick && button == eLeftButton;
202
0
  }
203
};
204
205
/******************************************************************************
206
 * mozilla::WidgetMouseEvent
207
 ******************************************************************************/
208
209
class WidgetMouseEvent : public WidgetMouseEventBase
210
                       , public WidgetPointerHelper
211
{
212
private:
213
  friend class dom::PBrowserParent;
214
  friend class dom::PBrowserChild;
215
216
public:
217
  typedef bool ReasonType;
218
  enum Reason : ReasonType
219
  {
220
    eReal,
221
    eSynthesized
222
  };
223
224
  typedef bool ContextMenuTriggerType;
225
  enum ContextMenuTrigger : ContextMenuTriggerType
226
  {
227
    eNormal,
228
    eContextMenuKey
229
  };
230
231
  typedef bool ExitFromType;
232
  enum ExitFrom : ExitFromType
233
  {
234
    eChild,
235
    eTopLevel
236
  };
237
238
protected:
239
  WidgetMouseEvent()
240
    : mReason(eReal)
241
    , mContextMenuTrigger(eNormal)
242
    , mExitFrom(eChild)
243
    , mIgnoreRootScrollFrame(false)
244
    , mClickCount(0)
245
0
  {
246
0
  }
247
248
  WidgetMouseEvent(bool aIsTrusted,
249
                   EventMessage aMessage,
250
                   nsIWidget* aWidget,
251
                   EventClassID aEventClassID,
252
                   Reason aReason)
253
    : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, aEventClassID)
254
    , mReason(aReason)
255
    , mContextMenuTrigger(eNormal)
256
    , mExitFrom(eChild)
257
    , mIgnoreRootScrollFrame(false)
258
    , mClickCount(0)
259
0
  {
260
0
  }
261
262
public:
263
0
  virtual WidgetMouseEvent* AsMouseEvent() override { return this; }
264
265
  WidgetMouseEvent(bool aIsTrusted,
266
                   EventMessage aMessage,
267
                   nsIWidget* aWidget,
268
                   Reason aReason,
269
                   ContextMenuTrigger aContextMenuTrigger = eNormal)
270
    : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eMouseEventClass)
271
    , mReason(aReason)
272
    , mContextMenuTrigger(aContextMenuTrigger)
273
    , mExitFrom(eChild)
274
    , mIgnoreRootScrollFrame(false)
275
    , mClickCount(0)
276
0
  {
277
0
    if (aMessage == eContextMenu) {
278
0
      button = (mContextMenuTrigger == eNormal) ? eRightButton : eLeftButton;
279
0
    }
280
0
  }
281
282
#ifdef DEBUG
283
  virtual ~WidgetMouseEvent()
284
  {
285
    NS_WARNING_ASSERTION(
286
      mMessage != eContextMenu ||
287
      button == ((mContextMenuTrigger == eNormal) ? eRightButton : eLeftButton),
288
      "Wrong button set to eContextMenu event?");
289
  }
290
#endif
291
292
  virtual WidgetEvent* Duplicate() const override
293
0
  {
294
0
    MOZ_ASSERT(mClass == eMouseEventClass,
295
0
               "Duplicate() must be overridden by sub class");
296
0
    // Not copying widget, it is a weak reference.
297
0
    WidgetMouseEvent* result =
298
0
      new WidgetMouseEvent(false, mMessage, nullptr,
299
0
                           mReason, mContextMenuTrigger);
300
0
    result->AssignMouseEventData(*this, true);
301
0
    result->mFlags = mFlags;
302
0
    return result;
303
0
  }
304
305
  // mReason indicates the reason why the event is fired:
306
  // - Representing mouse operation.
307
  // - Synthesized for emulating mousemove event when the content under the
308
  //   mouse cursor is scrolled.
309
  Reason mReason;
310
311
  // mContextMenuTrigger is valid only when mMessage is eContextMenu.
312
  // This indicates if the context menu event is caused by context menu key or
313
  // other reasons (typically, a click of right mouse button).
314
  ContextMenuTrigger mContextMenuTrigger;
315
316
  // mExitFrom is valid only when mMessage is eMouseExitFromWidget.
317
  // This indicates if the mouse cursor exits from a top level widget or
318
  // a child widget.
319
  ExitFrom mExitFrom;
320
321
  // Whether the event should ignore scroll frame bounds during dispatch.
322
  bool mIgnoreRootScrollFrame;
323
324
  // mClickCount may be non-zero value when mMessage is eMouseDown, eMouseUp,
325
  // eMouseClick or eMouseDoubleClick. The number is count of mouse clicks.
326
  // Otherwise, this must be 0.
327
  uint32_t mClickCount;
328
329
  void AssignMouseEventData(const WidgetMouseEvent& aEvent, bool aCopyTargets)
330
0
  {
331
0
    AssignMouseEventBaseData(aEvent, aCopyTargets);
332
0
    AssignPointerHelperData(aEvent, /* aCopyCoalescedEvents */ true);
333
0
334
0
    mIgnoreRootScrollFrame = aEvent.mIgnoreRootScrollFrame;
335
0
    mClickCount = aEvent.mClickCount;
336
0
  }
337
338
  /**
339
   * Returns true if the event is a context menu event caused by key.
340
   */
341
  bool IsContextMenuKeyEvent() const
342
0
  {
343
0
    return mMessage == eContextMenu && mContextMenuTrigger == eContextMenuKey;
344
0
  }
345
346
  /**
347
   * Returns true if the event is a real mouse event.  Otherwise, i.e., it's
348
   * a synthesized event by scroll or something, returns false.
349
   */
350
  bool IsReal() const
351
0
  {
352
0
    return mReason == eReal;
353
0
  }
354
};
355
356
/******************************************************************************
357
 * mozilla::WidgetDragEvent
358
 ******************************************************************************/
359
360
class WidgetDragEvent : public WidgetMouseEvent
361
{
362
private:
363
  friend class mozilla::dom::PBrowserParent;
364
  friend class mozilla::dom::PBrowserChild;
365
protected:
366
  WidgetDragEvent()
367
    : mUserCancelled(false)
368
    , mDefaultPreventedOnContent(false)
369
0
  {
370
0
  }
371
public:
372
0
  virtual WidgetDragEvent* AsDragEvent() override { return this; }
373
374
  WidgetDragEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
375
    : WidgetMouseEvent(aIsTrusted, aMessage, aWidget, eDragEventClass, eReal)
376
    , mUserCancelled(false)
377
    , mDefaultPreventedOnContent(false)
378
0
  {
379
0
  }
380
381
  virtual WidgetEvent* Duplicate() const override
382
0
  {
383
0
    MOZ_ASSERT(mClass == eDragEventClass,
384
0
               "Duplicate() must be overridden by sub class");
385
0
    // Not copying widget, it is a weak reference.
386
0
    WidgetDragEvent* result = new WidgetDragEvent(false, mMessage, nullptr);
387
0
    result->AssignDragEventData(*this, true);
388
0
    result->mFlags = mFlags;
389
0
    return result;
390
0
  }
391
392
  // The dragging data.
393
  nsCOMPtr<dom::DataTransfer> mDataTransfer;
394
395
  // If this is true, user has cancelled the drag operation.
396
  bool mUserCancelled;
397
  // If this is true, the drag event's preventDefault() is called on content.
398
  bool mDefaultPreventedOnContent;
399
400
  // XXX Not tested by test_assign_event_data.html
401
  void AssignDragEventData(const WidgetDragEvent& aEvent, bool aCopyTargets)
402
0
  {
403
0
    AssignMouseEventData(aEvent, aCopyTargets);
404
0
405
0
    mDataTransfer = aEvent.mDataTransfer;
406
0
    // XXX mUserCancelled isn't copied, is this intentionally?
407
0
    mUserCancelled = false;
408
0
    mDefaultPreventedOnContent = aEvent.mDefaultPreventedOnContent;
409
0
  }
410
};
411
412
/******************************************************************************
413
 * mozilla::WidgetMouseScrollEvent
414
 *
415
 * This is used for legacy DOM mouse scroll events, i.e.,
416
 * DOMMouseScroll and MozMousePixelScroll event.  These events are NOT hanbled
417
 * by ESM even if widget dispatches them.  Use new WidgetWheelEvent instead.
418
 ******************************************************************************/
419
420
class WidgetMouseScrollEvent : public WidgetMouseEventBase
421
{
422
private:
423
  WidgetMouseScrollEvent()
424
    : mDelta(0)
425
    , mIsHorizontal(false)
426
0
  {
427
0
  }
428
429
public:
430
  virtual WidgetMouseScrollEvent* AsMouseScrollEvent() override
431
0
  {
432
0
    return this;
433
0
  }
434
435
  WidgetMouseScrollEvent(bool aIsTrusted, EventMessage aMessage,
436
                         nsIWidget* aWidget)
437
    : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget,
438
                           eMouseScrollEventClass)
439
    , mDelta(0)
440
    , mIsHorizontal(false)
441
0
  {
442
0
  }
443
444
  virtual WidgetEvent* Duplicate() const override
445
0
  {
446
0
    MOZ_ASSERT(mClass == eMouseScrollEventClass,
447
0
               "Duplicate() must be overridden by sub class");
448
0
    // Not copying widget, it is a weak reference.
449
0
    WidgetMouseScrollEvent* result =
450
0
      new WidgetMouseScrollEvent(false, mMessage, nullptr);
451
0
    result->AssignMouseScrollEventData(*this, true);
452
0
    result->mFlags = mFlags;
453
0
    return result;
454
0
  }
455
456
  // The delta value of mouse scroll event.
457
  // If the event message is eLegacyMouseLineOrPageScroll, the value indicates
458
  // scroll amount in lines.  However, if the value is
459
  // UIEvent::SCROLL_PAGE_UP or UIEvent::SCROLL_PAGE_DOWN, the
460
  // value inducates one page scroll.  If the event message is
461
  // eLegacyMousePixelScroll, the value indicates scroll amount in pixels.
462
  int32_t mDelta;
463
464
  // If this is true, it may cause to scroll horizontally.
465
  // Otherwise, vertically.
466
  bool mIsHorizontal;
467
468
  void AssignMouseScrollEventData(const WidgetMouseScrollEvent& aEvent,
469
                                  bool aCopyTargets)
470
0
  {
471
0
    AssignMouseEventBaseData(aEvent, aCopyTargets);
472
0
473
0
    mDelta = aEvent.mDelta;
474
0
    mIsHorizontal = aEvent.mIsHorizontal;
475
0
  }
476
};
477
478
/******************************************************************************
479
 * mozilla::WidgetWheelEvent
480
 ******************************************************************************/
481
482
class WidgetWheelEvent : public WidgetMouseEventBase
483
{
484
private:
485
  friend class mozilla::dom::PBrowserParent;
486
  friend class mozilla::dom::PBrowserChild;
487
488
  WidgetWheelEvent()
489
    : mDeltaX(0.0)
490
    , mDeltaY(0.0)
491
    , mDeltaZ(0.0)
492
    , mOverflowDeltaX(0.0)
493
    , mOverflowDeltaY(0.0)
494
    // Including WheelEventBinding.h here leads to an include loop, so
495
    // we have to hardcode WheelEvent_Binding::DOM_DELTA_PIXEL.
496
    , mDeltaMode(/* WheelEvent_Binding::DOM_DELTA_PIXEL = */ 0)
497
    , mLineOrPageDeltaX(0)
498
    , mLineOrPageDeltaY(0)
499
    , mScrollType(SCROLL_DEFAULT)
500
    , mCustomizedByUserPrefs(false)
501
    , mMayHaveMomentum(false)
502
    , mIsMomentum(false)
503
    , mIsNoLineOrPageDelta(false)
504
    , mViewPortIsOverscrolled(false)
505
    , mCanTriggerSwipe(false)
506
    , mAllowToOverrideSystemScrollSpeed(false)
507
    , mDeltaValuesHorizontalizedForDefaultHandler(false)
508
0
  {
509
0
  }
510
511
public:
512
0
  virtual WidgetWheelEvent* AsWheelEvent() override { return this; }
513
514
  WidgetWheelEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
515
    : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eWheelEventClass)
516
    , mDeltaX(0.0)
517
    , mDeltaY(0.0)
518
    , mDeltaZ(0.0)
519
    , mOverflowDeltaX(0.0)
520
    , mOverflowDeltaY(0.0)
521
    // Including WheelEventBinding.h here leads to an include loop, so
522
    // we have to hardcode WheelEvent_Binding::DOM_DELTA_PIXEL.
523
    , mDeltaMode(/* WheelEvent_Binding::DOM_DELTA_PIXEL = */ 0)
524
    , mLineOrPageDeltaX(0)
525
    , mLineOrPageDeltaY(0)
526
    , mScrollType(SCROLL_DEFAULT)
527
    , mCustomizedByUserPrefs(false)
528
    , mMayHaveMomentum(false)
529
    , mIsMomentum(false)
530
    , mIsNoLineOrPageDelta(false)
531
    , mViewPortIsOverscrolled(false)
532
    , mCanTriggerSwipe(false)
533
    , mAllowToOverrideSystemScrollSpeed(true)
534
    , mDeltaValuesHorizontalizedForDefaultHandler(false)
535
0
  {
536
0
  }
537
538
  virtual WidgetEvent* Duplicate() const override
539
0
  {
540
0
    MOZ_ASSERT(mClass == eWheelEventClass,
541
0
               "Duplicate() must be overridden by sub class");
542
0
    // Not copying widget, it is a weak reference.
543
0
    WidgetWheelEvent* result = new WidgetWheelEvent(false, mMessage, nullptr);
544
0
    result->AssignWheelEventData(*this, true);
545
0
    result->mFlags = mFlags;
546
0
    return result;
547
0
  }
548
549
  // On OS X, scroll gestures that start at the edge of the scrollable range
550
  // can result in a swipe gesture. For the first wheel event of such a
551
  // gesture, call TriggersSwipe() after the event has been processed
552
  // in order to find out whether a swipe should be started.
553
  bool TriggersSwipe() const
554
0
  {
555
0
    return mCanTriggerSwipe && mViewPortIsOverscrolled &&
556
0
           this->mOverflowDeltaX != 0.0;
557
0
  }
558
559
  // NOTE: mDeltaX, mDeltaY and mDeltaZ may be customized by
560
  //       mousewheel.*.delta_multiplier_* prefs which are applied by
561
  //       EventStateManager.  So, after widget dispatches this event,
562
  //       these delta values may have different values than before.
563
  double mDeltaX;
564
  double mDeltaY;
565
  double mDeltaZ;
566
567
  // overflowed delta values for scroll, these values are set by
568
  // EventStateManger.  If the default action of the wheel event isn't scroll,
569
  // these values are always zero.  Otherwise, remaining delta values which are
570
  // not used by scroll are set.
571
  // NOTE: mDeltaX, mDeltaY and mDeltaZ may be modified by EventStateManager.
572
  //       However, mOverflowDeltaX and mOverflowDeltaY indicate unused original
573
  //       delta values which are not applied the delta_multiplier prefs.
574
  //       So, if widget wanted to know the actual direction to be scrolled,
575
  //       it would need to check the mDeltaX and mDeltaY.
576
  double mOverflowDeltaX;
577
  double mOverflowDeltaY;
578
579
  // Should be one of WheelEvent_Binding::DOM_DELTA_*
580
  uint32_t mDeltaMode;
581
582
  // If widget sets mLineOrPageDelta, EventStateManager will dispatch
583
  // eLegacyMouseLineOrPageScroll event for compatibility.  Note that the delta
584
  // value means pages if the mDeltaMode is DOM_DELTA_PAGE, otherwise, lines.
585
  int32_t mLineOrPageDeltaX;
586
  int32_t mLineOrPageDeltaY;
587
588
  // When the default action for an wheel event is moving history or zooming,
589
  // need to chose a delta value for doing it.
590
  int32_t GetPreferredIntDelta()
591
0
  {
592
0
    if (!mLineOrPageDeltaX && !mLineOrPageDeltaY) {
593
0
      return 0;
594
0
    }
595
0
    if (mLineOrPageDeltaY && !mLineOrPageDeltaX) {
596
0
      return mLineOrPageDeltaY;
597
0
    }
598
0
    if (mLineOrPageDeltaX && !mLineOrPageDeltaY) {
599
0
      return mLineOrPageDeltaX;
600
0
    }
601
0
    if ((mLineOrPageDeltaX < 0 && mLineOrPageDeltaY > 0) ||
602
0
        (mLineOrPageDeltaX > 0 && mLineOrPageDeltaY < 0)) {
603
0
      return 0; // We cannot guess the answer in this case.
604
0
    }
605
0
    return (Abs(mLineOrPageDeltaX) > Abs(mLineOrPageDeltaY)) ?
606
0
             mLineOrPageDeltaX : mLineOrPageDeltaY;
607
0
  }
608
609
  // Scroll type
610
  // The default value is SCROLL_DEFAULT, which means EventStateManager will
611
  // select preferred scroll type automatically.
612
  enum ScrollType : uint8_t
613
  {
614
    SCROLL_DEFAULT,
615
    SCROLL_SYNCHRONOUSLY,
616
    SCROLL_ASYNCHRONOUSELY,
617
    SCROLL_SMOOTHLY
618
  };
619
  ScrollType mScrollType;
620
621
  // If the delta values are computed from prefs, this value is true.
622
  // Otherwise, i.e., they are computed from native events, false.
623
  bool mCustomizedByUserPrefs;
624
625
  // true if the momentum events directly tied to this event may follow it.
626
  bool mMayHaveMomentum;
627
  // true if the event is caused by momentum.
628
  bool mIsMomentum;
629
630
  // If device event handlers don't know when they should set mLineOrPageDeltaX
631
  // and mLineOrPageDeltaY, this is true.  Otherwise, false.
632
  // If mIsNoLineOrPageDelta is true, ESM will generate
633
  // eLegacyMouseLineOrPageScroll events when accumulated delta values reach
634
  // a line height.
635
  bool mIsNoLineOrPageDelta;
636
637
  // Whether or not the parent of the currently overscrolled frame is the
638
  // ViewPort. This is false in situations when an element on the page is being
639
  // overscrolled (such as a text field), but true when the 'page' is being
640
  // overscrolled.
641
  bool mViewPortIsOverscrolled;
642
643
  // The wheel event can trigger a swipe to start if it's overscrolling the
644
  // viewport.
645
  bool mCanTriggerSwipe;
646
647
  // If mAllowToOverrideSystemScrollSpeed is true, the scroll speed may be
648
  // overridden.  Otherwise, the scroll speed won't be overridden even if
649
  // it's enabled by the pref.
650
  bool mAllowToOverrideSystemScrollSpeed;
651
652
  // After the event's default action handler has adjusted its delta's values
653
  // for horizontalizing a vertical wheel scroll, this variable will be set to
654
  // true.
655
  bool mDeltaValuesHorizontalizedForDefaultHandler;
656
657
  void AssignWheelEventData(const WidgetWheelEvent& aEvent, bool aCopyTargets)
658
0
  {
659
0
    AssignMouseEventBaseData(aEvent, aCopyTargets);
660
0
661
0
    mDeltaX = aEvent.mDeltaX;
662
0
    mDeltaY = aEvent.mDeltaY;
663
0
    mDeltaZ = aEvent.mDeltaZ;
664
0
    mDeltaMode = aEvent.mDeltaMode;
665
0
    mCustomizedByUserPrefs = aEvent.mCustomizedByUserPrefs;
666
0
    mMayHaveMomentum = aEvent.mMayHaveMomentum;
667
0
    mIsMomentum = aEvent.mIsMomentum;
668
0
    mIsNoLineOrPageDelta = aEvent.mIsNoLineOrPageDelta;
669
0
    mLineOrPageDeltaX = aEvent.mLineOrPageDeltaX;
670
0
    mLineOrPageDeltaY = aEvent.mLineOrPageDeltaY;
671
0
    mScrollType = aEvent.mScrollType;
672
0
    mOverflowDeltaX = aEvent.mOverflowDeltaX;
673
0
    mOverflowDeltaY = aEvent.mOverflowDeltaY;
674
0
    mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled;
675
0
    mCanTriggerSwipe = aEvent.mCanTriggerSwipe;
676
0
    mAllowToOverrideSystemScrollSpeed =
677
0
      aEvent.mAllowToOverrideSystemScrollSpeed;
678
0
    mDeltaValuesHorizontalizedForDefaultHandler =
679
0
      aEvent.mDeltaValuesHorizontalizedForDefaultHandler;
680
0
  }
681
682
  // System scroll speed settings may be too slow at using Gecko.  In such
683
  // case, we should override the scroll speed computed with system settings.
684
  // Following methods return preferred delta values which are multiplied by
685
  // factors specified by prefs.  If system scroll speed shouldn't be
686
  // overridden (e.g., this feature is disabled by pref), they return raw
687
  // delta values.
688
  double OverriddenDeltaX() const;
689
  double OverriddenDeltaY() const;
690
691
  // Compute the overridden delta value.  This may be useful for suppressing
692
  // too fast scroll by system scroll speed overriding when widget sets
693
  // mAllowToOverrideSystemScrollSpeed.
694
  static double ComputeOverriddenDelta(double aDelta, bool aIsForVertical);
695
696
private:
697
  static bool sInitialized;
698
  static bool sIsSystemScrollSpeedOverrideEnabled;
699
  static int32_t sOverrideFactorX;
700
  static int32_t sOverrideFactorY;
701
  static void Initialize();
702
};
703
704
/******************************************************************************
705
 * mozilla::WidgetPointerEvent
706
 ******************************************************************************/
707
708
class WidgetPointerEvent : public WidgetMouseEvent
709
{
710
  friend class mozilla::dom::PBrowserParent;
711
  friend class mozilla::dom::PBrowserChild;
712
713
  WidgetPointerEvent()
714
    : mWidth(1)
715
    , mHeight(1)
716
    , mIsPrimary(true)
717
0
  {
718
0
  }
719
720
public:
721
0
  virtual WidgetPointerEvent* AsPointerEvent() override { return this; }
722
723
  WidgetPointerEvent(bool aIsTrusted, EventMessage aMsg, nsIWidget* w)
724
    : WidgetMouseEvent(aIsTrusted, aMsg, w, ePointerEventClass, eReal)
725
    , mWidth(1)
726
    , mHeight(1)
727
    , mIsPrimary(true)
728
0
  {
729
0
  }
730
731
  explicit WidgetPointerEvent(const WidgetMouseEvent& aEvent)
732
    : WidgetMouseEvent(aEvent)
733
    , mWidth(1)
734
    , mHeight(1)
735
    , mIsPrimary(true)
736
0
  {
737
0
    mClass = ePointerEventClass;
738
0
  }
739
740
  virtual WidgetEvent* Duplicate() const override
741
0
  {
742
0
    MOZ_ASSERT(mClass == ePointerEventClass,
743
0
               "Duplicate() must be overridden by sub class");
744
0
    // Not copying widget, it is a weak reference.
745
0
    WidgetPointerEvent* result =
746
0
      new WidgetPointerEvent(false, mMessage, nullptr);
747
0
    result->AssignPointerEventData(*this, true);
748
0
    result->mFlags = mFlags;
749
0
    return result;
750
0
  }
751
752
  uint32_t mWidth;
753
  uint32_t mHeight;
754
  bool mIsPrimary;
755
756
  // XXX Not tested by test_assign_event_data.html
757
  void AssignPointerEventData(const WidgetPointerEvent& aEvent,
758
                              bool aCopyTargets)
759
0
  {
760
0
    AssignMouseEventData(aEvent, aCopyTargets);
761
0
762
0
    mWidth = aEvent.mWidth;
763
0
    mHeight = aEvent.mHeight;
764
0
    mIsPrimary = aEvent.mIsPrimary;
765
0
  }
766
};
767
768
} // namespace mozilla
769
770
#endif // mozilla_MouseEvents_h__