tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PointerEventHandler.h (28401B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_PointerEventHandler_h
      8 #define mozilla_PointerEventHandler_h
      9 
     10 #include "LayoutConstants.h"
     11 #include "mozilla/EventForwards.h"
     12 #include "mozilla/Maybe.h"
     13 #include "mozilla/MouseEvents.h"
     14 #include "mozilla/StaticPtr.h"
     15 #include "mozilla/TouchEvents.h"
     16 #include "mozilla/WeakPtr.h"
     17 
     18 // XXX Avoid including this here by moving function bodies to the cpp file
     19 #include "mozilla/dom/Document.h"
     20 #include "mozilla/dom/Element.h"
     21 #include "mozilla/layers/InputAPZContext.h"
     22 
     23 class AutoWeakFrame;
     24 class nsIFrame;
     25 class nsIContent;
     26 class nsPresContext;
     27 
     28 namespace mozilla {
     29 
     30 class PresShell;
     31 
     32 namespace dom {
     33 class BrowserParent;
     34 class Document;
     35 class Element;
     36 };  // namespace dom
     37 
     38 class PointerCaptureInfo final {
     39 public:
     40  RefPtr<dom::Element> mPendingElement;
     41  RefPtr<dom::Element> mOverrideElement;
     42 
     43  explicit PointerCaptureInfo(dom::Element* aPendingElement)
     44      : mPendingElement(aPendingElement) {
     45    MOZ_COUNT_CTOR(PointerCaptureInfo);
     46  }
     47 
     48  MOZ_COUNTED_DTOR(PointerCaptureInfo)
     49 
     50  bool Empty() { return !(mPendingElement || mOverrideElement); }
     51 };
     52 
     53 /**
     54 * PointerInfo stores the pointer's information and its last state (position,
     55 * buttons, etc).
     56 */
     57 struct PointerInfo final {
     58  using Document = dom::Document;
     59  enum class Active : bool { No, Yes };
     60  enum class Primary : bool { No, Yes };
     61  enum class FromTouchEvent : bool { No, Yes };
     62  enum class SynthesizeForTests : bool { No, Yes };
     63  PointerInfo()
     64      : mIsActive(false),
     65        mIsPrimary(false),
     66        mFromTouchEvent(false),
     67        mPreventMouseEventByContent(false),
     68        mIsSynthesizedForTests(false) {}
     69  PointerInfo(const PointerInfo&) = default;
     70  explicit PointerInfo(
     71      Active aActiveState, uint16_t aInputSource, Primary aPrimaryState,
     72      FromTouchEvent aFromTouchEvent, Document* aActiveDocument,
     73      const PointerInfo* aLastPointerInfo = nullptr,
     74      SynthesizeForTests aIsSynthesizedForTests = SynthesizeForTests::No)
     75      : mActiveDocument(aActiveDocument),
     76        mInputSource(aInputSource),
     77        mIsActive(static_cast<bool>(aActiveState)),
     78        mIsPrimary(static_cast<bool>(aPrimaryState)),
     79        mFromTouchEvent(static_cast<bool>(aFromTouchEvent)),
     80        mPreventMouseEventByContent(false),
     81        mIsSynthesizedForTests(static_cast<bool>(aIsSynthesizedForTests)) {
     82    if (aLastPointerInfo) {
     83      TakeOverLastState(*aLastPointerInfo);
     84    }
     85  }
     86  explicit PointerInfo(Active aActiveState,
     87                       const WidgetPointerEvent& aPointerEvent,
     88                       Document* aActiveDocument,
     89                       const PointerInfo* aLastPointerInfo = nullptr)
     90      : mActiveDocument(aActiveDocument),
     91        mInputSource(aPointerEvent.mInputSource),
     92        mIsActive(static_cast<bool>(aActiveState)),
     93        mIsPrimary(aPointerEvent.mIsPrimary),
     94        mFromTouchEvent(aPointerEvent.mFromTouchEvent),
     95        mPreventMouseEventByContent(false),
     96        mIsSynthesizedForTests(aPointerEvent.mFlags.mIsSynthesizedForTests) {
     97    if (aLastPointerInfo) {
     98      TakeOverLastState(*aLastPointerInfo);
     99    }
    100  }
    101 
    102  [[nodiscard]] bool InputSourceSupportsHover() const {
    103    return WidgetMouseEventBase::InputSourceSupportsHover(mInputSource);
    104  }
    105 
    106  [[nodiscard]] bool HasLastState() const {
    107    return mLastRefPointInRootDoc !=
    108           nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
    109  }
    110 
    111  /**
    112   * Make this store the last pointer state such as the position, buttons, etc,
    113   * which should be used at dispatching a synthetic mouse/pointer move.
    114   */
    115  void RecordLastState(const nsPoint& aRefPointInRootDoc,
    116                       const WidgetMouseEvent& aMouseOrPointerEvent) {
    117    MOZ_ASSERT_IF(aMouseOrPointerEvent.mMessage == eMouseMove ||
    118                      aMouseOrPointerEvent.mMessage == ePointerMove,
    119                  aMouseOrPointerEvent.IsReal());
    120 
    121    mLastRefPointInRootDoc = aRefPointInRootDoc;
    122    mLastTargetGuid = layers::InputAPZContext::GetTargetLayerGuid();
    123    // FIXME: DragEvent may not be initialized with the proper state.  So,
    124    // ignore the details of drag events for now.
    125    if (aMouseOrPointerEvent.mClass != eDragEventClass) {
    126      mLastTiltX = aMouseOrPointerEvent.tiltX;
    127      mLastTiltY = aMouseOrPointerEvent.tiltY;
    128      mLastButtons = aMouseOrPointerEvent.mButtons;
    129      mLastPressure = aMouseOrPointerEvent.mPressure;
    130    }
    131  }
    132 
    133  /**
    134   * Take over the last pointer state from older PointerInfo.
    135   */
    136  void TakeOverLastState(const PointerInfo& aPointerInfo) {
    137    mLastRefPointInRootDoc = aPointerInfo.mLastRefPointInRootDoc;
    138    mLastTargetGuid = aPointerInfo.mLastTargetGuid;
    139    mLastTiltX = aPointerInfo.mLastTiltX;
    140    mLastTiltY = aPointerInfo.mLastTiltY;
    141    mLastButtons = aPointerInfo.mLastButtons;
    142    mLastPressure = aPointerInfo.mLastPressure;
    143  }
    144 
    145  /**
    146   * Clear the last pointer state to stop dispatching synthesized mouse/pointer
    147   * move at the position.
    148   */
    149  void ClearLastState() {
    150    mLastRefPointInRootDoc =
    151        nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
    152    mLastTargetGuid = layers::ScrollableLayerGuid();
    153    mLastTiltX = 0;
    154    mLastTiltY = 0;
    155    mLastButtons = 0;
    156    mLastPressure = 0.0f;
    157  }
    158 
    159  [[nodiscard]] bool EqualsBasicPointerData(const PointerInfo& aOther) const {
    160    return mInputSource == aOther.mInputSource &&
    161           mIsActive == aOther.mIsActive && mIsPrimary == aOther.mIsPrimary &&
    162           mFromTouchEvent == aOther.mFromTouchEvent &&
    163           mIsSynthesizedForTests == aOther.mIsSynthesizedForTests;
    164  }
    165 
    166  // mLastRefPointInRootDoc stores the event point relative to the root
    167  // PresShell.  So, it's different from the WidgetEvent::mRefPoint.
    168  nsPoint mLastRefPointInRootDoc =
    169      nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
    170  layers::ScrollableLayerGuid mLastTargetGuid;
    171  WeakPtr<Document> mActiveDocument;
    172  // mInputSource indicates which input source caused the last event.  E.g.,
    173  // if the last event is a compatibility mouse event, the input source is
    174  // "touch".
    175  uint16_t mInputSource = 0;
    176  int32_t mLastTiltX = 0;
    177  int32_t mLastTiltY = 0;
    178  int16_t mLastButtons = 0;
    179  float mLastPressure = 0.0f;
    180  bool mIsActive : 1;
    181  bool mIsPrimary : 1;
    182  // mFromTouchEvent is set to true if the last event is a touch event or a
    183  // pointer event caused by a touch event.  If the last event is a
    184  // compatibility mouse event, this is set to false even though the input
    185  // source is "touch".
    186  bool mFromTouchEvent : 1;
    187  bool mPreventMouseEventByContent : 1;
    188  // Set to true if the pointer is activated only by synthesized mouse events.
    189  bool mIsSynthesizedForTests : 1;
    190 };
    191 
    192 class PointerEventHandler final {
    193 public:
    194  // Called in nsLayoutStatics::Initialize/Shutdown to initialize pointer event
    195  // related static variables.
    196  static void InitializeStatics();
    197  static void ReleaseStatics();
    198 
    199  // Return the preference value of implicit capture.
    200  static bool IsPointerEventImplicitCaptureForTouchEnabled();
    201 
    202  /**
    203   * Dispatch a pointer event on aTargetWeakFrame if and only if the frame is
    204   * available or aTargetContent if the target content does not have a frame.
    205   *
    206   * This follows the steps of "fire a pointer event" definition.
    207   * https://w3c.github.io/pointerevents/#dfn-fire-a-pointer-event
    208   *
    209   * @param aPointerEventMessage The event message which you want to dispatch a
    210   * pointer event.
    211   * @param aMouseOrPointerEvent The source event which caused the dispatching
    212   * pointer event.  Must be a mouse or pointer event.
    213   * @param aTargetWeakFrame If target frame is available, this should be set to
    214   * non-nullptr.
    215   * @param aTargetContent If target frame is not available for the content
    216   * node, set this to the proper target node.
    217   * @param aStatus [optional, out] The dispatched event status.
    218   */
    219  MOZ_CAN_RUN_SCRIPT static nsresult DispatchPointerEventWithTarget(
    220      EventMessage aPointerEventMessage,
    221      const WidgetMouseEvent& aMouseOrPointerEvent,
    222      const AutoWeakFrame& aTargetWeakFrame, nsIContent* aTargetContent,
    223      nsEventStatus* aStatus = nullptr);
    224 
    225  /**
    226   * Dispatch a pointer event on aTargetWeakFrame if and only if the frame is
    227   * available or aTargetContent if the target content does not have a frame.
    228   *
    229   * This follows the steps of "fire a pointer event" definition.
    230   * https://w3c.github.io/pointerevents/#dfn-fire-a-pointer-event
    231   *
    232   * @param aPointerEventMessage The event message which you want to dispatch a
    233   * pointer event.
    234   * @param aTouchEvent The source touch event which caused the dispatching
    235   * pointer event.
    236   * @param aTouchIndex The source touch index in aTouchEvent.
    237   * @param aTargetWeakFrame If target frame is available, this should be set to
    238   * non-nullptr.
    239   * @param aTargetContent If target frame is not available for the content
    240   * node, set this to the proper target node.
    241   * @param aStatus [optional, in/out] The dispatched event status.
    242   */
    243  MOZ_CAN_RUN_SCRIPT static nsresult DispatchPointerEventWithTarget(
    244      EventMessage aPointerEventMessage, const WidgetTouchEvent& aTouchEvent,
    245      size_t aTouchIndex, const AutoWeakFrame& aTargetWeakFrame,
    246      nsIContent* aTargetContent, nsEventStatus* aStatus = nullptr);
    247 
    248  /**
    249   * Dispatch a pointer event on aTargetWeakFrame if and only if the frame is
    250   * available or aTargetContent if the target content does not have a frame.
    251   *
    252   * This follows the steps of "fire a pointer event" definition.
    253   * https://w3c.github.io/pointerevents/#dfn-fire-a-pointer-event
    254   *
    255   * @param aPointerEvent The pointer event which should be dispatched.
    256   * @param aTouchIndex The source touch index in aTouchEvent.
    257   * @param aTargetWeakFrame If target frame is available, this should be set to
    258   * non-nullptr.
    259   * @param aTargetContent If target frame is not available for the content
    260   * node, set this to the proper target node.
    261   * @param aStatus [optional, in/out] The dispatched event status.
    262   */
    263  MOZ_CAN_RUN_SCRIPT static nsresult DispatchPointerEventWithTarget(
    264      WidgetPointerEvent& aPointerEvent, const AutoWeakFrame& aTargetWeakFrame,
    265      nsIContent* aTargetContent, nsEventStatus* aStatus = nullptr);
    266 
    267  /**
    268   * Return true if click/auxclick/contextmenu event should be fired on
    269   * an element which was capturing the pointer at dispatching ePointerUp.
    270   *
    271   * @param aSourceEvent    [Optional] The source event which causes the
    272   *                        `click`, `auxclick` or `contextmenu` event.  I.e.,
    273   *                        must be one of `mouseup`, `pointerup` or `touchend`.
    274   *                        If specifying nullptr, this method checks only
    275   *                        whether the behavior is enabled.
    276   */
    277  [[nodiscard]] static bool ShouldDispatchClickEventOnCapturingElement(
    278      const WidgetGUIEvent* aSourceEvent = nullptr);
    279 
    280  // Called in ESM::PreHandleEvent to update current active pointers in a hash
    281  // table.
    282  static void UpdatePointerActiveState(WidgetMouseEvent* aEvent,
    283                                       nsIContent* aTargetContent = nullptr);
    284 
    285  /**
    286   * Called when PresShell starts handling a mouse or subclass event.  This will
    287   * set PointerInfo for synthesizing pointer move at the position later.
    288   *
    289   * @param aRefPointInRootPresShell    The event location in the root
    290   *                                    PresShell.
    291   * @param aMouseEvent                 The event which will be handled.
    292   */
    293  static void RecordPointerState(const nsPoint& aRefPointInRootPresShell,
    294                                 const WidgetMouseEvent& aMouseEvent);
    295 
    296  /**
    297   * Called when PresShell starts handling a mouse event.  The data will be used
    298   * for synthesizing eMouseMove to dispatch mouse boundary events and updates
    299   * `:hover` state.
    300   *
    301   * @param aRootPresShell      Must be the root PresShell of the PresShell
    302   *                            which starts handling the event.
    303   * @param aMouseEvent         The mouse event which the PresShell starts
    304   *                            handling.
    305   */
    306  static void RecordMouseState(PresShell& aRootPresShell,
    307                               const WidgetMouseEvent& aMouseEvent);
    308 
    309  /**
    310   * Called when PresShell dispatches a mouse event to the DOM.
    311   */
    312  static void RecordMouseButtons(const WidgetMouseEvent& aMouseEvent) {
    313    // Buttons of mouse should be shared even if there are multiple mouse
    314    // pointers which has different pointerIds for the backward compatibility.
    315    // Thus, here does not check sLastMousePresShell nor pointerId.
    316    if (sLastMouseInfo) {
    317      sLastMouseInfo->mLastButtons = aMouseEvent.mButtons;
    318    }
    319  }
    320 
    321  /**
    322   * Called when PresShell starts handling a mouse event or something which
    323   * should make aRootPresShell should never dispatch synthetic eMouseMove
    324   * events.
    325   *
    326   * @param aRootPresShell      Must be the root PresShell of the PresShell
    327   *                            which starts handling the event.
    328   * @param aMouseEvent         The mouse event which the PresShell starts
    329   *                            handling.
    330   */
    331  static void ClearMouseState(PresShell& aRootPresShell,
    332                              const WidgetMouseEvent& aMouseEvent);
    333 
    334  // Request/release pointer capture of the specified pointer by the element.
    335  static void RequestPointerCaptureById(uint32_t aPointerId,
    336                                        dom::Element* aElement);
    337  static void ReleasePointerCaptureById(uint32_t aPointerId);
    338  static void ReleaseAllPointerCapture();
    339 
    340  // Set/release pointer capture of the specified pointer by the remote target.
    341  // Should only be called in parent process.
    342  static bool SetPointerCaptureRemoteTarget(uint32_t aPointerId,
    343                                            dom::BrowserParent* aBrowserParent);
    344  static void ReleasePointerCaptureRemoteTarget(
    345      dom::BrowserParent* aBrowserParent);
    346  static void ReleasePointerCaptureRemoteTarget(uint32_t aPointerId);
    347  static void ReleaseAllPointerCaptureRemoteTarget();
    348 
    349  // Get the pointer capturing remote target of the specified pointer.
    350  static dom::BrowserParent* GetPointerCapturingRemoteTarget(
    351      uint32_t aPointerId);
    352 
    353  // Get the pointer captured info of the specified pointer.
    354  static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId);
    355 
    356  // Return the PointerInfo if the pointer with aPointerId is situated in
    357  // device, nullptr otherwise.
    358  // Note that the result may be activated only by synthesized events for test.
    359  // If you don't want it, check PointerInfo::mIsSynthesizedForTests.
    360  static const PointerInfo* GetPointerInfo(uint32_t aPointerId);
    361 
    362  /**
    363   * Return the PointeInfo which stores the last mouse event state which should
    364   * be used for dispatching a synthetic eMouseMove.
    365   *
    366   * @param aRootPresShell      [optional] If specified, return non-nullptr if
    367   *                            and only if the last mouse info was set by
    368   *                            aRootPresShell.  Otherwise, return the last
    369   *                            mouse info which was set by any PresShell.
    370   */
    371  [[nodiscard]] static const PointerInfo* GetLastMouseInfo(
    372      const PresShell* aRootPresShell = nullptr);
    373 
    374  /**
    375   * Return the last pointerId which has not left from any documents managed in
    376   * this process.
    377   */
    378  [[nodiscard]] static Maybe<uint32_t> GetLastPointerId() {
    379    return sLastPointerId;
    380  }
    381  /**
    382   * Retrun true if aPointerId is the last pointerId.
    383   */
    384  [[nodiscard]] static bool IsLastPointerId(uint32_t aPointerId) {
    385    return sLastPointerId && *sLastPointerId == aPointerId;
    386  }
    387 
    388  // CheckPointerCaptureState checks cases, when got/lostpointercapture events
    389  // should be fired.
    390  MOZ_CAN_RUN_SCRIPT
    391  static void MaybeProcessPointerCapture(WidgetGUIEvent* aEvent);
    392  MOZ_CAN_RUN_SCRIPT
    393  static void ProcessPointerCaptureForMouse(WidgetMouseEvent* aEvent);
    394  MOZ_CAN_RUN_SCRIPT
    395  static void ProcessPointerCaptureForTouch(WidgetTouchEvent* aEvent);
    396  MOZ_CAN_RUN_SCRIPT
    397  static void CheckPointerCaptureState(WidgetPointerEvent* aEvent);
    398 
    399  // Implicitly get and release capture of current pointer for touch.
    400  static void ImplicitlyCapturePointer(nsIFrame* aFrame, WidgetEvent* aEvent);
    401  MOZ_CAN_RUN_SCRIPT
    402  static void ImplicitlyReleasePointerCapture(WidgetEvent* aEvent);
    403  MOZ_CAN_RUN_SCRIPT static void MaybeImplicitlyReleasePointerCapture(
    404      WidgetGUIEvent* aEvent);
    405 
    406  /**
    407   * GetPointerCapturingContent returns a target element which captures the
    408   * pointer. It's applied to mouse or pointer event (except mousedown and
    409   * pointerdown). When capturing, return the element. Otherwise, nullptr.
    410   *
    411   * @param aEvent               A mouse event or pointer event which may be
    412   *                             captured.
    413   *
    414   * @return                     Target element for aEvent.
    415   */
    416  static dom::Element* GetPointerCapturingElement(const WidgetGUIEvent* aEvent);
    417 
    418  static dom::Element* GetPointerCapturingElement(uint32_t aPointerId);
    419 
    420  /**
    421   * Return pending capture element of for the pointerId (of the event).
    422   * - If the element has already overriden the pointer capture and there is no
    423   * new pending capture element, the result is what captures the pointer right
    424   * now.
    425   * - If the element has not overriden the pointer capture, the result will
    426   * start capturing the pointer once the pending pointer capture is processed
    427   * at dispatching a pointer event later.
    428   *
    429   * So, in other words, the result is the element which will capture the next
    430   * pointer event for the pointerId.
    431   */
    432  static dom::Element* GetPendingPointerCapturingElement(
    433      const WidgetGUIEvent* aEvent);
    434  static dom::Element* GetPendingPointerCapturingElement(uint32_t aPointerId);
    435 
    436  /**
    437   * Return an element which captured the pointer at dispatching the last
    438   * ePointerUp event caused by eMouseUp except the compatibility mouse events
    439   * of Touch Events or caused by eTouchEnd whose number of touches is one,
    440   * i.e., the last touch release.
    441   */
    442  [[nodiscard]] static RefPtr<dom::Element>
    443  GetPointerCapturingElementAtLastPointerUp();
    444 
    445  /**
    446   * Forget the pointer capturing element at dispatching the last ePointerUp.
    447   */
    448  static void ReleasePointerCapturingElementAtLastPointerUp();
    449 
    450  // Release pointer capture if captured by the specified content or it's
    451  // descendant. This is called to handle the case that the pointer capturing
    452  // content or it's parent is removed from the document.
    453  static void ReleaseIfCaptureByDescendant(nsIContent* aContent);
    454 
    455  /*
    456   * This function handles the case when content had called preventDefault on
    457   * the active pointer. In that case we have to prevent firing subsequent mouse
    458   * to content. We check the flag PointerInfo::mPreventMouseEventByContent and
    459   * call PreventDefault(false) to stop default behaviors and stop firing mouse
    460   * events to content and chrome.
    461   *
    462   * note: mouse transition events are excluded
    463   * note: we have to clean mPreventMouseEventByContent on pointerup for those
    464   *       devices support hover
    465   * note: we don't suppress firing mouse events to chrome and system group
    466   *       handlers because they may implement default behaviors
    467   */
    468  static void PreHandlePointerEventsPreventDefault(
    469      WidgetPointerEvent* aPointerEvent, WidgetGUIEvent* aMouseOrTouchEvent);
    470 
    471  /*
    472   * This function handles the preventDefault behavior of pointerdown. When user
    473   * preventDefault on pointerdown, We have to mark the active pointer to
    474   * prevent sebsequent mouse events (except mouse transition events) and
    475   * default behaviors.
    476   *
    477   * We add mPreventMouseEventByContent flag in PointerInfo to represent the
    478   * active pointer won't firing compatible mouse events. It's set to true when
    479   * content preventDefault on pointerdown
    480   */
    481  static void PostHandlePointerEventsPreventDefault(
    482      WidgetPointerEvent* aPointerEvent, WidgetGUIEvent* aMouseOrTouchEvent);
    483 
    484  /**
    485   * Dispatch a pointer event for aMouseOrTouchEvent to aEventTargetContent.
    486   *
    487   * @param aShell              The PresShell which is handling the event.
    488   * @param aEventTargetFrame   The frame for aEventTargetContent.
    489   * @param aEventTargetContent The event target node.
    490   * @param aPointerCapturingElement
    491   *                            The pointer capturing element.
    492   * @param aMouseOrTouchEvent  A mouse or touch event.
    493   * @param aDontRetargetEvents If true, this won't dispatch event with
    494   *                            different PresShell from aShell.  Otherwise,
    495   *                            pointer events may be fired on different
    496   *                            document if and only if aMouseOrTOuchEvent is a
    497   *                            touch event except eTouchStart.
    498   * @param aState              [out] The result of the pointer event.
    499   * @param aMouseOrTouchEventTarget
    500   *                            [out] The event target for the following mouse
    501   *                            or touch event. If aEventTargetContent has not
    502   *                            been removed from the tree, this is always set
    503   *                            to it. If aEventTargetContent is removed from
    504   *                            the tree and aMouseOrTouchEvent is a mouse
    505   *                            event, this is set to inclusive ancestor of
    506   *                            aEventTargetContent which is still connected.
    507   *                            If aEventTargetContent is removed from the tree
    508   *                            and aMouseOrTouchEvent is a touch event, this is
    509   *                            set to aEventTargetContent because touch event
    510   *                            should be dispatched even on disconnected node.
    511   *                            FIXME: If the event is a touch event but the
    512   *                            message is not eTouchStart, this won't be set.
    513   */
    514  MOZ_CAN_RUN_SCRIPT static void DispatchPointerFromMouseOrTouch(
    515      PresShell* aShell, nsIFrame* aEventTargetFrame,
    516      nsIContent* aEventTargetContent, dom::Element* aPointerCapturingElement,
    517      WidgetGUIEvent* aMouseOrTouchEvent, bool aDontRetargetEvents,
    518      nsEventStatus* aStatus, nsIContent** aMouseOrTouchEventTarget = nullptr);
    519 
    520  /**
    521   * Synthesize eMouseMove or ePointerMove to dispatch mouse/pointer boundary
    522   * events if they are required.  This dispatches the event on the widget.
    523   * Therefore, this dispatches the event on correct document in the same
    524   * process.  However, if there is a popup under the pointer or a document in a
    525   * different process, this does not work as you expected.
    526   */
    527  MOZ_CAN_RUN_SCRIPT static void SynthesizeMoveToDispatchBoundaryEvents(
    528      const WidgetMouseEvent* aEvent);
    529 
    530  static void InitPointerEventFromMouse(WidgetPointerEvent* aPointerEvent,
    531                                        const WidgetMouseEvent* aMouseEvent,
    532                                        EventMessage aMessage);
    533 
    534  static void InitPointerEventFromTouch(WidgetPointerEvent& aPointerEvent,
    535                                        const WidgetTouchEvent& aTouchEvent,
    536                                        const mozilla::dom::Touch& aTouch);
    537 
    538  static void InitCoalescedEventFromPointerEvent(
    539      WidgetPointerEvent& aCoalescedEvent,
    540      const WidgetPointerEvent& aSourceEvent);
    541 
    542  static bool ShouldGeneratePointerEventFromMouse(WidgetGUIEvent* aEvent) {
    543    return aEvent->mMessage == eMouseRawUpdate ||
    544           aEvent->mMessage == eMouseDown || aEvent->mMessage == eMouseUp ||
    545           (aEvent->mMessage == eMouseMove &&
    546            aEvent->AsMouseEvent()->IsReal()) ||
    547           aEvent->mMessage == eMouseExitFromWidget;
    548  }
    549 
    550  static bool ShouldGeneratePointerEventFromTouch(WidgetGUIEvent* aEvent) {
    551    return aEvent->mMessage == eTouchRawUpdate ||
    552           aEvent->mMessage == eTouchStart || aEvent->mMessage == eTouchMove ||
    553           aEvent->mMessage == eTouchEnd || aEvent->mMessage == eTouchCancel ||
    554           aEvent->mMessage == eTouchPointerCancel;
    555  }
    556 
    557  static MOZ_ALWAYS_INLINE int32_t GetSpoofedPointerIdForRFP() {
    558    return sSpoofedPointerId.valueOr(0);
    559  }
    560 
    561  static void NotifyDestroyPresContext(nsPresContext* aPresContext);
    562 
    563  static bool IsDragAndDropEnabled(WidgetMouseEvent& aEvent);
    564 
    565  // Get proper pointer event message for a mouse or touch event.
    566  [[nodiscard]] static EventMessage ToPointerEventMessage(
    567      const WidgetGUIEvent* aMouseOrTouchEvent);
    568 
    569  /**
    570   * Return true if the window containing aDocument has had a
    571   * `pointerrawupdate` event listener.
    572   */
    573  [[nodiscard]] static bool NeedToDispatchPointerRawUpdate(
    574      const dom::Document* aDocument);
    575 
    576  /**
    577   * Return a log module reference for logging the mouse location.
    578   */
    579  [[nodiscard]] static LazyLogModule& MouseLocationLogRef();
    580 
    581  /**
    582   * Return a log module reference for logging the pointer location.
    583   */
    584  [[nodiscard]] static LazyLogModule& PointerLocationLogRef();
    585 
    586 private:
    587  // Set pointer capture of the specified pointer by the element.
    588  static void SetPointerCaptureById(uint32_t aPointerId,
    589                                    dom::Element* aElement);
    590 
    591  // GetPointerType returns pointer type like mouse, pen or touch for pointer
    592  // event with pointerId. The return value must be one of
    593  // MouseEvent_Binding::MOZ_SOURCE_*
    594  static uint16_t GetPointerType(uint32_t aPointerId);
    595 
    596  // GetPointerPrimaryState returns state of attribute isPrimary for pointer
    597  // event with pointerId
    598  static bool GetPointerPrimaryState(uint32_t aPointerId);
    599 
    600  // HasActiveTouchPointer returns true if there is active pointer event that is
    601  // generated from touch event.
    602  static bool HasActiveTouchPointer();
    603 
    604  MOZ_CAN_RUN_SCRIPT
    605  static void DispatchGotOrLostPointerCaptureEvent(
    606      bool aIsGotCapture, const WidgetPointerEvent* aPointerEvent,
    607      dom::Element* aCaptureTarget);
    608 
    609  enum class CapturingState { Pending, Override };
    610  static dom::Element* GetPointerCapturingElementInternal(
    611      CapturingState aCapturingState, const WidgetGUIEvent* aEvent);
    612 
    613  // The cached spoofed pointer ID for fingerprinting resistance. We will use a
    614  // mouse pointer id for desktop. For mobile, we should use the touch pointer
    615  // id as the spoofed one, and this work will be addressed in Bug 1492775.
    616  static Maybe<int32_t> sSpoofedPointerId;
    617 
    618  // A helper function to cache the pointer id of the spoofed interface, we
    619  // would only cache the pointer id once. After that, we would always stick to
    620  // that pointer id for fingerprinting resistance.
    621  static void MaybeCacheSpoofedPointerID(uint16_t aInputSource,
    622                                         uint32_t aPointerId);
    623 
    624  /**
    625   * Store the pointer capturing element.
    626   */
    627  static void SetPointerCapturingElementAtLastPointerUp(
    628      nsWeakPtr&& aPointerCapturingElement);
    629 
    630  /**
    631   * Insert/update a pointer to/in sActivePointerIds.
    632   */
    633  static const UniquePtr<PointerInfo>& InsertOrUpdateActivePointer(
    634      uint32_t aPointerId, UniquePtr<PointerInfo>&& aNewPointerInfo,
    635      EventMessage aEventMessage, const char* aCallerName);
    636 
    637  /**
    638   * Remove a pointer from sActivePointerIds.
    639   */
    640  static void RemoveActivePointer(uint32_t aPointerId,
    641                                  EventMessage aEventMessage,
    642                                  const char* aCallerName);
    643 
    644  /**
    645   * Called when a new pointer event is bing fired.
    646   */
    647  static void UpdateLastPointerId(uint32_t aPointerId,
    648                                  EventMessage aEventMessage);
    649 
    650  /**
    651   * Called when a pointer is leaving from this process.
    652   */
    653  static void MaybeForgetLastPointerId(uint32_t aPointerId,
    654                                       EventMessage aEventMessage);
    655 
    656  // Stores the last mouse info to dispatch synthetic eMouseMove in root
    657  // PresShells.
    658  static StaticAutoPtr<PointerInfo> sLastMouseInfo;
    659 
    660  // Stores the last mouse info setter.
    661  static StaticRefPtr<nsIWeakReference> sLastMousePresShell;
    662 
    663  // Stores the last pointerId which has not left from all documents managed in
    664  // this process.
    665  static Maybe<uint32_t> sLastPointerId;
    666 };
    667 
    668 }  // namespace mozilla
    669 
    670 #endif  // mozilla_PointerEventHandler_h