Bug 1747171 don't hold mutex while spinning nested event loop r=jesup
[gecko.git] / widget / MouseEvents.h
blobeb9b0c723634e210bf6decedb1bd9b35de7cc7fd
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__
9 #include <stdint.h>
11 #include "mozilla/BasicEvents.h"
12 #include "mozilla/MathAlgorithms.h"
13 #include "mozilla/dom/DataTransfer.h"
14 #include "nsCOMPtr.h"
16 namespace mozilla {
18 namespace dom {
19 class PBrowserParent;
20 class PBrowserChild;
21 class PBrowserBridgeParent;
22 } // namespace dom
24 class WidgetPointerEvent;
25 } // namespace mozilla
27 namespace mozilla {
28 class WidgetPointerEventHolder final {
29 public:
30 nsTArray<WidgetPointerEvent> mEvents;
31 NS_INLINE_DECL_REFCOUNTING(WidgetPointerEventHolder)
33 private:
34 virtual ~WidgetPointerEventHolder() = default;
37 /******************************************************************************
38 * mozilla::WidgetPointerHelper
39 ******************************************************************************/
41 class WidgetPointerHelper {
42 public:
43 uint32_t pointerId;
44 uint32_t tiltX;
45 uint32_t tiltY;
46 uint32_t twist;
47 float tangentialPressure;
48 bool convertToPointer;
49 RefPtr<WidgetPointerEventHolder> mCoalescedWidgetEvents;
51 WidgetPointerHelper()
52 : pointerId(0),
53 tiltX(0),
54 tiltY(0),
55 twist(0),
56 tangentialPressure(0),
57 convertToPointer(true) {}
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) {}
68 explicit WidgetPointerHelper(const WidgetPointerHelper& aHelper) = default;
70 void AssignPointerHelperData(const WidgetPointerHelper& aEvent,
71 bool aCopyCoalescedEvents = false) {
72 pointerId = aEvent.pointerId;
73 tiltX = aEvent.tiltX;
74 tiltY = aEvent.tiltY;
75 twist = aEvent.twist;
76 tangentialPressure = aEvent.tangentialPressure;
77 convertToPointer = aEvent.convertToPointer;
78 if (aCopyCoalescedEvents) {
79 mCoalescedWidgetEvents = aEvent.mCoalescedWidgetEvents;
84 /******************************************************************************
85 * mozilla::WidgetMouseEventBase
86 ******************************************************************************/
88 class WidgetMouseEventBase : public WidgetInputEvent {
89 private:
90 friend class dom::PBrowserParent;
91 friend class dom::PBrowserChild;
92 friend class dom::PBrowserBridgeParent;
94 protected:
95 WidgetMouseEventBase()
96 : mPressure(0),
97 mButton(0),
98 mButtons(0),
99 mInputSource(/* MouseEvent_Binding::MOZ_SOURCE_MOUSE = */ 1) {}
100 // Including MouseEventBinding.h here leads to an include loop, so
101 // we have to hardcode MouseEvent_Binding::MOZ_SOURCE_MOUSE.
103 WidgetMouseEventBase(bool aIsTrusted, EventMessage aMessage,
104 nsIWidget* aWidget, EventClassID aEventClassID)
105 : WidgetInputEvent(aIsTrusted, aMessage, aWidget, aEventClassID),
106 mPressure(0),
107 mButton(0),
108 mButtons(0),
109 mInputSource(/* MouseEvent_Binding::MOZ_SOURCE_MOUSE = */ 1) {}
110 // Including MouseEventBinding.h here leads to an include loop, so
111 // we have to hardcode MouseEvent_Binding::MOZ_SOURCE_MOUSE.
113 public:
114 virtual WidgetMouseEventBase* AsMouseEventBase() override { return this; }
116 virtual WidgetEvent* Duplicate() const override {
117 MOZ_CRASH("WidgetMouseEventBase must not be most-subclass");
120 // ID of the canvas HitRegion
121 nsString mRegion;
123 // Finger or touch pressure of event. It ranges between 0.0 and 1.0.
124 float mPressure;
126 // Pressed button ID of mousedown or mouseup event.
127 // This is set only when pressing a button causes the event.
128 int16_t mButton;
130 // Flags of all pressed buttons at the event fired.
131 // This is set at any mouse event, don't be confused with |mButton|.
132 int16_t mButtons;
134 // Possible values a in MouseEvent
135 uint16_t mInputSource;
137 bool IsLeftButtonPressed() const {
138 return !!(mButtons & MouseButtonsFlag::ePrimaryFlag);
140 bool IsRightButtonPressed() const {
141 return !!(mButtons & MouseButtonsFlag::eSecondaryFlag);
143 bool IsMiddleButtonPressed() const {
144 return !!(mButtons & MouseButtonsFlag::eMiddleFlag);
146 bool Is4thButtonPressed() const {
147 return !!(mButtons & MouseButtonsFlag::e4thFlag);
149 bool Is5thButtonPressed() const {
150 return !!(mButtons & MouseButtonsFlag::e5thFlag);
153 void AssignMouseEventBaseData(const WidgetMouseEventBase& aEvent,
154 bool aCopyTargets) {
155 AssignInputEventData(aEvent, aCopyTargets);
157 mButton = aEvent.mButton;
158 mButtons = aEvent.mButtons;
159 mPressure = aEvent.mPressure;
160 mInputSource = aEvent.mInputSource;
164 * Returns true if left click event.
166 bool IsLeftClickEvent() const {
167 return mMessage == eMouseClick && mButton == MouseButton::ePrimary;
171 /******************************************************************************
172 * mozilla::WidgetMouseEvent
173 ******************************************************************************/
175 class WidgetMouseEvent : public WidgetMouseEventBase,
176 public WidgetPointerHelper {
177 private:
178 friend class dom::PBrowserParent;
179 friend class dom::PBrowserChild;
180 friend class dom::PBrowserBridgeParent;
182 public:
183 typedef bool ReasonType;
184 enum Reason : ReasonType { eReal, eSynthesized };
186 typedef uint8_t ContextMenuTriggerType;
187 enum ContextMenuTrigger : ContextMenuTriggerType {
188 eNormal,
189 eContextMenuKey,
190 eControlClick
193 typedef uint8_t ExitFromType;
194 enum ExitFrom : ExitFromType {
195 ePlatformChild,
196 ePlatformTopLevel,
197 ePuppet,
198 ePuppetParentToPuppetChild
201 protected:
202 WidgetMouseEvent()
203 : mReason(eReal),
204 mContextMenuTrigger(eNormal),
205 mClickCount(0),
206 mIgnoreRootScrollFrame(false),
207 mUseLegacyNonPrimaryDispatch(false),
208 mClickEventPrevented(false) {}
210 WidgetMouseEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
211 EventClassID aEventClassID, Reason aReason)
212 : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, aEventClassID),
213 mReason(aReason),
214 mContextMenuTrigger(eNormal),
215 mClickCount(0),
216 mIgnoreRootScrollFrame(false),
217 mUseLegacyNonPrimaryDispatch(false),
218 mClickEventPrevented(false) {}
220 #ifdef DEBUG
221 void AssertContextMenuEventButtonConsistency() const;
222 #endif
224 public:
225 virtual WidgetMouseEvent* AsMouseEvent() override { return this; }
227 WidgetMouseEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
228 Reason aReason,
229 ContextMenuTrigger aContextMenuTrigger = eNormal)
230 : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eMouseEventClass),
231 mReason(aReason),
232 mContextMenuTrigger(aContextMenuTrigger),
233 mClickCount(0),
234 mIgnoreRootScrollFrame(false),
235 mUseLegacyNonPrimaryDispatch(false),
236 mClickEventPrevented(false) {
237 if (aMessage == eContextMenu) {
238 mButton = (mContextMenuTrigger == eNormal) ? MouseButton::eSecondary
239 : MouseButton::ePrimary;
243 #ifdef DEBUG
244 virtual ~WidgetMouseEvent() { AssertContextMenuEventButtonConsistency(); }
245 #endif
247 virtual WidgetEvent* Duplicate() const override {
248 MOZ_ASSERT(mClass == eMouseEventClass,
249 "Duplicate() must be overridden by sub class");
250 // Not copying widget, it is a weak reference.
251 WidgetMouseEvent* result = new WidgetMouseEvent(
252 false, mMessage, nullptr, mReason, mContextMenuTrigger);
253 result->AssignMouseEventData(*this, true);
254 result->mFlags = mFlags;
255 return result;
258 // If during mouseup handling we detect that click event might need to be
259 // dispatched, this is setup to be the target of the click event.
260 nsCOMPtr<dom::EventTarget> mClickTarget;
262 // mReason indicates the reason why the event is fired:
263 // - Representing mouse operation.
264 // - Synthesized for emulating mousemove event when the content under the
265 // mouse cursor is scrolled.
266 Reason mReason;
268 // mContextMenuTrigger is valid only when mMessage is eContextMenu.
269 // This indicates if the context menu event is caused by context menu key or
270 // other reasons (typically, a click of right mouse button).
271 ContextMenuTrigger mContextMenuTrigger;
273 // mExitFrom contains a value only when mMessage is eMouseExitFromWidget.
274 // This indicates if the mouse cursor exits from a top level platform widget,
275 // a child widget or a puppet widget.
276 Maybe<ExitFrom> mExitFrom;
278 // mClickCount may be non-zero value when mMessage is eMouseDown, eMouseUp,
279 // eMouseClick or eMouseDoubleClick. The number is count of mouse clicks.
280 // Otherwise, this must be 0.
281 uint32_t mClickCount;
283 // Whether the event should ignore scroll frame bounds during dispatch.
284 bool mIgnoreRootScrollFrame;
286 // Indicates whether the event should dispatch click events for non-primary
287 // mouse buttons on window and document.
288 bool mUseLegacyNonPrimaryDispatch;
290 // Whether the event shouldn't cause click event.
291 bool mClickEventPrevented;
293 void AssignMouseEventData(const WidgetMouseEvent& aEvent, bool aCopyTargets) {
294 AssignMouseEventBaseData(aEvent, aCopyTargets);
295 AssignPointerHelperData(aEvent, /* aCopyCoalescedEvents */ true);
297 mExitFrom = aEvent.mExitFrom;
298 mClickCount = aEvent.mClickCount;
299 mIgnoreRootScrollFrame = aEvent.mIgnoreRootScrollFrame;
300 mUseLegacyNonPrimaryDispatch = aEvent.mUseLegacyNonPrimaryDispatch;
301 mClickEventPrevented = aEvent.mClickEventPrevented;
305 * Returns true if the event is a context menu event caused by key.
307 bool IsContextMenuKeyEvent() const {
308 return mMessage == eContextMenu && mContextMenuTrigger == eContextMenuKey;
312 * Returns true if the event is a real mouse event. Otherwise, i.e., it's
313 * a synthesized event by scroll or something, returns false.
315 bool IsReal() const { return mReason == eReal; }
318 * Returns true if middle click paste is enabled.
320 static bool IsMiddleClickPasteEnabled();
323 /******************************************************************************
324 * mozilla::WidgetDragEvent
325 ******************************************************************************/
327 class WidgetDragEvent : public WidgetMouseEvent {
328 private:
329 friend class mozilla::dom::PBrowserParent;
330 friend class mozilla::dom::PBrowserChild;
332 protected:
333 WidgetDragEvent()
334 : mUserCancelled(false), mDefaultPreventedOnContent(false) {}
336 public:
337 virtual WidgetDragEvent* AsDragEvent() override { return this; }
339 WidgetDragEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
340 : WidgetMouseEvent(aIsTrusted, aMessage, aWidget, eDragEventClass, eReal),
341 mUserCancelled(false),
342 mDefaultPreventedOnContent(false) {}
344 virtual WidgetEvent* Duplicate() const override {
345 MOZ_ASSERT(mClass == eDragEventClass,
346 "Duplicate() must be overridden by sub class");
347 // Not copying widget, it is a weak reference.
348 WidgetDragEvent* result = new WidgetDragEvent(false, mMessage, nullptr);
349 result->AssignDragEventData(*this, true);
350 result->mFlags = mFlags;
351 return result;
354 // The dragging data.
355 nsCOMPtr<dom::DataTransfer> mDataTransfer;
357 // If this is true, user has cancelled the drag operation.
358 bool mUserCancelled;
359 // If this is true, the drag event's preventDefault() is called on content.
360 bool mDefaultPreventedOnContent;
362 // XXX Not tested by test_assign_event_data.html
363 void AssignDragEventData(const WidgetDragEvent& aEvent, bool aCopyTargets) {
364 AssignMouseEventData(aEvent, aCopyTargets);
366 mDataTransfer = aEvent.mDataTransfer;
367 // XXX mUserCancelled isn't copied, is this intentionally?
368 mUserCancelled = false;
369 mDefaultPreventedOnContent = aEvent.mDefaultPreventedOnContent;
373 * Should be called before dispatching the DOM tree if this event is
374 * synthesized for tests because drop effect is initialized before
375 * dispatching from widget if it's not synthesized event, but synthesized
376 * events are not initialized in the path.
378 void InitDropEffectForTests();
381 /******************************************************************************
382 * mozilla::WidgetMouseScrollEvent
384 * This is used for legacy DOM mouse scroll events, i.e.,
385 * DOMMouseScroll and MozMousePixelScroll event. These events are NOT hanbled
386 * by ESM even if widget dispatches them. Use new WidgetWheelEvent instead.
387 ******************************************************************************/
389 class WidgetMouseScrollEvent : public WidgetMouseEventBase {
390 private:
391 WidgetMouseScrollEvent() : mDelta(0), mIsHorizontal(false) {}
393 public:
394 virtual WidgetMouseScrollEvent* AsMouseScrollEvent() override { return this; }
396 WidgetMouseScrollEvent(bool aIsTrusted, EventMessage aMessage,
397 nsIWidget* aWidget)
398 : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget,
399 eMouseScrollEventClass),
400 mDelta(0),
401 mIsHorizontal(false) {}
403 virtual WidgetEvent* Duplicate() const override {
404 MOZ_ASSERT(mClass == eMouseScrollEventClass,
405 "Duplicate() must be overridden by sub class");
406 // Not copying widget, it is a weak reference.
407 WidgetMouseScrollEvent* result =
408 new WidgetMouseScrollEvent(false, mMessage, nullptr);
409 result->AssignMouseScrollEventData(*this, true);
410 result->mFlags = mFlags;
411 return result;
414 // The delta value of mouse scroll event.
415 // If the event message is eLegacyMouseLineOrPageScroll, the value indicates
416 // scroll amount in lines. However, if the value is
417 // UIEvent::SCROLL_PAGE_UP or UIEvent::SCROLL_PAGE_DOWN, the
418 // value inducates one page scroll. If the event message is
419 // eLegacyMousePixelScroll, the value indicates scroll amount in pixels.
420 int32_t mDelta;
422 // If this is true, it may cause to scroll horizontally.
423 // Otherwise, vertically.
424 bool mIsHorizontal;
426 void AssignMouseScrollEventData(const WidgetMouseScrollEvent& aEvent,
427 bool aCopyTargets) {
428 AssignMouseEventBaseData(aEvent, aCopyTargets);
430 mDelta = aEvent.mDelta;
431 mIsHorizontal = aEvent.mIsHorizontal;
435 /******************************************************************************
436 * mozilla::WidgetWheelEvent
437 ******************************************************************************/
439 class WidgetWheelEvent : public WidgetMouseEventBase {
440 private:
441 friend class mozilla::dom::PBrowserParent;
442 friend class mozilla::dom::PBrowserChild;
444 WidgetWheelEvent()
445 : mDeltaX(0.0),
446 mDeltaY(0.0),
447 mDeltaZ(0.0),
448 mOverflowDeltaX(0.0),
449 mOverflowDeltaY(0.0)
450 // Including WheelEventBinding.h here leads to an include loop, so
451 // we have to hardcode WheelEvent_Binding::DOM_DELTA_PIXEL.
453 mDeltaMode(/* WheelEvent_Binding::DOM_DELTA_PIXEL = */ 0),
454 mLineOrPageDeltaX(0),
455 mLineOrPageDeltaY(0),
456 mScrollType(SCROLL_DEFAULT),
457 mCustomizedByUserPrefs(false),
458 mMayHaveMomentum(false),
459 mIsMomentum(false),
460 mIsNoLineOrPageDelta(false),
461 mViewPortIsOverscrolled(false),
462 mCanTriggerSwipe(false),
463 mAllowToOverrideSystemScrollSpeed(false),
464 mDeltaValuesHorizontalizedForDefaultHandler(false) {}
466 public:
467 virtual WidgetWheelEvent* AsWheelEvent() override { return this; }
469 WidgetWheelEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget)
470 : WidgetMouseEventBase(aIsTrusted, aMessage, aWidget, eWheelEventClass),
471 mDeltaX(0.0),
472 mDeltaY(0.0),
473 mDeltaZ(0.0),
474 mOverflowDeltaX(0.0),
475 mOverflowDeltaY(0.0)
476 // Including WheelEventBinding.h here leads to an include loop, so
477 // we have to hardcode WheelEvent_Binding::DOM_DELTA_PIXEL.
479 mDeltaMode(/* WheelEvent_Binding::DOM_DELTA_PIXEL = */ 0),
480 mLineOrPageDeltaX(0),
481 mLineOrPageDeltaY(0),
482 mScrollType(SCROLL_DEFAULT),
483 mCustomizedByUserPrefs(false),
484 mMayHaveMomentum(false),
485 mIsMomentum(false),
486 mIsNoLineOrPageDelta(false),
487 mViewPortIsOverscrolled(false),
488 mCanTriggerSwipe(false),
489 mAllowToOverrideSystemScrollSpeed(true),
490 mDeltaValuesHorizontalizedForDefaultHandler(false) {}
492 virtual WidgetEvent* Duplicate() const override {
493 MOZ_ASSERT(mClass == eWheelEventClass,
494 "Duplicate() must be overridden by sub class");
495 // Not copying widget, it is a weak reference.
496 WidgetWheelEvent* result = new WidgetWheelEvent(false, mMessage, nullptr);
497 result->AssignWheelEventData(*this, true);
498 result->mFlags = mFlags;
499 return result;
502 // On OS X, scroll gestures that start at the edge of the scrollable range
503 // can result in a swipe gesture. For the first wheel event of such a
504 // gesture, call TriggersSwipe() after the event has been processed
505 // in order to find out whether a swipe should be started.
506 bool TriggersSwipe() const {
507 return mCanTriggerSwipe && mViewPortIsOverscrolled &&
508 this->mOverflowDeltaX != 0.0;
511 // NOTE: mDeltaX, mDeltaY and mDeltaZ may be customized by
512 // mousewheel.*.delta_multiplier_* prefs which are applied by
513 // EventStateManager. So, after widget dispatches this event,
514 // these delta values may have different values than before.
515 double mDeltaX;
516 double mDeltaY;
517 double mDeltaZ;
519 // The mousewheel tick counts.
520 double mWheelTicksX = 0.0;
521 double mWheelTicksY = 0.0;
523 enum class DeltaModeCheckingState : uint8_t {
524 // Neither deltaMode nor the delta values have been accessed.
525 Unknown,
526 // The delta values have been accessed, without checking deltaMode first.
527 Unchecked,
528 // The deltaMode has been checked.
529 Checked,
532 // For compat reasons, we might expose a DOM_DELTA_LINE event as
533 // DOM_DELTA_PIXEL instead. Whether we do that depends on whether the event
534 // has been asked for the deltaMode before the deltas. If it has, we assume
535 // that the page will correctly handle DOM_DELTA_LINE. This variable tracks
536 // that state. See bug 1392460.
537 DeltaModeCheckingState mDeltaModeCheckingState =
538 DeltaModeCheckingState::Unknown;
540 // The amount of scrolling per line or page, without accounting for mouse
541 // wheel transactions etc.
543 // Computed by EventStateManager::DeltaAccumulator::InitLineOrPageDelta.
544 nsSize mScrollAmount;
546 // overflowed delta values for scroll, these values are set by
547 // EventStateManger. If the default action of the wheel event isn't scroll,
548 // these values are always zero. Otherwise, remaining delta values which are
549 // not used by scroll are set.
550 // NOTE: mDeltaX, mDeltaY and mDeltaZ may be modified by EventStateManager.
551 // However, mOverflowDeltaX and mOverflowDeltaY indicate unused original
552 // delta values which are not applied the delta_multiplier prefs.
553 // So, if widget wanted to know the actual direction to be scrolled,
554 // it would need to check the mDeltaX and mDeltaY.
555 double mOverflowDeltaX;
556 double mOverflowDeltaY;
558 // Should be one of WheelEvent_Binding::DOM_DELTA_*
559 uint32_t mDeltaMode;
561 // If widget sets mLineOrPageDelta, EventStateManager will dispatch
562 // eLegacyMouseLineOrPageScroll event for compatibility. Note that the delta
563 // value means pages if the mDeltaMode is DOM_DELTA_PAGE, otherwise, lines.
564 int32_t mLineOrPageDeltaX;
565 int32_t mLineOrPageDeltaY;
567 // When the default action for an wheel event is moving history or zooming,
568 // need to chose a delta value for doing it.
569 int32_t GetPreferredIntDelta() {
570 if (!mLineOrPageDeltaX && !mLineOrPageDeltaY) {
571 return 0;
573 if (mLineOrPageDeltaY && !mLineOrPageDeltaX) {
574 return mLineOrPageDeltaY;
576 if (mLineOrPageDeltaX && !mLineOrPageDeltaY) {
577 return mLineOrPageDeltaX;
579 if ((mLineOrPageDeltaX < 0 && mLineOrPageDeltaY > 0) ||
580 (mLineOrPageDeltaX > 0 && mLineOrPageDeltaY < 0)) {
581 return 0; // We cannot guess the answer in this case.
583 return (Abs(mLineOrPageDeltaX) > Abs(mLineOrPageDeltaY))
584 ? mLineOrPageDeltaX
585 : mLineOrPageDeltaY;
588 // Scroll type
589 // The default value is SCROLL_DEFAULT, which means EventStateManager will
590 // select preferred scroll type automatically.
591 enum ScrollType : uint8_t {
592 SCROLL_DEFAULT,
593 SCROLL_SYNCHRONOUSLY,
594 SCROLL_ASYNCHRONOUSELY,
595 SCROLL_SMOOTHLY
597 ScrollType mScrollType;
599 // If the delta values are computed from prefs, this value is true.
600 // Otherwise, i.e., they are computed from native events, false.
601 bool mCustomizedByUserPrefs;
603 // true if the momentum events directly tied to this event may follow it.
604 bool mMayHaveMomentum;
605 // true if the event is caused by momentum.
606 bool mIsMomentum;
608 // If device event handlers don't know when they should set mLineOrPageDeltaX
609 // and mLineOrPageDeltaY, this is true. Otherwise, false.
610 // If mIsNoLineOrPageDelta is true, ESM will generate
611 // eLegacyMouseLineOrPageScroll events when accumulated delta values reach
612 // a line height.
613 bool mIsNoLineOrPageDelta;
615 // Whether or not the parent of the currently overscrolled frame is the
616 // ViewPort. This is false in situations when an element on the page is being
617 // overscrolled (such as a text field), but true when the 'page' is being
618 // overscrolled.
619 bool mViewPortIsOverscrolled;
621 // The wheel event can trigger a swipe to start if it's overscrolling the
622 // viewport.
623 bool mCanTriggerSwipe;
625 // If mAllowToOverrideSystemScrollSpeed is true, the scroll speed may be
626 // overridden. Otherwise, the scroll speed won't be overridden even if
627 // it's enabled by the pref.
628 bool mAllowToOverrideSystemScrollSpeed;
630 // After the event's default action handler has adjusted its delta's values
631 // for horizontalizing a vertical wheel scroll, this variable will be set to
632 // true.
633 bool mDeltaValuesHorizontalizedForDefaultHandler;
635 void AssignWheelEventData(const WidgetWheelEvent& aEvent, bool aCopyTargets) {
636 AssignMouseEventBaseData(aEvent, aCopyTargets);
638 mDeltaX = aEvent.mDeltaX;
639 mDeltaY = aEvent.mDeltaY;
640 mDeltaZ = aEvent.mDeltaZ;
641 mDeltaMode = aEvent.mDeltaMode;
642 mScrollAmount = aEvent.mScrollAmount;
643 mCustomizedByUserPrefs = aEvent.mCustomizedByUserPrefs;
644 mMayHaveMomentum = aEvent.mMayHaveMomentum;
645 mIsMomentum = aEvent.mIsMomentum;
646 mIsNoLineOrPageDelta = aEvent.mIsNoLineOrPageDelta;
647 mLineOrPageDeltaX = aEvent.mLineOrPageDeltaX;
648 mLineOrPageDeltaY = aEvent.mLineOrPageDeltaY;
649 mScrollType = aEvent.mScrollType;
650 mOverflowDeltaX = aEvent.mOverflowDeltaX;
651 mOverflowDeltaY = aEvent.mOverflowDeltaY;
652 mViewPortIsOverscrolled = aEvent.mViewPortIsOverscrolled;
653 mCanTriggerSwipe = aEvent.mCanTriggerSwipe;
654 mAllowToOverrideSystemScrollSpeed =
655 aEvent.mAllowToOverrideSystemScrollSpeed;
656 mDeltaValuesHorizontalizedForDefaultHandler =
657 aEvent.mDeltaValuesHorizontalizedForDefaultHandler;
660 // System scroll speed settings may be too slow at using Gecko. In such
661 // case, we should override the scroll speed computed with system settings.
662 // Following methods return preferred delta values which are multiplied by
663 // factors specified by prefs. If system scroll speed shouldn't be
664 // overridden (e.g., this feature is disabled by pref), they return raw
665 // delta values.
666 double OverriddenDeltaX() const;
667 double OverriddenDeltaY() const;
669 // Compute the overridden delta value. This may be useful for suppressing
670 // too fast scroll by system scroll speed overriding when widget sets
671 // mAllowToOverrideSystemScrollSpeed.
672 static double ComputeOverriddenDelta(double aDelta, bool aIsForVertical);
674 private:
675 static bool sInitialized;
676 static bool sIsSystemScrollSpeedOverrideEnabled;
677 static int32_t sOverrideFactorX;
678 static int32_t sOverrideFactorY;
679 static void Initialize();
682 /******************************************************************************
683 * mozilla::WidgetPointerEvent
684 ******************************************************************************/
686 class WidgetPointerEvent : public WidgetMouseEvent {
687 friend class mozilla::dom::PBrowserParent;
688 friend class mozilla::dom::PBrowserChild;
690 public:
691 virtual WidgetPointerEvent* AsPointerEvent() override { return this; }
693 WidgetPointerEvent(bool aIsTrusted, EventMessage aMsg, nsIWidget* w)
694 : WidgetMouseEvent(aIsTrusted, aMsg, w, ePointerEventClass, eReal),
695 mWidth(1),
696 mHeight(1),
697 mIsPrimary(true),
698 mFromTouchEvent(false) {}
700 explicit WidgetPointerEvent(const WidgetMouseEvent& aEvent)
701 : WidgetMouseEvent(aEvent),
702 mWidth(1),
703 mHeight(1),
704 mIsPrimary(true),
705 mFromTouchEvent(false) {
706 mClass = ePointerEventClass;
709 virtual WidgetEvent* Duplicate() const override {
710 MOZ_ASSERT(mClass == ePointerEventClass,
711 "Duplicate() must be overridden by sub class");
712 // Not copying widget, it is a weak reference.
713 WidgetPointerEvent* result =
714 new WidgetPointerEvent(false, mMessage, nullptr);
715 result->AssignPointerEventData(*this, true);
716 result->mFlags = mFlags;
717 return result;
720 uint32_t mWidth;
721 uint32_t mHeight;
722 bool mIsPrimary;
723 bool mFromTouchEvent;
725 // XXX Not tested by test_assign_event_data.html
726 void AssignPointerEventData(const WidgetPointerEvent& aEvent,
727 bool aCopyTargets) {
728 AssignMouseEventData(aEvent, aCopyTargets);
730 mWidth = aEvent.mWidth;
731 mHeight = aEvent.mHeight;
732 mIsPrimary = aEvent.mIsPrimary;
733 mFromTouchEvent = aEvent.mFromTouchEvent;
737 } // namespace mozilla
739 #endif // mozilla_MouseEvents_h__