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/. */
6 #ifndef mozilla_MouseEvents_h__
7 #define mozilla_MouseEvents_h__
12 #include "mozilla/BasicEvents.h"
13 #include "mozilla/EventForwards.h"
14 #include "mozilla/MathAlgorithms.h"
15 #include "mozilla/dom/DataTransfer.h"
16 #include "mozilla/ipc/IPCForwards.h"
24 class PBrowserBridgeParent
;
27 class WidgetPointerEvent
;
28 } // namespace mozilla
31 class WidgetPointerEventHolder final
{
33 nsTArray
<WidgetPointerEvent
> mEvents
;
34 NS_INLINE_DECL_REFCOUNTING(WidgetPointerEventHolder
)
37 virtual ~WidgetPointerEventHolder() = default;
40 /******************************************************************************
41 * mozilla::WidgetPointerHelper
42 ******************************************************************************/
44 class WidgetPointerHelper
{
50 float tangentialPressure
;
51 bool convertToPointer
;
52 RefPtr
<WidgetPointerEventHolder
> mCoalescedWidgetEvents
;
59 tangentialPressure(0),
60 convertToPointer(true) {}
62 WidgetPointerHelper(uint32_t aPointerId
, uint32_t aTiltX
, uint32_t aTiltY
,
63 uint32_t aTwist
= 0, float aTangentialPressure
= 0)
64 : pointerId(aPointerId
),
68 tangentialPressure(aTangentialPressure
),
69 convertToPointer(true) {}
71 explicit WidgetPointerHelper(const WidgetPointerHelper
& aHelper
) = default;
73 constexpr static double kPi
=
77 3.14159265358979323846;
79 constexpr static double kHalfPi
=
83 1.57079632679489661923;
85 constexpr static double kDoublePi
= kPi
* 2;
87 constexpr static double GetDefaultAltitudeAngle() { return kHalfPi
; }
88 constexpr static double GetDefaultAzimuthAngle() { return 0.0; }
90 double ComputeAltitudeAngle() const {
91 return ComputeAltitudeAngle(tiltX
, tiltY
);
93 double ComputeAzimuthAngle() const {
94 return ComputeAzimuthAngle(tiltX
, tiltY
);
97 static double ComputeAltitudeAngle(int32_t aTiltX
, int32_t aTiltY
);
98 static double ComputeAzimuthAngle(int32_t aTiltX
, int32_t aTiltY
);
100 static double ComputeTiltX(double aAltitudeAngle
, double aAzimuthAngle
);
101 static double ComputeTiltY(double aAltitudeAngle
, double aAzimuthAngle
);
103 void AssignPointerHelperData(const WidgetPointerHelper
& aEvent
,
104 bool aCopyCoalescedEvents
= false) {
105 pointerId
= aEvent
.pointerId
;
106 tiltX
= aEvent
.tiltX
;
107 tiltY
= aEvent
.tiltY
;
108 twist
= aEvent
.twist
;
109 tangentialPressure
= aEvent
.tangentialPressure
;
110 convertToPointer
= aEvent
.convertToPointer
;
111 if (aCopyCoalescedEvents
) {
112 mCoalescedWidgetEvents
= aEvent
.mCoalescedWidgetEvents
;
117 static int32_t GetValidTiltValue(int32_t aTilt
);
118 static double GetValidAltitudeAngle(double aAltitudeAngle
);
119 static double GetValidAzimuthAngle(double aAzimuthAngle
);
122 /******************************************************************************
123 * mozilla::WidgetMouseEventBase
124 ******************************************************************************/
126 class WidgetMouseEventBase
: public WidgetInputEvent
{
128 friend class dom::PBrowserParent
;
129 friend class dom::PBrowserChild
;
130 friend class dom::PBrowserBridgeParent
;
131 ALLOW_DEPRECATED_READPARAM
134 WidgetMouseEventBase()
138 mInputSource(/* MouseEvent_Binding::MOZ_SOURCE_MOUSE = */ 1) {}
139 // Including MouseEventBinding.h here leads to an include loop, so
140 // we have to hardcode MouseEvent_Binding::MOZ_SOURCE_MOUSE.
142 WidgetMouseEventBase(bool aIsTrusted
, EventMessage aMessage
,
143 nsIWidget
* aWidget
, EventClassID aEventClassID
,
144 const WidgetEventTime
* aTime
= nullptr)
145 : WidgetInputEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
, aTime
),
149 mInputSource(/* MouseEvent_Binding::MOZ_SOURCE_MOUSE = */ 1) {}
150 // Including MouseEventBinding.h here leads to an include loop, so
151 // we have to hardcode MouseEvent_Binding::MOZ_SOURCE_MOUSE.
154 virtual WidgetMouseEventBase
* AsMouseEventBase() override
{ return this; }
156 virtual WidgetEvent
* Duplicate() const override
{
157 MOZ_CRASH("WidgetMouseEventBase must not be most-subclass");
160 // Finger or touch pressure of event. It ranges between 0.0 and 1.0.
163 // Pressed button ID of mousedown or mouseup event.
164 // This is set only when pressing a button causes the event.
167 // Flags of all pressed buttons at the event fired.
168 // This is set at any mouse event, don't be confused with |mButton|.
171 // Possible values a in MouseEvent
172 uint16_t mInputSource
;
174 bool IsLeftButtonPressed() const {
175 return !!(mButtons
& MouseButtonsFlag::ePrimaryFlag
);
177 bool IsRightButtonPressed() const {
178 return !!(mButtons
& MouseButtonsFlag::eSecondaryFlag
);
180 bool IsMiddleButtonPressed() const {
181 return !!(mButtons
& MouseButtonsFlag::eMiddleFlag
);
183 bool Is4thButtonPressed() const {
184 return !!(mButtons
& MouseButtonsFlag::e4thFlag
);
186 bool Is5thButtonPressed() const {
187 return !!(mButtons
& MouseButtonsFlag::e5thFlag
);
190 void AssignMouseEventBaseData(const WidgetMouseEventBase
& aEvent
,
192 AssignInputEventData(aEvent
, aCopyTargets
);
194 mButton
= aEvent
.mButton
;
195 mButtons
= aEvent
.mButtons
;
196 mPressure
= aEvent
.mPressure
;
197 mInputSource
= aEvent
.mInputSource
;
201 * Returns true if left click event.
203 bool IsLeftClickEvent() const {
204 return mMessage
== ePointerClick
&& mButton
== MouseButton::ePrimary
;
208 * Returns true if this event changes a button state to "pressed".
210 [[nodiscard
]] bool IsPressingButton() const {
211 MOZ_ASSERT(IsTrusted());
212 if (mClass
== eMouseEventClass
) {
213 return mMessage
== eMouseDown
;
215 if (mButton
== MouseButton::eNotPressed
) {
218 // If this is an ePointerDown event whose mButton is not "not pressed", this
219 // is a button pressing event.
220 if (mMessage
== ePointerDown
) {
223 // If 2 or more buttons are pressed at same time, they are sent with
224 // pointermove rather than pointerdown. Therefore, let's check whether
225 // mButtons contains the proper flag for the pressing button.
226 const bool buttonsContainButton
= !!(
227 mButtons
& MouseButtonsFlagToChange(static_cast<MouseButton
>(mButton
)));
228 return mMessage
== ePointerMove
&& buttonsContainButton
;
232 * Returns true if this event changes a button state to "released".
234 [[nodiscard
]] bool IsReleasingButton() const {
235 MOZ_ASSERT(IsTrusted());
236 if (mClass
== eMouseEventClass
) {
237 return mMessage
== eMouseUp
;
239 if (mButton
== MouseButton::eNotPressed
) {
242 // If this is an ePointerUp event whose mButton is not "not pressed", this
243 // is a button release event.
244 if (mMessage
== ePointerUp
) {
247 // If the releasing button is not the last button of pressing buttons, web
248 // apps notified by pointermove rather than pointerup. Therefore, let's
249 // check whether mButtons loses the proper flag for the releasing button.
250 const bool buttonsLoseTheButton
= !(
251 mButtons
& MouseButtonsFlagToChange(static_cast<MouseButton
>(mButton
)));
252 return mMessage
== ePointerMove
&& buttonsLoseTheButton
;
256 * Returns true if the input source supports hover state like a mouse.
258 [[nodiscard
]] bool InputSourceSupportsHover() const;
261 * Returns true if corresponding DOM event should use fractional coordinates.
263 [[nodiscard
]] bool DOMEventShouldUseFractionalCoords() const;
266 /******************************************************************************
267 * mozilla::WidgetMouseEvent
268 ******************************************************************************/
270 class WidgetMouseEvent
: public WidgetMouseEventBase
,
271 public WidgetPointerHelper
{
273 friend class dom::PBrowserParent
;
274 friend class dom::PBrowserChild
;
275 friend class dom::PBrowserBridgeParent
;
276 ALLOW_DEPRECATED_READPARAM
279 typedef bool ReasonType
;
280 enum Reason
: ReasonType
{ eReal
, eSynthesized
};
282 typedef uint8_t ContextMenuTriggerType
;
283 enum ContextMenuTrigger
: ContextMenuTriggerType
{
289 typedef uint8_t ExitFromType
;
290 enum ExitFrom
: ExitFromType
{
294 ePuppetParentToPuppetChild
298 WidgetMouseEvent() = default;
300 WidgetMouseEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
301 EventClassID aEventClassID
, Reason aReason
,
302 ContextMenuTrigger aContextMenuTrigger
,
303 const WidgetEventTime
* aTime
= nullptr)
304 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, aEventClassID
,
307 mContextMenuTrigger(aContextMenuTrigger
) {}
310 void AssertContextMenuEventButtonConsistency() const;
314 virtual WidgetMouseEvent
* AsMouseEvent() override
{ return this; }
316 WidgetMouseEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
317 Reason aReason
= eReal
,
318 ContextMenuTrigger aContextMenuTrigger
= eNormal
,
319 const WidgetEventTime
* aTime
= nullptr)
320 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, eMouseEventClass
,
323 mContextMenuTrigger(aContextMenuTrigger
) {
324 MOZ_ASSERT_IF(aIsTrusted
, !IsPointerEventMessage(mMessage
));
325 if (aMessage
== eContextMenu
) {
326 mButton
= (mContextMenuTrigger
== eNormal
) ? MouseButton::eSecondary
327 : MouseButton::ePrimary
;
332 virtual ~WidgetMouseEvent() { AssertContextMenuEventButtonConsistency(); }
335 virtual WidgetEvent
* Duplicate() const override
{
336 MOZ_ASSERT(mClass
== eMouseEventClass
,
337 "Duplicate() must be overridden by sub class");
338 // Not copying widget, it is a weak reference.
339 WidgetMouseEvent
* result
= new WidgetMouseEvent(
340 false, mMessage
, nullptr, mReason
, mContextMenuTrigger
, this);
341 result
->AssignMouseEventData(*this, true);
342 result
->mFlags
= mFlags
;
346 // If during mouseup handling we detect that click event might need to be
347 // dispatched, this is setup to be the target of the click event.
348 nsCOMPtr
<dom::EventTarget
> mClickTarget
;
350 // mReason indicates the reason why the event is fired:
351 // - Representing mouse operation.
352 // - Synthesized for emulating mousemove event when the content under the
353 // mouse cursor is scrolled.
354 Reason mReason
= eReal
;
356 // mContextMenuTrigger is valid only when mMessage is eContextMenu.
357 // This indicates if the context menu event is caused by context menu key or
358 // other reasons (typically, a click of right mouse button).
359 ContextMenuTrigger mContextMenuTrigger
= eNormal
;
361 // mExitFrom contains a value only when mMessage is eMouseExitFromWidget.
362 // This indicates if the mouse cursor exits from a top level platform widget,
363 // a child widget or a puppet widget.
364 Maybe
<ExitFrom
> mExitFrom
;
366 // mClickCount may be non-zero value when mMessage is eMouseDown, eMouseUp,
367 // ePointerClick or eMouseDoubleClick. The number is count of mouse clicks.
368 // Otherwise, this must be 0.
369 uint32_t mClickCount
= 0;
371 // Whether the event should ignore scroll frame bounds during dispatch.
372 bool mIgnoreRootScrollFrame
= false;
374 // Whether the event should be dispatched on a target limited in capturing
376 bool mIgnoreCapturingContent
= false;
378 // Whether the event shouldn't cause click event.
379 bool mClickEventPrevented
= false;
381 // If this is set to true while the event is being dispatched,
382 // PresShell::EventHandler::FinalizeHandlingEvent will dispatch a synthesized
383 // eMouseMove or ePointerMove.
384 bool mSynthesizeMoveAfterDispatch
= false;
386 void AssignMouseEventData(const WidgetMouseEvent
& aEvent
, bool aCopyTargets
) {
387 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
388 AssignPointerHelperData(aEvent
, /* aCopyCoalescedEvents */ true);
390 mReason
= aEvent
.mReason
;
391 mContextMenuTrigger
= aEvent
.mContextMenuTrigger
;
392 mExitFrom
= aEvent
.mExitFrom
;
393 mClickCount
= aEvent
.mClickCount
;
394 mIgnoreRootScrollFrame
= aEvent
.mIgnoreRootScrollFrame
;
395 mIgnoreCapturingContent
= aEvent
.mIgnoreCapturingContent
;
396 mClickEventPrevented
= aEvent
.mClickEventPrevented
;
400 * Returns true if the event is a context menu event caused by key.
402 bool IsContextMenuKeyEvent() const {
403 return mMessage
== eContextMenu
&& mContextMenuTrigger
== eContextMenuKey
;
407 * Returns true if the event is a real mouse event. Otherwise, i.e., it's
408 * a synthesized event by scroll or something, returns false.
410 bool IsReal() const { return mReason
== eReal
; }
413 * Returns true if middle click paste is enabled.
415 static bool IsMiddleClickPasteEnabled();
418 /******************************************************************************
419 * mozilla::WidgetDragEvent
420 ******************************************************************************/
422 class WidgetDragEvent
: public WidgetMouseEvent
{
424 friend class mozilla::dom::PBrowserParent
;
425 friend class mozilla::dom::PBrowserChild
;
426 ALLOW_DEPRECATED_READPARAM
430 : mUserCancelled(false),
431 mDefaultPreventedOnContent(false),
432 mInHTMLEditorEventListener(false) {}
435 virtual WidgetDragEvent
* AsDragEvent() override
{ return this; }
437 WidgetDragEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
438 const WidgetEventTime
* aTime
= nullptr)
439 : WidgetMouseEvent(aIsTrusted
, aMessage
, aWidget
, eDragEventClass
, eReal
,
441 mUserCancelled(false),
442 mDefaultPreventedOnContent(false),
443 mInHTMLEditorEventListener(false) {}
445 virtual WidgetEvent
* Duplicate() const override
{
446 MOZ_ASSERT(mClass
== eDragEventClass
,
447 "Duplicate() must be overridden by sub class");
448 // Not copying widget, it is a weak reference.
449 WidgetDragEvent
* result
=
450 new WidgetDragEvent(false, mMessage
, nullptr, this);
451 result
->AssignDragEventData(*this, true);
452 result
->mFlags
= mFlags
;
456 // The dragging data.
457 nsCOMPtr
<dom::DataTransfer
> mDataTransfer
;
459 // If this is true, user has cancelled the drag operation.
461 // If this is true, the drag event's preventDefault() is called on content.
462 bool mDefaultPreventedOnContent
;
463 // If this event is currently being handled by HTMLEditorEventListener.
464 bool mInHTMLEditorEventListener
;
466 // XXX Not tested by test_assign_event_data.html
467 void AssignDragEventData(const WidgetDragEvent
& aEvent
, bool aCopyTargets
) {
468 AssignMouseEventData(aEvent
, aCopyTargets
);
470 mDataTransfer
= aEvent
.mDataTransfer
;
471 // XXX mUserCancelled isn't copied, is this intentionally?
472 mUserCancelled
= false;
473 mDefaultPreventedOnContent
= aEvent
.mDefaultPreventedOnContent
;
474 // XXX mInHTMLEditorEventListener isn't copied, is this intentionally?
475 mInHTMLEditorEventListener
= false;
478 bool CanConvertToInputData() const {
479 return mMessage
== eDragStart
|| mMessage
== eDragEnd
||
480 mMessage
== eDragEnter
|| mMessage
== eDragOver
||
481 mMessage
== eDragExit
|| mMessage
== eDrop
;
485 * Should be called before dispatching the DOM tree if this event is
486 * synthesized for tests because drop effect is initialized before
487 * dispatching from widget if it's not synthesized event, but synthesized
488 * events are not initialized in the path.
490 void InitDropEffectForTests();
493 /******************************************************************************
494 * mozilla::WidgetMouseScrollEvent
496 * This is used for legacy DOM mouse scroll events, i.e.,
497 * DOMMouseScroll and MozMousePixelScroll event. These events are NOT hanbled
498 * by ESM even if widget dispatches them. Use new WidgetWheelEvent instead.
499 ******************************************************************************/
501 class WidgetMouseScrollEvent
: public WidgetMouseEventBase
{
503 WidgetMouseScrollEvent() : mDelta(0), mIsHorizontal(false) {}
506 virtual WidgetMouseScrollEvent
* AsMouseScrollEvent() override
{ return this; }
508 WidgetMouseScrollEvent(bool aIsTrusted
, EventMessage aMessage
,
510 const WidgetEventTime
* aTime
= nullptr)
511 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
,
512 eMouseScrollEventClass
, aTime
),
514 mIsHorizontal(false) {}
516 virtual WidgetEvent
* Duplicate() const override
{
517 MOZ_ASSERT(mClass
== eMouseScrollEventClass
,
518 "Duplicate() must be overridden by sub class");
519 // Not copying widget, it is a weak reference.
520 WidgetMouseScrollEvent
* result
=
521 new WidgetMouseScrollEvent(false, mMessage
, nullptr, this);
522 result
->AssignMouseScrollEventData(*this, true);
523 result
->mFlags
= mFlags
;
527 // The delta value of mouse scroll event.
528 // If the event message is eLegacyMouseLineOrPageScroll, the value indicates
529 // scroll amount in lines. However, if the value is
530 // UIEvent::SCROLL_PAGE_UP or UIEvent::SCROLL_PAGE_DOWN, the
531 // value inducates one page scroll. If the event message is
532 // eLegacyMousePixelScroll, the value indicates scroll amount in pixels.
535 // If this is true, it may cause to scroll horizontally.
536 // Otherwise, vertically.
539 void AssignMouseScrollEventData(const WidgetMouseScrollEvent
& aEvent
,
541 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
543 mDelta
= aEvent
.mDelta
;
544 mIsHorizontal
= aEvent
.mIsHorizontal
;
548 /******************************************************************************
549 * mozilla::WidgetWheelEvent
550 ******************************************************************************/
552 class WidgetWheelEvent
: public WidgetMouseEventBase
{
554 friend class mozilla::dom::PBrowserParent
;
555 friend class mozilla::dom::PBrowserChild
;
556 ALLOW_DEPRECATED_READPARAM
562 mOverflowDeltaX(0.0),
564 // Including WheelEventBinding.h here leads to an include loop, so
565 // we have to hardcode WheelEvent_Binding::DOM_DELTA_PIXEL.
567 mDeltaMode(/* WheelEvent_Binding::DOM_DELTA_PIXEL = */ 0),
568 mLineOrPageDeltaX(0),
569 mLineOrPageDeltaY(0),
570 mScrollType(SCROLL_DEFAULT
),
571 mCustomizedByUserPrefs(false),
572 mMayHaveMomentum(false),
574 mIsNoLineOrPageDelta(false),
575 mViewPortIsOverscrolled(false),
576 mCanTriggerSwipe(false),
577 mAllowToOverrideSystemScrollSpeed(false),
578 mDeltaValuesHorizontalizedForDefaultHandler(false) {}
581 virtual WidgetWheelEvent
* AsWheelEvent() override
{ return this; }
583 WidgetWheelEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
584 const WidgetEventTime
* aTime
= nullptr)
585 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, eWheelEventClass
,
590 mOverflowDeltaX(0.0),
592 // Including WheelEventBinding.h here leads to an include loop, so
593 // we have to hardcode WheelEvent_Binding::DOM_DELTA_PIXEL.
595 mDeltaMode(/* WheelEvent_Binding::DOM_DELTA_PIXEL = */ 0),
596 mLineOrPageDeltaX(0),
597 mLineOrPageDeltaY(0),
598 mScrollType(SCROLL_DEFAULT
),
599 mCustomizedByUserPrefs(false),
600 mMayHaveMomentum(false),
602 mIsNoLineOrPageDelta(false),
603 mViewPortIsOverscrolled(false),
604 mCanTriggerSwipe(false),
605 mAllowToOverrideSystemScrollSpeed(true),
606 mDeltaValuesHorizontalizedForDefaultHandler(false) {}
608 virtual WidgetEvent
* Duplicate() const override
{
609 MOZ_ASSERT(mClass
== eWheelEventClass
,
610 "Duplicate() must be overridden by sub class");
611 // Not copying widget, it is a weak reference.
612 WidgetWheelEvent
* result
=
613 new WidgetWheelEvent(false, mMessage
, nullptr, this);
614 result
->AssignWheelEventData(*this, true);
615 result
->mFlags
= mFlags
;
619 // Scroll gestures that start at the edge of the scrollable range can result
620 // in a swipe gesture. For the first wheel event of such a gesture, call
621 // TriggersSwipe() after the event has been processed in order to find out
622 // whether a swipe should be started.
623 bool TriggersSwipe() const {
624 return mCanTriggerSwipe
&& mViewPortIsOverscrolled
&&
625 this->mOverflowDeltaX
!= 0.0;
628 // NOTE: mDeltaX, mDeltaY and mDeltaZ may be customized by
629 // mousewheel.*.delta_multiplier_* prefs which are applied by
630 // EventStateManager. So, after widget dispatches this event,
631 // these delta values may have different values than before.
636 // The mousewheel tick counts.
637 double mWheelTicksX
= 0.0;
638 double mWheelTicksY
= 0.0;
640 enum class DeltaModeCheckingState
: uint8_t {
641 // Neither deltaMode nor the delta values have been accessed.
643 // The delta values have been accessed, without checking deltaMode first.
645 // The deltaMode has been checked.
649 // For compat reasons, we might expose a DOM_DELTA_LINE event as
650 // DOM_DELTA_PIXEL instead. Whether we do that depends on whether the event
651 // has been asked for the deltaMode before the deltas. If it has, we assume
652 // that the page will correctly handle DOM_DELTA_LINE. This variable tracks
653 // that state. See bug 1392460.
654 DeltaModeCheckingState mDeltaModeCheckingState
=
655 DeltaModeCheckingState::Unknown
;
657 // The amount of scrolling per line or page, without accounting for mouse
658 // wheel transactions etc.
660 // Computed by EventStateManager::DeltaAccumulator::InitLineOrPageDelta.
661 nsSize mScrollAmount
;
663 // overflowed delta values for scroll, these values are set by
664 // EventStateManger. If the default action of the wheel event isn't scroll,
665 // these values are always zero. Otherwise, remaining delta values which are
666 // not used by scroll are set.
667 // NOTE: mDeltaX, mDeltaY and mDeltaZ may be modified by EventStateManager.
668 // However, mOverflowDeltaX and mOverflowDeltaY indicate unused original
669 // delta values which are not applied the delta_multiplier prefs.
670 // So, if widget wanted to know the actual direction to be scrolled,
671 // it would need to check the mDeltaX and mDeltaY.
672 double mOverflowDeltaX
;
673 double mOverflowDeltaY
;
675 // Should be one of WheelEvent_Binding::DOM_DELTA_*
678 // If widget sets mLineOrPageDelta, EventStateManager will dispatch
679 // eLegacyMouseLineOrPageScroll event for compatibility. Note that the delta
680 // value means pages if the mDeltaMode is DOM_DELTA_PAGE, otherwise, lines.
681 int32_t mLineOrPageDeltaX
;
682 int32_t mLineOrPageDeltaY
;
684 // When the default action for an wheel event is moving history or zooming,
685 // need to chose a delta value for doing it.
686 int32_t GetPreferredIntDelta() {
687 if (!mLineOrPageDeltaX
&& !mLineOrPageDeltaY
) {
690 if (mLineOrPageDeltaY
&& !mLineOrPageDeltaX
) {
691 return mLineOrPageDeltaY
;
693 if (mLineOrPageDeltaX
&& !mLineOrPageDeltaY
) {
694 return mLineOrPageDeltaX
;
696 if ((mLineOrPageDeltaX
< 0 && mLineOrPageDeltaY
> 0) ||
697 (mLineOrPageDeltaX
> 0 && mLineOrPageDeltaY
< 0)) {
698 return 0; // We cannot guess the answer in this case.
700 return (Abs(mLineOrPageDeltaX
) > Abs(mLineOrPageDeltaY
))
706 // The default value is SCROLL_DEFAULT, which means EventStateManager will
707 // select preferred scroll type automatically.
708 enum ScrollType
: uint8_t {
710 SCROLL_SYNCHRONOUSLY
,
711 SCROLL_ASYNCHRONOUSLY
,
714 ScrollType mScrollType
;
716 // If the delta values are computed from prefs, this value is true.
717 // Otherwise, i.e., they are computed from native events, false.
718 bool mCustomizedByUserPrefs
;
720 // true if the momentum events directly tied to this event may follow it.
721 bool mMayHaveMomentum
;
722 // true if the event is caused by momentum.
725 // If device event handlers don't know when they should set mLineOrPageDeltaX
726 // and mLineOrPageDeltaY, this is true. Otherwise, false.
727 // If mIsNoLineOrPageDelta is true, ESM will generate
728 // eLegacyMouseLineOrPageScroll events when accumulated delta values reach
730 bool mIsNoLineOrPageDelta
;
732 // Whether or not the parent of the currently overscrolled frame is the
733 // ViewPort. This is false in situations when an element on the page is being
734 // overscrolled (such as a text field), but true when the 'page' is being
736 bool mViewPortIsOverscrolled
;
738 // The wheel event can trigger a swipe to start if it's overscrolling the
740 bool mCanTriggerSwipe
;
742 // If mAllowToOverrideSystemScrollSpeed is true, the scroll speed may be
743 // overridden. Otherwise, the scroll speed won't be overridden even if
744 // it's enabled by the pref.
745 bool mAllowToOverrideSystemScrollSpeed
;
747 // After the event's default action handler has adjusted its delta's values
748 // for horizontalizing a vertical wheel scroll, this variable will be set to
750 bool mDeltaValuesHorizontalizedForDefaultHandler
;
752 void AssignWheelEventData(const WidgetWheelEvent
& aEvent
, bool aCopyTargets
) {
753 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
755 mDeltaX
= aEvent
.mDeltaX
;
756 mDeltaY
= aEvent
.mDeltaY
;
757 mDeltaZ
= aEvent
.mDeltaZ
;
758 mDeltaMode
= aEvent
.mDeltaMode
;
759 mScrollAmount
= aEvent
.mScrollAmount
;
760 mCustomizedByUserPrefs
= aEvent
.mCustomizedByUserPrefs
;
761 mMayHaveMomentum
= aEvent
.mMayHaveMomentum
;
762 mIsMomentum
= aEvent
.mIsMomentum
;
763 mIsNoLineOrPageDelta
= aEvent
.mIsNoLineOrPageDelta
;
764 mLineOrPageDeltaX
= aEvent
.mLineOrPageDeltaX
;
765 mLineOrPageDeltaY
= aEvent
.mLineOrPageDeltaY
;
766 mScrollType
= aEvent
.mScrollType
;
767 mOverflowDeltaX
= aEvent
.mOverflowDeltaX
;
768 mOverflowDeltaY
= aEvent
.mOverflowDeltaY
;
769 mViewPortIsOverscrolled
= aEvent
.mViewPortIsOverscrolled
;
770 mCanTriggerSwipe
= aEvent
.mCanTriggerSwipe
;
771 mAllowToOverrideSystemScrollSpeed
=
772 aEvent
.mAllowToOverrideSystemScrollSpeed
;
773 mDeltaValuesHorizontalizedForDefaultHandler
=
774 aEvent
.mDeltaValuesHorizontalizedForDefaultHandler
;
777 // System scroll speed settings may be too slow at using Gecko. In such
778 // case, we should override the scroll speed computed with system settings.
779 // Following methods return preferred delta values which are multiplied by
780 // factors specified by prefs. If system scroll speed shouldn't be
781 // overridden (e.g., this feature is disabled by pref), they return raw
783 double OverriddenDeltaX() const;
784 double OverriddenDeltaY() const;
786 // Compute the overridden delta value. This may be useful for suppressing
787 // too fast scroll by system scroll speed overriding when widget sets
788 // mAllowToOverrideSystemScrollSpeed.
789 static double ComputeOverriddenDelta(double aDelta
, bool aIsForVertical
);
792 static bool sInitialized
;
793 static bool sIsSystemScrollSpeedOverrideEnabled
;
794 static int32_t sOverrideFactorX
;
795 static int32_t sOverrideFactorY
;
796 static void Initialize();
799 /******************************************************************************
800 * mozilla::WidgetPointerEvent
801 ******************************************************************************/
803 class WidgetPointerEvent
: public WidgetMouseEvent
{
804 friend class mozilla::dom::PBrowserParent
;
805 friend class mozilla::dom::PBrowserChild
;
806 ALLOW_DEPRECATED_READPARAM
808 WidgetPointerEvent() = default;
811 virtual WidgetPointerEvent
* AsPointerEvent() override
{ return this; }
813 WidgetPointerEvent(bool aIsTrusted
, EventMessage aMsg
, nsIWidget
* w
,
814 const WidgetEventTime
* aTime
)
815 : WidgetMouseEvent(aIsTrusted
, aMsg
, w
, ePointerEventClass
, eReal
,
817 if (aMsg
== eContextMenu
) {
818 mButton
= (mContextMenuTrigger
== eNormal
) ? MouseButton::eSecondary
819 : MouseButton::ePrimary
;
823 WidgetPointerEvent(bool aIsTrusted
, EventMessage aMsg
, nsIWidget
* w
,
824 ContextMenuTrigger aContextMenuTrigger
= eNormal
,
825 const WidgetEventTime
* aTime
= nullptr)
826 : WidgetMouseEvent(aIsTrusted
, aMsg
, w
, ePointerEventClass
, eReal
,
827 aContextMenuTrigger
, aTime
) {
828 if (aMsg
== eContextMenu
) {
829 mButton
= (mContextMenuTrigger
== eNormal
) ? MouseButton::eSecondary
830 : MouseButton::ePrimary
;
834 explicit WidgetPointerEvent(const WidgetMouseEvent
& aEvent
)
835 : WidgetMouseEvent(aEvent
) {
836 mClass
= ePointerEventClass
;
839 virtual WidgetEvent
* Duplicate() const override
{
840 MOZ_ASSERT(mClass
== ePointerEventClass
,
841 "Duplicate() must be overridden by sub class");
842 // Not copying widget, it is a weak reference.
843 WidgetPointerEvent
* result
= new WidgetPointerEvent(
844 false, mMessage
, nullptr, mContextMenuTrigger
, this);
845 result
->AssignPointerEventData(*this, true);
846 result
->mFlags
= mFlags
;
851 double mHeight
= 1.0;
852 bool mIsPrimary
= true;
853 bool mFromTouchEvent
= false;
855 // XXX Not tested by test_assign_event_data.html
856 void AssignPointerEventData(const WidgetPointerEvent
& aEvent
,
858 AssignMouseEventData(aEvent
, aCopyTargets
);
860 mWidth
= aEvent
.mWidth
;
861 mHeight
= aEvent
.mHeight
;
862 mIsPrimary
= aEvent
.mIsPrimary
;
863 mFromTouchEvent
= aEvent
.mFromTouchEvent
;
867 } // namespace mozilla
869 #endif // mozilla_MouseEvents_h__