Bug 1686668 [wpt PR 27185] - Update wpt metadata, a=testonly
[gecko.git] / dom / events / PointerEventHandler.h
blobdd0b1bea408a89647bf68fd02fe32b4e0bd6f27f
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/. */
7 #ifndef mozilla_PointerEventHandler_h
8 #define mozilla_PointerEventHandler_h
10 #include "mozilla/EventForwards.h"
11 #include "mozilla/MouseEvents.h"
12 #include "mozilla/TouchEvents.h"
13 #include "mozilla/WeakPtr.h"
15 // XXX Avoid including this here by moving function bodies to the cpp file
16 #include "mozilla/dom/Document.h"
17 #include "mozilla/dom/Element.h"
19 class nsIFrame;
20 class nsIContent;
21 class nsPresContext;
23 namespace mozilla {
25 class PresShell;
27 namespace dom {
28 class BrowserParent;
29 class Document;
30 class Element;
31 }; // namespace dom
33 class PointerCaptureInfo final {
34 public:
35 RefPtr<dom::Element> mPendingElement;
36 RefPtr<dom::Element> mOverrideElement;
38 explicit PointerCaptureInfo(dom::Element* aPendingElement)
39 : mPendingElement(aPendingElement) {
40 MOZ_COUNT_CTOR(PointerCaptureInfo);
43 MOZ_COUNTED_DTOR(PointerCaptureInfo)
45 bool Empty() { return !(mPendingElement || mOverrideElement); }
48 class PointerInfo final {
49 public:
50 uint16_t mPointerType;
51 bool mActiveState;
52 bool mPrimaryState;
53 bool mPreventMouseEventByContent;
54 WeakPtr<dom::Document> mActiveDocument;
55 explicit PointerInfo(bool aActiveState, uint16_t aPointerType,
56 bool aPrimaryState, dom::Document* aActiveDocument)
57 : mPointerType(aPointerType),
58 mActiveState(aActiveState),
59 mPrimaryState(aPrimaryState),
60 mPreventMouseEventByContent(false),
61 mActiveDocument(aActiveDocument) {}
64 class PointerEventHandler final {
65 public:
66 // Called in nsLayoutStatics::Initialize/Shutdown to initialize pointer event
67 // related static variables.
68 static void InitializeStatics();
69 static void ReleaseStatics();
71 // Return the preference value of implicit capture.
72 static bool IsPointerEventImplicitCaptureForTouchEnabled();
74 // Called in ESM::PreHandleEvent to update current active pointers in a hash
75 // table.
76 static void UpdateActivePointerState(WidgetMouseEvent* aEvent,
77 nsIContent* aTargetContent = nullptr);
79 // Request/release pointer capture of the specified pointer by the element.
80 static void RequestPointerCaptureById(uint32_t aPointerId,
81 dom::Element* aElement);
82 static void ReleasePointerCaptureById(uint32_t aPointerId);
83 static void ReleaseAllPointerCapture();
85 // Set/release pointer capture of the specified pointer by the remote target.
86 // Should only be called in parent process.
87 static bool SetPointerCaptureRemoteTarget(uint32_t aPointerId,
88 dom::BrowserParent* aBrowserParent);
89 static void ReleasePointerCaptureRemoteTarget(
90 dom::BrowserParent* aBrowserParent);
91 static void ReleasePointerCaptureRemoteTarget(uint32_t aPointerId);
92 static void ReleaseAllPointerCaptureRemoteTarget();
94 // Get the pointer capturing remote target of the specified pointer.
95 static dom::BrowserParent* GetPointerCapturingRemoteTarget(
96 uint32_t aPointerId);
98 // Get the pointer captured info of the specified pointer.
99 static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId);
101 // Return the PointerInfo if the pointer with aPointerId is situated in device
102 // , nullptr otherwise.
103 static const PointerInfo* GetPointerInfo(uint32_t aPointerId);
105 // CheckPointerCaptureState checks cases, when got/lostpointercapture events
106 // should be fired.
107 MOZ_CAN_RUN_SCRIPT
108 static void MaybeProcessPointerCapture(WidgetGUIEvent* aEvent);
109 MOZ_CAN_RUN_SCRIPT
110 static void ProcessPointerCaptureForMouse(WidgetMouseEvent* aEvent);
111 MOZ_CAN_RUN_SCRIPT
112 static void ProcessPointerCaptureForTouch(WidgetTouchEvent* aEvent);
113 MOZ_CAN_RUN_SCRIPT
114 static void CheckPointerCaptureState(WidgetPointerEvent* aEvent);
116 // Implicitly get and release capture of current pointer for touch.
117 static void ImplicitlyCapturePointer(nsIFrame* aFrame, WidgetEvent* aEvent);
118 MOZ_CAN_RUN_SCRIPT
119 static void ImplicitlyReleasePointerCapture(WidgetEvent* aEvent);
122 * GetPointerCapturingContent returns a target element which captures the
123 * pointer. It's applied to mouse or pointer event (except mousedown and
124 * pointerdown). When capturing, return the element. Otherwise, nullptr.
126 * @param aEvent A mouse event or pointer event which may be
127 * captured.
129 * @return Target element for aEvent.
131 static dom::Element* GetPointerCapturingElement(WidgetGUIEvent* aEvent);
133 static dom::Element* GetPointerCapturingElement(uint32_t aPointerId);
135 // Release pointer capture if captured by the specified content or it's
136 // descendant. This is called to handle the case that the pointer capturing
137 // content or it's parent is removed from the document.
138 static void ReleaseIfCaptureByDescendant(nsIContent* aContent);
141 * This function handles the case when content had called preventDefault on
142 * the active pointer. In that case we have to prevent firing subsequent mouse
143 * to content. We check the flag PointerInfo::mPreventMouseEventByContent and
144 * call PreventDefault(false) to stop default behaviors and stop firing mouse
145 * events to content and chrome.
147 * note: mouse transition events are excluded
148 * note: we have to clean mPreventMouseEventByContent on pointerup for those
149 * devices support hover
150 * note: we don't suppress firing mouse events to chrome and system group
151 * handlers because they may implement default behaviors
153 static void PreHandlePointerEventsPreventDefault(
154 WidgetPointerEvent* aPointerEvent, WidgetGUIEvent* aMouseOrTouchEvent);
157 * This function handles the preventDefault behavior of pointerdown. When user
158 * preventDefault on pointerdown, We have to mark the active pointer to
159 * prevent sebsequent mouse events (except mouse transition events) and
160 * default behaviors.
162 * We add mPreventMouseEventByContent flag in PointerInfo to represent the
163 * active pointer won't firing compatible mouse events. It's set to true when
164 * content preventDefault on pointerdown
166 static void PostHandlePointerEventsPreventDefault(
167 WidgetPointerEvent* aPointerEvent, WidgetGUIEvent* aMouseOrTouchEvent);
169 MOZ_CAN_RUN_SCRIPT
170 static void DispatchPointerFromMouseOrTouch(
171 PresShell* aShell, nsIFrame* aFrame, nsIContent* aContent,
172 WidgetGUIEvent* aEvent, bool aDontRetargetEvents, nsEventStatus* aStatus,
173 nsIContent** aTargetContent);
175 static void InitPointerEventFromMouse(WidgetPointerEvent* aPointerEvent,
176 WidgetMouseEvent* aMouseEvent,
177 EventMessage aMessage);
179 static void InitPointerEventFromTouch(WidgetPointerEvent* aPointerEvent,
180 WidgetTouchEvent* aTouchEvent,
181 mozilla::dom::Touch* aTouch,
182 bool aIsPrimary);
184 static bool ShouldGeneratePointerEventFromMouse(WidgetGUIEvent* aEvent) {
185 return aEvent->mMessage == eMouseDown || aEvent->mMessage == eMouseUp ||
186 aEvent->mMessage == eMouseMove ||
187 aEvent->mMessage == eMouseExitFromWidget;
190 static bool ShouldGeneratePointerEventFromTouch(WidgetGUIEvent* aEvent) {
191 return aEvent->mMessage == eTouchStart || aEvent->mMessage == eTouchMove ||
192 aEvent->mMessage == eTouchEnd || aEvent->mMessage == eTouchCancel ||
193 aEvent->mMessage == eTouchPointerCancel;
196 static MOZ_ALWAYS_INLINE int32_t GetSpoofedPointerIdForRFP() {
197 return sSpoofedPointerId.valueOr(0);
200 static void NotifyDestroyPresContext(nsPresContext* aPresContext);
202 private:
203 // Set pointer capture of the specified pointer by the element.
204 static void SetPointerCaptureById(uint32_t aPointerId,
205 dom::Element* aElement);
207 // GetPointerType returns pointer type like mouse, pen or touch for pointer
208 // event with pointerId. The return value must be one of
209 // MouseEvent_Binding::MOZ_SOURCE_*
210 static uint16_t GetPointerType(uint32_t aPointerId);
212 // GetPointerPrimaryState returns state of attribute isPrimary for pointer
213 // event with pointerId
214 static bool GetPointerPrimaryState(uint32_t aPointerId);
216 MOZ_CAN_RUN_SCRIPT
217 static void DispatchGotOrLostPointerCaptureEvent(
218 bool aIsGotCapture, const WidgetPointerEvent* aPointerEvent,
219 dom::Element* aCaptureTarget);
221 // The cached spoofed pointer ID for fingerprinting resistance. We will use a
222 // mouse pointer id for desktop. For mobile, we should use the touch pointer
223 // id as the spoofed one, and this work will be addressed in Bug 1492775.
224 static Maybe<int32_t> sSpoofedPointerId;
226 // A helper function to cache the pointer id of the spoofed interface, we
227 // would only cache the pointer id once. After that, we would always stick to
228 // that pointer id for fingerprinting resistance.
229 static void MaybeCacheSpoofedPointerID(uint16_t aInputSource,
230 uint32_t aPointerId);
233 } // namespace mozilla
235 #endif // mozilla_PointerEventHandler_h