Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / events / EventStateManager.h
bloba4e709d507025c4b7185eda8cdfba6f8e1d5669b
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_EventStateManager_h_
8 #define mozilla_EventStateManager_h_
10 #include "mozilla/EventForwards.h"
12 #include "nsIObserver.h"
13 #include "nsWeakReference.h"
14 #include "nsCOMPtr.h"
15 #include "nsCOMArray.h"
16 #include "nsCycleCollectionParticipant.h"
17 #include "nsRefPtrHashtable.h"
18 #include "mozilla/Attributes.h"
19 #include "mozilla/TimeStamp.h"
20 #include "mozilla/layers/APZPublicUtils.h"
21 #include "mozilla/dom/Record.h"
22 #include "Units.h"
23 #include "WheelHandlingHelper.h" // for WheelDeltaAdjustmentStrategy
25 class nsFrameLoader;
26 class nsIContent;
27 class nsICookieJarSettings;
28 class nsIDocShell;
29 class nsIDocShellTreeItem;
30 class nsIFrame;
31 class imgIContainer;
32 class nsIDocumentViewer;
33 class nsIScrollableFrame;
34 class nsITimer;
35 class nsPresContext;
37 enum class FormControlType : uint8_t;
39 namespace mozilla {
41 class EditorBase;
42 class EnterLeaveDispatcher;
43 class IMEContentObserver;
44 class ScrollbarsForWheel;
45 class TextControlElement;
46 class WheelTransaction;
48 namespace dom {
49 class DataTransfer;
50 class Document;
51 class Element;
52 class Selection;
53 class BrowserParent;
54 class RemoteDragStartData;
56 } // namespace dom
58 class OverOutElementsWrapper final : public nsISupports {
59 ~OverOutElementsWrapper() = default;
61 public:
62 enum class BoundaryEventType : bool { Mouse, Pointer };
63 explicit OverOutElementsWrapper(BoundaryEventType aType) : mType(aType) {}
65 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
66 NS_DECL_CYCLE_COLLECTION_CLASS(OverOutElementsWrapper)
68 void ContentRemoved(nsIContent& aContent);
69 void WillDispatchOverAndEnterEvent(nsIContent* aOverEventTarget) {
70 mDeepestEnterEventTarget = aOverEventTarget;
71 // Store the first "over" event target we fire and don't refire "over" event
72 // to that element while the first "over" event is still ongoing.
73 mDispatchingOverEventTarget = aOverEventTarget;
74 mDeepestEnterEventTargetIsOverEventTarget = true;
76 void DidDispatchOverAndEnterEvent(
77 nsIContent* aOriginalOverTargetInComposedDoc);
78 [[nodiscard]] bool IsDispatchingOverEventOn(
79 nsIContent* aOverEventTarget) const {
80 MOZ_ASSERT(aOverEventTarget);
81 return mDeepestEnterEventTargetIsOverEventTarget &&
82 mDeepestEnterEventTarget == aOverEventTarget;
84 void WillDispatchOutAndOrLeaveEvent() {
85 // Store the first "out" event target or the deepest "leave" event target
86 // which we fire and don't refire "out" event to that element while the
87 // first "out" event is still ongoing.
88 mDispatchingOutOrDeepestLeaveEventTarget = mDeepestEnterEventTarget;
90 void DidDispatchOutAndOrLeaveEvent() {
91 mLastOverFrame = nullptr;
92 mDeepestEnterEventTarget = mDispatchingOutOrDeepestLeaveEventTarget =
93 nullptr;
95 [[nodiscard]] bool IsDispatchingOutEventOnLastOverEventTarget() const {
96 return mDispatchingOutOrDeepestLeaveEventTarget &&
97 mDispatchingOutOrDeepestLeaveEventTarget == mDeepestEnterEventTarget;
99 void OverrideOverEventTarget(nsIContent* aOverEventTarget) {
100 mDeepestEnterEventTarget = aOverEventTarget;
101 mDeepestEnterEventTargetIsOverEventTarget = true;
104 [[nodiscard]] nsIContent* GetDeepestLeaveEventTarget() const {
105 // The last deepest "enter" event targe (it may be same as the last "over"
106 // target) is the deepest "leave" event target.
107 return mDeepestEnterEventTarget;
109 [[nodiscard]] nsIContent* GetOutEventTarget() const {
110 // The last deepest "enter" event target is same as the "over" event target
111 // unless it's never been removed from the DOM tree. If and only if the
112 // last "over" event target has not been removed from the DOM tree, it's
113 // the next "out" event target. Once the last "over" target is removed,
114 // "out" event should not be fired on the target nor its ancestor.
115 return mDeepestEnterEventTargetIsOverEventTarget
116 ? mDeepestEnterEventTarget.get()
117 : nullptr;
120 public:
121 WeakFrame mLastOverFrame;
123 private:
124 // The deepest event target of the last "enter" event. If
125 // mDeepestEnterEventTargetIsOverEventTarget is true, this is the last "over"
126 // event target too. If it's set to false, this is an ancestor of the last
127 // "over" event target which has not been removed from the DOM tree.
128 nsCOMPtr<nsIContent> mDeepestEnterEventTarget;
130 // While we're dispatching "over" and "enter" events, this is set to the
131 // "over" event target. If it's removed from the DOM tree, this is set to
132 // nullptr.
133 nsCOMPtr<nsIContent> mDispatchingOverEventTarget;
135 // While we're dispatching "out" and/or "leave" events, this is set to the
136 // "out" event target or the deepest leave event target. If it's removed from
137 // the DOM tree, this is set to nullptr.
138 nsCOMPtr<nsIContent> mDispatchingOutOrDeepestLeaveEventTarget;
140 const BoundaryEventType mType;
142 // Once the last "over" element is removed from the tree, this is set
143 // to false. Then, mDeepestEnterEventTarget may be an ancestor of the
144 // "over" element which should be the deepest target of next "leave"
145 // element but shouldn't be target of "out" event.
146 bool mDeepestEnterEventTargetIsOverEventTarget = true;
149 class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
150 friend class mozilla::EnterLeaveDispatcher;
151 friend class mozilla::ScrollbarsForWheel;
152 friend class mozilla::WheelTransaction;
154 using ElementState = dom::ElementState;
156 virtual ~EventStateManager();
158 public:
159 EventStateManager();
161 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
162 NS_DECL_NSIOBSERVER
164 nsresult Init();
165 nsresult Shutdown();
167 /* The PreHandleEvent method is called before event dispatch to either
168 * the DOM or frames. Any processing which must not be prevented or
169 * cancelled should occur here. Any processing which is intended to
170 * be conditional based on either DOM or frame processing should occur in
171 * PostHandleEvent. Any centralized event processing which must occur before
172 * DOM or frame event handling should occur here as well.
174 * aOverrideClickTarget can be used to indicate which element should be
175 * used as the *up target when deciding whether to send click event.
176 * This is used when releasing pointer capture. Otherwise null.
178 MOZ_CAN_RUN_SCRIPT
179 nsresult PreHandleEvent(nsPresContext* aPresContext, WidgetEvent* aEvent,
180 nsIFrame* aTargetFrame, nsIContent* aTargetContent,
181 nsEventStatus* aStatus,
182 nsIContent* aOverrideClickTarget);
184 /* The PostHandleEvent method should contain all system processing which
185 * should occur conditionally based on DOM or frame processing. It should
186 * also contain any centralized event processing which must occur after
187 * DOM and frame processing.
189 MOZ_CAN_RUN_SCRIPT
190 nsresult PostHandleEvent(nsPresContext* aPresContext, WidgetEvent* aEvent,
191 nsIFrame* aTargetFrame, nsEventStatus* aStatus,
192 nsIContent* aOverrideClickTarget);
194 MOZ_CAN_RUN_SCRIPT void PostHandleKeyboardEvent(
195 WidgetKeyboardEvent* aKeyboardEvent, nsIFrame* aTargetFrame,
196 nsEventStatus& aStatus);
199 * DispatchLegacyMouseScrollEvents() dispatches eLegacyMouseLineOrPageScroll
200 * event and eLegacyMousePixelScroll event for compatibility with old Gecko.
202 MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchLegacyMouseScrollEvents(
203 nsIFrame* aTargetFrame, WidgetWheelEvent* aEvent, nsEventStatus* aStatus);
205 MOZ_CAN_RUN_SCRIPT_BOUNDARY void NotifyDestroyPresContext(
206 nsPresContext* aPresContext);
208 void ResetHoverState();
210 void SetPresContext(nsPresContext* aPresContext);
211 void ClearFrameRefs(nsIFrame* aFrame);
213 nsIFrame* GetEventTarget();
214 already_AddRefed<nsIContent> GetEventTargetContent(WidgetEvent* aEvent);
216 // We manage 4 states here: ACTIVE, HOVER, DRAGOVER, URLTARGET
217 static bool ManagesState(ElementState aState) {
218 return aState == ElementState::ACTIVE || aState == ElementState::HOVER ||
219 aState == ElementState::DRAGOVER ||
220 aState == ElementState::URLTARGET;
224 * Notify that the given ElementState::* bit has changed for this content.
225 * @param aContent Content which has changed states
226 * @param aState Corresponding state flags such as ElementState::FOCUS
227 * @return Whether the content was able to change all states. Returns false
228 * if a resulting DOM event causes the content node passed in
229 * to not change states. Note, the frame for the content may
230 * change as a result of the content state change, because of
231 * frame reconstructions that may occur, but this does not
232 * affect the return value.
234 bool SetContentState(nsIContent* aContent, ElementState aState);
236 nsIContent* GetActiveContent() const { return mActiveContent; }
238 void NativeAnonymousContentRemoved(nsIContent* aAnonContent);
239 MOZ_CAN_RUN_SCRIPT_BOUNDARY void ContentRemoved(dom::Document* aDocument,
240 nsIContent* aContent);
243 * Called when a native anonymous <div> element which is root element of
244 * text editor will be removed.
246 void TextControlRootWillBeRemoved(TextControlElement& aTextControlElement);
249 * Called when a native anonymous <div> element which is root element of
250 * text editor is created.
252 void TextControlRootAdded(dom::Element& aAnonymousDivElement,
253 TextControlElement& aTextControlElement);
255 bool EventStatusOK(WidgetGUIEvent* aEvent);
258 * EventStateManager stores IMEContentObserver while it's observing contents.
259 * Following mehtods are called by IMEContentObserver when it starts to
260 * observe or stops observing the content.
262 void OnStartToObserveContent(IMEContentObserver* aIMEContentObserver);
263 void OnStopObservingContent(IMEContentObserver* aIMEContentObserver);
266 * TryToFlushPendingNotificationsToIME() suggests flushing pending
267 * notifications to IME to IMEContentObserver.
268 * Doesn't do anything in child processes where flushing happens
269 * asynchronously.
271 void TryToFlushPendingNotificationsToIME();
273 static bool IsKeyboardEventUserActivity(WidgetEvent* aEvent);
276 * Register accesskey on the given element. When accesskey is activated then
277 * the element will be notified via Element::PerformAccesskey() method.
279 * @param aElement the given element
280 * @param aKey accesskey
282 void RegisterAccessKey(dom::Element* aElement, uint32_t aKey);
285 * Unregister accesskey for the given element.
287 * @param aElement the given element
288 * @param aKey accesskey
290 void UnregisterAccessKey(dom::Element* aElement, uint32_t aKey);
293 * Get accesskey registered on the given element or 0 if there is none.
295 * @param aElement the given element (must not be null)
296 * @return registered accesskey
298 uint32_t GetRegisteredAccessKey(dom::Element* aContent);
300 static void GetAccessKeyLabelPrefix(dom::Element* aElement,
301 nsAString& aPrefix);
304 * HandleAccessKey() looks for access keys which matches with aEvent and
305 * execute when it matches with a chrome access key or some content access
306 * keys.
307 * If the event may match chrome access keys, this handles the access key
308 * synchronously (if there are nested ESMs, their HandleAccessKey() are
309 * also called recursively).
310 * If the event may match content access keys and focused target is a remote
311 * process, this does nothing for the content because when this is called,
312 * it should already have been handled in the remote process.
313 * If the event may match content access keys and focused target is not in
314 * remote process but there are some remote children, this will post
315 * HandleAccessKey messages to all remote children.
317 * @return true if there is accesskey which aEvent and
318 * aAccessCharCodes match with. Otherwise, false.
319 * I.e., when this returns true, a target is executed
320 * or focused.
321 * Note that even if this returns false, a target in
322 * remote process may be executed or focused
323 * asynchronously.
325 bool HandleAccessKey(WidgetKeyboardEvent* aEvent, nsPresContext* aPresContext,
326 nsTArray<uint32_t>& aAccessCharCodes) {
327 return WalkESMTreeToHandleAccessKey(aEvent, aPresContext, aAccessCharCodes,
328 nullptr, eAccessKeyProcessingNormal,
329 true);
333 * CheckIfEventMatchesAccessKey() looks for access key which matches with
334 * aEvent in the process but won't execute it.
336 * @return true if there is accesskey which aEvent matches with
337 * in this process. Otherwise, false.
339 bool CheckIfEventMatchesAccessKey(WidgetKeyboardEvent* aEvent,
340 nsPresContext* aPresContext);
342 nsresult SetCursor(StyleCursorKind, imgIContainer*, const ImageResolution&,
343 const Maybe<gfx::IntPoint>& aHotspot, nsIWidget* aWidget,
344 bool aLockCursor);
346 void StartHidingCursorWhileTyping(nsIWidget*);
349 * Checks if the current mouse over element matches the given
350 * Element (which has a remote frame), and if so, notifies
351 * the BrowserParent of the mouse enter.
352 * Called when we reconstruct the BrowserParent and need to
353 * recompute state on the new object.
355 void RecomputeMouseEnterStateForRemoteFrame(dom::Element& aElement);
357 nsPresContext* GetPresContext() { return mPresContext; }
359 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(EventStateManager, nsIObserver)
361 // The manager in this process that is setting the cursor. In the parent
362 // process it might be null if a remote process is setting the cursor.
363 static EventStateManager* sCursorSettingManager;
364 static void ClearCursorSettingManager() { sCursorSettingManager = nullptr; }
366 static EventStateManager* GetActiveEventStateManager() { return sActiveESM; }
368 // Sets aNewESM to be the active event state manager, and
369 // if aContent is non-null, marks the object as active.
370 static void SetActiveManager(EventStateManager* aNewESM,
371 nsIContent* aContent);
373 static bool IsRemoteTarget(nsIContent* target);
375 static bool IsTopLevelRemoteTarget(nsIContent* aTarget);
377 // Returns the kind of APZ action the given WidgetWheelEvent will perform.
378 static Maybe<layers::APZWheelAction> APZWheelActionFor(
379 const WidgetWheelEvent* aEvent);
381 // For some kinds of scrollings, the delta values of WidgetWheelEvent are
382 // possbile to be adjusted. This function is used to detect such scrollings
383 // and returns a wheel delta adjustment strategy to use, which is corresponded
384 // to the kind of the scrolling.
385 // It returns WheelDeltaAdjustmentStrategy::eAutoDir if the current default
386 // action is auto-dir scrolling which honours the scrolling target(The
387 // comments in WheelDeltaAdjustmentStrategy describes the concept in detail).
388 // It returns WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour if the
389 // current action is auto-dir scrolling which honours the root element in the
390 // document where the scrolling target is(The comments in
391 // WheelDeltaAdjustmentStrategy describes the concept in detail).
392 // It returns WheelDeltaAdjustmentStrategy::eHorizontalize if the current
393 // default action is horizontalized scrolling.
394 // It returns WheelDeltaAdjustmentStrategy::eNone to mean no delta adjustment
395 // strategy should be used if the scrolling is just a tranditional scrolling
396 // whose delta values are never possible to be adjusted.
397 static WheelDeltaAdjustmentStrategy GetWheelDeltaAdjustmentStrategy(
398 const WidgetWheelEvent& aEvent);
400 // Returns user-set multipliers for a wheel event.
401 static void GetUserPrefsForWheelEvent(const WidgetWheelEvent* aEvent,
402 double* aOutMultiplierX,
403 double* aOutMultiplierY);
405 // Holds the point in screen coords that a mouse event was dispatched to,
406 // before we went into pointer lock mode. This is constantly updated while
407 // the pointer is not locked, but we don't update it while the pointer is
408 // locked. This is used by dom::Event::GetScreenCoords() to make mouse
409 // events' screen coord appear frozen at the last mouse position while
410 // the pointer is locked.
411 static CSSIntPoint sLastScreenPoint;
413 // Holds the point in client coords of the last mouse event. Used by
414 // dom::Event::GetClientCoords() to make mouse events' client coords appear
415 // frozen at the last mouse position while the pointer is locked.
416 static CSSIntPoint sLastClientPoint;
419 * If the absolute values of mMultiplierX and/or mMultiplierY are equal or
420 * larger than this value, the computed scroll amount isn't rounded down to
421 * the page width or height.
423 static constexpr double MIN_MULTIPLIER_VALUE_ALLOWING_OVER_ONE_PAGE_SCROLL =
424 1000.0;
427 * HandleMiddleClickPaste() handles middle mouse button event as pasting
428 * clipboard text. Note that if aEditorBase is nullptr, this only
429 * dispatches ePaste event because it's necessary for some web apps which
430 * want to implement their own editor and supports middle click paste.
432 * @param aPresShell The PresShell for the ESM. This lifetime
433 * should be guaranteed by the caller.
434 * @param aMouseEvent The eMouseClick event which caused the
435 * paste.
436 * @param aStatus The event status of aMouseEvent.
437 * @param aEditorBase EditorBase which may be pasted the
438 * clipboard text by the middle click.
439 * If there is no editor for aMouseEvent,
440 * set nullptr.
442 MOZ_CAN_RUN_SCRIPT
443 nsresult HandleMiddleClickPaste(PresShell* aPresShell,
444 WidgetMouseEvent* aMouseEvent,
445 nsEventStatus* aStatus,
446 EditorBase* aEditorBase);
448 static void ConsumeInteractionData(
449 dom::Record<nsString, dom::InteractionData>& aInteractions);
451 // Stop tracking a possible drag. If aClearInChildProcesses is true, send
452 // a notification to any child processes that are in the drag service that
453 // tried to start a drag.
454 void StopTrackingDragGesture(bool aClearInChildProcesses);
456 protected:
458 * If aTargetFrame's widget has a cached cursor value, resets the cursor
459 * such that the next call to SetCursor on the widget will force an update
460 * of the native cursor. For use in getting puppet widget to update its
461 * cursor between mouse exit / enter transitions. This call basically wraps
462 * nsIWidget ClearCachedCursor.
464 void ClearCachedWidgetCursor(nsIFrame* aTargetFrame);
466 void UpdateCursor(nsPresContext*, WidgetMouseEvent*, nsIFrame* aTargetFrame,
467 nsEventStatus* aStatus);
469 * Turn a GUI mouse/pointer event into a mouse/pointer event targeted at the
470 * specified content. This returns the primary frame for the content (or null
471 * if it goes away during the event).
473 MOZ_CAN_RUN_SCRIPT nsIFrame* DispatchMouseOrPointerEvent(
474 WidgetMouseEvent* aMouseEvent, EventMessage aMessage,
475 nsIContent* aTargetContent, nsIContent* aRelatedContent);
477 * Synthesize DOM pointerover and pointerout events
479 void GeneratePointerEnterExit(EventMessage aMessage,
480 WidgetMouseEvent* aEvent);
482 * Synthesize DOM and frame mouseover and mouseout events from this
483 * MOUSE_MOVE or MOUSE_EXIT event.
485 void GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent);
487 * Tell this ESM and ESMs in parent documents that the mouse is
488 * over some content in this document.
490 MOZ_CAN_RUN_SCRIPT_BOUNDARY void NotifyMouseOver(
491 WidgetMouseEvent* aMouseEvent, nsIContent* aContent);
493 * Tell this ESM and ESMs in affected child documents that the mouse
494 * has exited this document's currently hovered content.
495 * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
497 * @param aMouseEvent the event that triggered the mouseout
498 * @param aMovingInto the content node we've moved into. This is used to set
499 * the relatedTarget for mouseout events. Also, if it's non-null
500 * NotifyMouseOut will NOT change the current hover content to null;
501 * in that case the caller is responsible for updating hover state.
503 MOZ_CAN_RUN_SCRIPT_BOUNDARY void NotifyMouseOut(WidgetMouseEvent* aMouseEvent,
504 nsIContent* aMovingInto);
505 MOZ_CAN_RUN_SCRIPT void GenerateDragDropEnterExit(
506 nsPresContext* aPresContext, WidgetDragEvent* aDragEvent);
509 * Return mMouseEnterLeaveHelper or relevant mPointersEnterLeaveHelper
510 * elements wrapper. If mPointersEnterLeaveHelper does not contain wrapper for
511 * pointerId it create new one
513 OverOutElementsWrapper* GetWrapperByEventID(WidgetMouseEvent* aMouseEvent);
516 * Fire the dragenter and dragexit/dragleave events when the mouse moves to a
517 * new target.
519 * @param aRelatedTarget relatedTarget to set for the event
520 * @param aTargetContent target to set for the event
521 * @param aTargetFrame target frame for the event
523 MOZ_CAN_RUN_SCRIPT void FireDragEnterOrExit(nsPresContext* aPresContext,
524 WidgetDragEvent* aDragEvent,
525 EventMessage aMessage,
526 nsIContent* aRelatedTarget,
527 nsIContent* aTargetContent,
528 AutoWeakFrame& aTargetFrame);
530 * Update the initial drag session data transfer with any changes that occur
531 * on cloned data transfer objects used for events.
533 void UpdateDragDataTransfer(WidgetDragEvent* dragEvent);
536 * InitAndDispatchClickEvent() dispatches a click event.
538 * @param aMouseUpEvent eMouseUp event which causes the click event.
539 * EventCausesClickEvents() must return true
540 * if this event is set to it.
541 * @param aStatus Returns the result of click event.
542 * If the status indicates consumed, the
543 * value won't be overwritten with
544 * nsEventStatus_eIgnore.
545 * @param aMessage Should be eMouseClick, eMouseDoubleClick or
546 * eMouseAuxClick.
547 * @param aPresShell The PresShell.
548 * @param aMouseUpContent The event target of aMouseUpEvent.
549 * @param aCurrentTarget Current target of the caller.
550 * @param aNoContentDispatch true if the event shouldn't be exposed to
551 * web contents (although will be fired on
552 * document and window).
553 * @param aOverrideClickTarget Preferred click event target. If this is
554 * not nullptr, aMouseUpContent and
555 * aCurrentTarget are ignored.
557 MOZ_CAN_RUN_SCRIPT
558 static nsresult InitAndDispatchClickEvent(
559 WidgetMouseEvent* aMouseUpEvent, nsEventStatus* aStatus,
560 EventMessage aMessage, PresShell* aPresShell, nsIContent* aMouseUpContent,
561 AutoWeakFrame aCurrentTarget, bool aNoContentDispatch,
562 nsIContent* aOverrideClickTarget);
564 nsresult SetClickCount(WidgetMouseEvent* aEvent, nsEventStatus* aStatus,
565 nsIContent* aOverrideClickTarget = nullptr);
568 * EventCausesClickEvents() returns true when aMouseEvent is an eMouseUp
569 * event and it should cause eMouseClick, eMouseDoubleClick and/or
570 * eMouseAuxClick events. Note that this method assumes that
571 * aMouseEvent.mClickCount has already been initialized with SetClickCount().
573 static bool EventCausesClickEvents(const WidgetMouseEvent& aMouseEvent);
576 * PostHandleMouseUp() handles default actions of eMouseUp event.
578 * @param aMouseUpEvent eMouseUp event which causes the click event.
579 * EventCausesClickEvents() must return true
580 * if this event is set to it.
581 * @param aStatus Returns the result of event status.
582 * If one of dispatching event is consumed or
583 * this does something as default action,
584 * returns nsEventStatus_eConsumeNoDefault.
585 * @param aOverrideClickTarget Preferred click event target. If nullptr,
586 * aMouseUpEvent target and current target
587 * are used.
589 MOZ_CAN_RUN_SCRIPT
590 nsresult PostHandleMouseUp(WidgetMouseEvent* aMouseUpEvent,
591 nsEventStatus* aStatus,
592 nsIContent* aOverrideClickTarget);
595 * DispatchClickEvents() dispatches eMouseClick, eMouseDoubleClick and
596 * eMouseAuxClick events for aMouseUpEvent. aMouseUpEvent should cause
597 * click event.
599 * @param aPresShell The PresShell.
600 * @param aMouseUpEvent eMouseUp event which causes the click event.
601 * EventCausesClickEvents() must return true
602 * if this event is set to it.
603 * @param aStatus Returns the result of event status.
604 * If one of dispatching click event is
605 * consumed, returns
606 * nsEventStatus_eConsumeNoDefault.
607 * @param aMouseUpContent The event target of aMouseUpEvent.
608 * @param aOverrideClickTarget Preferred click event target. If this is
609 * not nullptr, aMouseUpContent and
610 * current target frame of the ESM are ignored.
612 MOZ_CAN_RUN_SCRIPT
613 nsresult DispatchClickEvents(PresShell* aPresShell,
614 WidgetMouseEvent* aMouseUpEvent,
615 nsEventStatus* aStatus,
616 nsIContent* aMouseUpContent,
617 nsIContent* aOverrideClickTarget);
619 void EnsureDocument(nsPresContext* aPresContext);
620 MOZ_CAN_RUN_SCRIPT_BOUNDARY
621 void FlushLayout(nsPresContext* aPresContext);
624 * The phases of WalkESMTreeToHandleAccessKey processing. See below.
626 enum ProcessingAccessKeyState {
627 eAccessKeyProcessingNormal = 0,
628 eAccessKeyProcessingUp,
629 eAccessKeyProcessingDown
633 * Walk EMS to look for access key and execute found access key when aExecute
634 * is true.
635 * If there is registered element for the accesskey given by the key event
636 * and modifier mask then call element.PerformAccesskey(), otherwise call
637 * WalkESMTreeToHandleAccessKey() recursively, on descendant docshells first,
638 * then on the ancestor (with |aBubbledFrom| set to the docshell associated
639 * with |this|), until something matches.
641 * @param aEvent the keyboard event triggering the acccess key
642 * @param aPresContext the presentation context
643 * @param aAccessCharCodes list of charcode candidates
644 * @param aBubbledFrom is used by an ancestor to avoid calling
645 * WalkESMTreeToHandleAccessKey() on the child the call originally
646 * came from, i.e. this is the child that recursively called us in
647 * its Up phase. The initial caller passes |nullptr| here. This is to
648 * avoid an infinite loop.
649 * @param aAccessKeyState Normal, Down or Up processing phase (see enums
650 * above). The initial event receiver uses 'normal', then 'down' when
651 * processing children and Up when recursively calling its ancestor.
652 * @param aExecute is true, execute an accesskey if it's found. Otherwise,
653 * found accesskey won't be executed.
655 * @return true if there is a target which aEvent and
656 * aAccessCharCodes match with in this process.
657 * Otherwise, false. I.e., when this returns true and
658 * aExecute is true, a target is executed or focused.
659 * Note that even if this returns false, a target in
660 * remote process may be executed or focused
661 * asynchronously.
663 bool WalkESMTreeToHandleAccessKey(WidgetKeyboardEvent* aEvent,
664 nsPresContext* aPresContext,
665 nsTArray<uint32_t>& aAccessCharCodes,
666 nsIDocShellTreeItem* aBubbledFrom,
667 ProcessingAccessKeyState aAccessKeyState,
668 bool aExecute);
671 * Look for access key and execute found access key if aExecute is true in
672 * the instance.
674 * @return true if there is a target which matches with
675 * aAccessCharCodes and aIsTrustedEvent. Otherwise,
676 * false. I.e., when this returns true and aExecute
677 * is true, a target is executed or focused.
679 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool LookForAccessKeyAndExecute(
680 nsTArray<uint32_t>& aAccessCharCodes, bool aIsTrustedEvent,
681 bool aIsRepeat, bool aExecute);
683 //---------------------------------------------
684 // DocShell Focus Traversal Methods
685 //---------------------------------------------
687 dom::Element* GetFocusedElement();
688 bool IsShellVisible(nsIDocShell* aShell);
690 // These functions are for mousewheel and pixel scrolling
692 class WheelPrefs {
693 public:
694 static WheelPrefs* GetInstance();
695 static void Shutdown();
698 * ApplyUserPrefsToDelta() overrides the wheel event's delta values with
699 * user prefs.
701 void ApplyUserPrefsToDelta(WidgetWheelEvent* aEvent);
704 * Returns whether or not ApplyUserPrefsToDelta() would change the delta
705 * values of an event.
707 void GetUserPrefsForEvent(const WidgetWheelEvent* aEvent,
708 double* aOutMultiplierX, double* aOutMultiplierY);
711 * If ApplyUserPrefsToDelta() changed the delta values with customized
712 * prefs, the overflowDelta values would be inflated.
713 * CancelApplyingUserPrefsFromOverflowDelta() cancels the inflation.
715 void CancelApplyingUserPrefsFromOverflowDelta(WidgetWheelEvent* aEvent);
718 * Computes the default action for the aEvent with the prefs.
720 enum Action : uint8_t {
721 ACTION_NONE = 0,
722 ACTION_SCROLL,
723 ACTION_HISTORY,
724 ACTION_ZOOM,
725 // Horizontalized scrolling means treating vertical wheel scrolling as
726 // horizontal scrolling during the process of its default action and
727 // plugins handling scrolling. Note that delta values as the event object
728 // in a DOM event listener won't be affected, and will be still the
729 // original values. For more details, refer to
730 // mozilla::WheelDeltaAdjustmentStrategy::eHorizontalize
731 ACTION_HORIZONTALIZED_SCROLL,
732 ACTION_PINCH_ZOOM,
733 ACTION_LAST = ACTION_PINCH_ZOOM,
734 // Following actions are used only by internal processing. So, cannot
735 // specified by prefs.
736 ACTION_SEND_TO_PLUGIN,
738 Action ComputeActionFor(const WidgetWheelEvent* aEvent);
741 * NeedToComputeLineOrPageDelta() returns if the aEvent needs to be
742 * computed the lineOrPageDelta values.
744 bool NeedToComputeLineOrPageDelta(const WidgetWheelEvent* aEvent);
747 * IsOverOnePageScrollAllowed*() checks whether wheel scroll amount should
748 * be rounded down to the page width/height (false) or not (true).
750 bool IsOverOnePageScrollAllowedX(const WidgetWheelEvent* aEvent);
751 bool IsOverOnePageScrollAllowedY(const WidgetWheelEvent* aEvent);
753 private:
754 WheelPrefs();
755 ~WheelPrefs();
757 static void OnPrefChanged(const char* aPrefName, void* aClosure);
759 enum Index {
760 INDEX_DEFAULT = 0,
761 INDEX_ALT,
762 INDEX_CONTROL,
763 INDEX_META,
764 INDEX_SHIFT,
765 COUNT_OF_MULTIPLIERS
769 * GetIndexFor() returns the index of the members which should be used for
770 * the aEvent. When only one modifier key of MODIFIER_ALT,
771 * MODIFIER_CONTROL, MODIFIER_META or MODIFIER_SHIFT is pressed, returns the
772 * index for the modifier. Otherwise, this return the default index which
773 * is used at either no modifier key is pressed or two or modifier keys are
774 * pressed.
776 Index GetIndexFor(const WidgetWheelEvent* aEvent);
779 * GetPrefNameBase() returns the base pref name for aEvent.
780 * It's decided by GetModifierForPref() which modifier should be used for
781 * the aEvent.
783 * @param aBasePrefName The result, must be "mousewheel.with_*." or
784 * "mousewheel.default.".
786 void GetBasePrefName(Index aIndex, nsACString& aBasePrefName);
788 void Init(Index aIndex);
790 void Reset();
793 * Retrieve multiplier for aEvent->mDeltaX and aEvent->mDeltaY.
795 * Note that if the default action is ACTION_HORIZONTALIZED_SCROLL and the
796 * delta values have been adjusted by WheelDeltaHorizontalizer() before this
797 * function is called, this function will swap the X and Y multipliers. By
798 * doing this, multipliers will still apply to the delta values they
799 * originally corresponded to.
801 * @param aEvent The event which is being handled.
802 * @param aIndex The index of mMultiplierX and mMultiplierY.
803 * Should be result of GetIndexFor(aEvent).
804 * @param aMultiplierForDeltaX Will be set to multiplier for
805 * aEvent->mDeltaX.
806 * @param aMultiplierForDeltaY Will be set to multiplier for
807 * aEvent->mDeltaY.
809 void GetMultiplierForDeltaXAndY(const WidgetWheelEvent* aEvent,
810 Index aIndex, double* aMultiplierForDeltaX,
811 double* aMultiplierForDeltaY);
813 bool mInit[COUNT_OF_MULTIPLIERS];
814 double mMultiplierX[COUNT_OF_MULTIPLIERS];
815 double mMultiplierY[COUNT_OF_MULTIPLIERS];
816 double mMultiplierZ[COUNT_OF_MULTIPLIERS];
817 Action mActions[COUNT_OF_MULTIPLIERS];
819 * action values overridden by .override_x pref.
820 * If an .override_x value is -1, same as the
821 * corresponding mActions value.
823 Action mOverriddenActionsX[COUNT_OF_MULTIPLIERS];
825 static WheelPrefs* sInstance;
829 * DeltaDirection is used for specifying whether the called method should
830 * handle vertical delta or horizontal delta.
831 * This is clearer than using bool.
833 enum DeltaDirection { DELTA_DIRECTION_X = 0, DELTA_DIRECTION_Y };
835 struct MOZ_STACK_CLASS EventState {
836 bool mDefaultPrevented;
837 bool mDefaultPreventedByContent;
839 EventState()
840 : mDefaultPrevented(false), mDefaultPreventedByContent(false) {}
844 * SendLineScrollEvent() dispatches a DOMMouseScroll event for the
845 * WidgetWheelEvent. This method shouldn't be called for non-trusted
846 * wheel event because it's not necessary for compatiblity.
848 * @param aTargetFrame The event target of wheel event.
849 * @param aEvent The original Wheel event.
850 * @param aState The event which should be set to the dispatching
851 * event. This also returns the dispatched event
852 * state.
853 * @param aDelta The delta value of the event.
854 * @param aDeltaDirection The X/Y direction of dispatching event.
856 MOZ_CAN_RUN_SCRIPT void SendLineScrollEvent(nsIFrame* aTargetFrame,
857 WidgetWheelEvent* aEvent,
858 EventState& aState,
859 int32_t aDelta,
860 DeltaDirection aDeltaDirection);
863 * SendPixelScrollEvent() dispatches a MozMousePixelScroll event for the
864 * WidgetWheelEvent. This method shouldn't be called for non-trusted
865 * wheel event because it's not necessary for compatiblity.
867 * @param aTargetFrame The event target of wheel event.
868 * @param aEvent The original Wheel event.
869 * @param aState The event which should be set to the dispatching
870 * event. This also returns the dispatched event
871 * state.
872 * @param aPixelDelta The delta value of the event.
873 * @param aDeltaDirection The X/Y direction of dispatching event.
875 MOZ_CAN_RUN_SCRIPT void SendPixelScrollEvent(nsIFrame* aTargetFrame,
876 WidgetWheelEvent* aEvent,
877 EventState& aState,
878 int32_t aPixelDelta,
879 DeltaDirection aDeltaDirection);
882 * ComputeScrollTargetAndMayAdjustWheelEvent() returns the scrollable frame
883 * which should be scrolled.
885 * @param aTargetFrame The event target of the wheel event.
886 * @param aEvent The handling mouse wheel event.
887 * @param aOptions The options for finding the scroll target.
888 * Callers should use COMPUTE_*.
889 * @return The scrollable frame which should be scrolled.
891 // These flags are used in ComputeScrollTargetAndMayAdjustWheelEvent().
892 // Callers should use COMPUTE_*.
893 enum {
894 PREFER_MOUSE_WHEEL_TRANSACTION = 0x00000001,
895 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS = 0x00000002,
896 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS = 0x00000004,
897 START_FROM_PARENT = 0x00000008,
898 INCLUDE_PLUGIN_AS_TARGET = 0x00000010,
899 // Indicates the wheel scroll event being computed is an auto-dir scroll, so
900 // its delta may be adjusted after being computed.
901 MAY_BE_ADJUSTED_BY_AUTO_DIR = 0x00000020,
903 enum ComputeScrollTargetOptions {
904 // At computing scroll target for legacy mouse events, we should return
905 // first scrollable element even when it's not scrollable to the direction.
906 COMPUTE_LEGACY_MOUSE_SCROLL_EVENT_TARGET = 0,
907 // Default action prefers the scrolled element immediately before if it's
908 // still under the mouse cursor. Otherwise, it prefers the nearest
909 // scrollable ancestor which will be scrolled actually.
910 COMPUTE_DEFAULT_ACTION_TARGET =
911 (PREFER_MOUSE_WHEEL_TRANSACTION |
912 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS |
913 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS),
914 COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR =
915 (COMPUTE_DEFAULT_ACTION_TARGET | MAY_BE_ADJUSTED_BY_AUTO_DIR),
916 // Look for the nearest scrollable ancestor which can be scrollable with
917 // aEvent.
918 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS =
919 (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS | START_FROM_PARENT),
920 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS =
921 (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS | START_FROM_PARENT),
922 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS_WITH_AUTO_DIR =
923 (COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS |
924 MAY_BE_ADJUSTED_BY_AUTO_DIR),
925 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS_WITH_AUTO_DIR =
926 (COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS |
927 MAY_BE_ADJUSTED_BY_AUTO_DIR),
930 // Compute the scroll target.
931 // The delta values in the wheel event may be changed if the event is for
932 // auto-dir scrolling. For information on auto-dir,
933 // @see mozilla::WheelDeltaAdjustmentStrategy
934 nsIFrame* ComputeScrollTargetAndMayAdjustWheelEvent(
935 nsIFrame* aTargetFrame, WidgetWheelEvent* aEvent,
936 ComputeScrollTargetOptions aOptions);
938 nsIFrame* ComputeScrollTargetAndMayAdjustWheelEvent(
939 nsIFrame* aTargetFrame, double aDirectionX, double aDirectionY,
940 WidgetWheelEvent* aEvent, ComputeScrollTargetOptions aOptions);
942 nsIFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
943 WidgetWheelEvent* aEvent,
944 ComputeScrollTargetOptions aOptions) {
945 MOZ_ASSERT(!(aOptions & MAY_BE_ADJUSTED_BY_AUTO_DIR),
946 "aEvent may be modified by auto-dir");
947 return ComputeScrollTargetAndMayAdjustWheelEvent(aTargetFrame, aEvent,
948 aOptions);
951 nsIFrame* ComputeScrollTarget(nsIFrame* aTargetFrame, double aDirectionX,
952 double aDirectionY, WidgetWheelEvent* aEvent,
953 ComputeScrollTargetOptions aOptions) {
954 MOZ_ASSERT(!(aOptions & MAY_BE_ADJUSTED_BY_AUTO_DIR),
955 "aEvent may be modified by auto-dir");
956 return ComputeScrollTargetAndMayAdjustWheelEvent(
957 aTargetFrame, aDirectionX, aDirectionY, aEvent, aOptions);
961 * GetScrollAmount() returns the scroll amount in app uints of one line or
962 * one page. If the wheel event scrolls a page, returns the page width and
963 * height. Otherwise, returns line height for both its width and height.
965 * @param aScrollableFrame A frame which will be scrolled by the event.
966 * The result of
967 * ComputeScrollTargetAndMayAdjustWheelEvent() is
968 * expected for this value.
969 * This can be nullptr if there is no scrollable
970 * frame. Then, this method uses root frame's
971 * line height or visible area's width and height.
973 nsSize GetScrollAmount(nsPresContext* aPresContext, WidgetWheelEvent* aEvent,
974 nsIScrollableFrame* aScrollableFrame);
977 * DoScrollText() scrolls the scrollable frame for aEvent.
979 void DoScrollText(nsIScrollableFrame* aScrollableFrame,
980 WidgetWheelEvent* aEvent);
982 void DoScrollHistory(int32_t direction);
983 void DoScrollZoom(nsIFrame* aTargetFrame, int32_t adjustment);
984 void ChangeZoom(bool aIncrease);
987 * DeltaAccumulator class manages delta values for dispatching DOMMouseScroll
988 * event. If wheel events are caused by pixel scroll only devices or
989 * the delta values are customized by prefs, this class stores the delta
990 * values and set lineOrPageDelta values.
992 class DeltaAccumulator {
993 public:
994 static DeltaAccumulator* GetInstance() {
995 if (!sInstance) {
996 sInstance = new DeltaAccumulator;
998 return sInstance;
1001 static void Shutdown() {
1002 delete sInstance;
1003 sInstance = nullptr;
1006 bool IsInTransaction() { return mHandlingDeltaMode != UINT32_MAX; }
1009 * InitLineOrPageDelta() stores pixel delta values of WidgetWheelEvents
1010 * which are caused if it's needed. And if the accumulated delta becomes a
1011 * line height, sets lineOrPageDeltaX and lineOrPageDeltaY automatically.
1013 void InitLineOrPageDelta(nsIFrame* aTargetFrame, EventStateManager* aESM,
1014 WidgetWheelEvent* aEvent);
1017 * Reset() resets all members.
1019 void Reset();
1022 * ComputeScrollAmountForDefaultAction() computes the default action's
1023 * scroll amount in device pixels with mPendingScrollAmount*.
1025 nsIntPoint ComputeScrollAmountForDefaultAction(
1026 WidgetWheelEvent* aEvent, const nsIntSize& aScrollAmountInDevPixels);
1028 private:
1029 DeltaAccumulator()
1030 : mX(0.0),
1031 mY(0.0),
1032 mPendingScrollAmountX(0.0),
1033 mPendingScrollAmountY(0.0),
1034 mHandlingDeltaMode(UINT32_MAX),
1035 mIsNoLineOrPageDeltaDevice(false) {}
1037 double mX;
1038 double mY;
1040 // When default action of a wheel event is scroll but some delta values
1041 // are ignored because the computed amount values are not integer, the
1042 // fractional values are saved by these members.
1043 double mPendingScrollAmountX;
1044 double mPendingScrollAmountY;
1046 TimeStamp mLastTime;
1048 uint32_t mHandlingDeltaMode;
1049 bool mIsNoLineOrPageDeltaDevice;
1051 static DeltaAccumulator* sInstance;
1054 // end mousewheel functions
1057 * When a touch gesture is about to start, this function determines what
1058 * kind of gesture interaction we will want to use, based on what is
1059 * underneath the initial touch point.
1060 * Currently it decides between panning (finger scrolling) or dragging
1061 * the target element, as well as the orientation to trigger panning and
1062 * display visual boundary feedback. The decision is stored back in aEvent.
1064 void DecideGestureEvent(WidgetGestureNotifyEvent* aEvent,
1065 nsIFrame* targetFrame);
1067 // routines for the d&d gesture tracking state machine
1068 void BeginTrackingDragGesture(nsPresContext* aPresContext,
1069 WidgetMouseEvent* aDownEvent,
1070 nsIFrame* aDownFrame);
1072 void SetGestureDownPoint(WidgetGUIEvent* aEvent);
1074 LayoutDeviceIntPoint GetEventRefPoint(WidgetEvent* aEvent) const;
1076 friend class mozilla::dom::BrowserParent;
1077 void BeginTrackingRemoteDragGesture(nsIContent* aContent,
1078 dom::RemoteDragStartData* aDragStartData);
1080 MOZ_CAN_RUN_SCRIPT
1081 void GenerateDragGesture(nsPresContext* aPresContext,
1082 WidgetInputEvent* aEvent);
1085 * When starting a dnd session, UA must fire a pointercancel event and stop
1086 * firing the subsequent pointer events.
1088 MOZ_CAN_RUN_SCRIPT
1089 void MaybeFirePointerCancel(WidgetInputEvent* aEvent);
1092 * Determine which node the drag should be targeted at.
1093 * This is either the node clicked when there is a selection, or, for HTML,
1094 * the element with a draggable property set to true.
1096 * aSelectionTarget - target to check for selection
1097 * aDataTransfer - data transfer object that will contain the data to drag
1098 * aAllowEmptyDataTransfer - [out] set to true, if dnd operation can be
1099 * started even if DataTransfer is empty
1100 * aSelection - [out] set to the selection to be dragged
1101 * aTargetNode - [out] the draggable node, or null if there isn't one
1102 * aPrincipal - [out] set to the triggering principal of the drag, or null
1103 * if it's from browser chrome or OS
1104 * aCookieJarSettings - [out] set to the cookieJarSettings of the drag, or
1105 * null if it's from browser chrome or OS.
1107 void DetermineDragTargetAndDefaultData(
1108 nsPIDOMWindowOuter* aWindow, nsIContent* aSelectionTarget,
1109 dom::DataTransfer* aDataTransfer, bool* aAllowEmptyDataTransfer,
1110 dom::Selection** aSelection,
1111 dom::RemoteDragStartData** aRemoteDragStartData, nsIContent** aTargetNode,
1112 nsIPrincipal** aPrincipal, nsIContentSecurityPolicy** aCsp,
1113 nsICookieJarSettings** aCookieJarSettings);
1116 * Perform the default handling for the dragstart event and set up a
1117 * drag for aDataTransfer if it contains any data. Returns true if a drag has
1118 * started.
1120 * aDragEvent - the dragstart event
1121 * aDataTransfer - the data transfer that holds the data to be dragged
1122 * aAllowEmptyDataTransfer - if true, dnd can be started even if there is no
1123 * data to drag
1124 * aDragTarget - the target of the drag
1125 * aSelection - the selection to be dragged
1126 * aData - information pertaining to a drag started in a child process
1127 * aPrincipal - the triggering principal of the drag, or null if it's from
1128 * browser chrome or OS
1129 * aCookieJarSettings - the cookieJarSettings of the drag. or null if it's
1130 * from browser chrome or OS.
1132 MOZ_CAN_RUN_SCRIPT
1133 bool DoDefaultDragStart(
1134 nsPresContext* aPresContext, WidgetDragEvent* aDragEvent,
1135 dom::DataTransfer* aDataTransfer, bool aAllowEmptyDataTransfer,
1136 nsIContent* aDragTarget, dom::Selection* aSelection,
1137 dom::RemoteDragStartData* aDragStartData, nsIPrincipal* aPrincipal,
1138 nsIContentSecurityPolicy* aCsp, nsICookieJarSettings* aCookieJarSettings);
1140 bool IsTrackingDragGesture() const { return mGestureDownContent != nullptr; }
1142 * Set the fields of aEvent to reflect the mouse position and modifier keys
1143 * that were set when the user first pressed the mouse button (stored by
1144 * BeginTrackingDragGesture). aEvent->mWidget must be
1145 * mCurrentTarget->GetNearestWidget().
1147 void FillInEventFromGestureDown(WidgetMouseEvent* aEvent);
1149 MOZ_CAN_RUN_SCRIPT
1150 nsresult DoContentCommandEvent(WidgetContentCommandEvent* aEvent);
1151 MOZ_CAN_RUN_SCRIPT
1152 nsresult DoContentCommandInsertTextEvent(WidgetContentCommandEvent* aEvent);
1153 nsresult DoContentCommandScrollEvent(WidgetContentCommandEvent* aEvent);
1155 dom::BrowserParent* GetCrossProcessTarget();
1156 bool IsTargetCrossProcess(WidgetGUIEvent* aEvent);
1159 * DispatchCrossProcessEvent() try to post aEvent to target remote process.
1160 * If you need to check if the event is posted to a remote process, you
1161 * can use aEvent->HasBeenPostedToRemoteProcess().
1163 void DispatchCrossProcessEvent(WidgetEvent* aEvent,
1164 dom::BrowserParent* aRemoteTarget,
1165 nsEventStatus* aStatus);
1167 * HandleCrossProcessEvent() may post aEvent to target remote processes.
1168 * When it succeeded to post the event to at least one remote process,
1169 * returns true. Otherwise, including the case not tried to dispatch to
1170 * post the event, returns false.
1171 * If you need to check if the event is posted to at least one remote
1172 * process, you can use aEvent->HasBeenPostedToRemoteProcess().
1174 bool HandleCrossProcessEvent(WidgetEvent* aEvent, nsEventStatus* aStatus);
1176 void ReleaseCurrentIMEContentObserver();
1178 MOZ_CAN_RUN_SCRIPT void HandleQueryContentEvent(
1179 WidgetQueryContentEvent* aEvent);
1181 private:
1182 // Removes a node from the :hover / :active chain if needed, notifying if the
1183 // node is not a NAC subtree.
1185 // Only meant to be called from ContentRemoved and
1186 // NativeAnonymousContentRemoved.
1187 void RemoveNodeFromChainIfNeeded(ElementState aState,
1188 nsIContent* aContentRemoved, bool aNotify);
1190 bool IsEventOutsideDragThreshold(WidgetInputEvent* aEvent) const;
1192 static inline void DoStateChange(dom::Element* aElement, ElementState aState,
1193 bool aAddState);
1194 static inline void DoStateChange(nsIContent* aContent, ElementState aState,
1195 bool aAddState);
1196 static void UpdateAncestorState(nsIContent* aStartNode,
1197 nsIContent* aStopBefore, ElementState aState,
1198 bool aAddState);
1201 * Update the attribute mLastRefPoint of the mouse event. It should be
1202 * the center of the window while the pointer is locked.
1203 * the same value as mRefPoint while there is no known last ref point.
1204 * the same value as the last known mRefPoint.
1206 static void UpdateLastRefPointOfMouseEvent(WidgetMouseEvent* aMouseEvent);
1208 static void ResetPointerToWindowCenterWhilePointerLocked(
1209 WidgetMouseEvent* aMouseEvent);
1211 // Update the last known ref point to the current event's mRefPoint.
1212 static void UpdateLastPointerPosition(WidgetMouseEvent* aMouseEvent);
1215 * Notify target when user has been interaction with some speicific user
1216 * gestures which are eKeyUp, eMouseUp, eTouchEnd.
1218 void NotifyTargetUserActivation(WidgetEvent* aEvent,
1219 nsIContent* aTargetContent);
1222 * https://html.spec.whatwg.org/multipage/popover.html#light-dismiss-open-popovers.
1224 MOZ_CAN_RUN_SCRIPT void LightDismissOpenPopovers(WidgetEvent* aEvent,
1225 nsIContent* aTargetContent);
1227 already_AddRefed<EventStateManager> ESMFromContentOrThis(
1228 nsIContent* aContent);
1230 struct LastMouseDownInfo {
1231 nsCOMPtr<nsIContent> mLastMouseDownContent;
1232 Maybe<FormControlType> mLastMouseDownInputControlType;
1233 uint32_t mClickCount = 0;
1236 LastMouseDownInfo& GetLastMouseDownInfo(int16_t aButton);
1238 // These variables are only relevant if we're the cursor-setting manager.
1239 StyleCursorKind mLockCursor;
1240 bool mHidingCursorWhileTyping = false;
1242 // Last mouse event screen point (in device pixel) when mouse was locked, used
1243 // to restore mouse position after unlocking.
1244 static LayoutDeviceIntPoint sPreLockScreenPoint;
1246 // Stores the mRefPoint of the last synthetic mouse move we dispatched
1247 // to re-center the mouse when we were pointer locked. If this is (-1,-1) it
1248 // means we've not recently dispatched a centering event. We use this to
1249 // detect when we receive the synth event, so we can cancel and not send it
1250 // to content.
1251 static LayoutDeviceIntPoint sSynthCenteringPoint;
1253 WeakFrame mCurrentTarget;
1254 nsCOMPtr<nsIContent> mCurrentTargetContent;
1255 static AutoWeakFrame sLastDragOverFrame;
1257 // Stores the mRefPoint (the offset from the widget's origin in device
1258 // pixels) of the last mouse event.
1259 static LayoutDeviceIntPoint sLastRefPoint;
1261 // member variables for the d&d gesture state machine
1262 LayoutDeviceIntPoint mGestureDownPoint; // screen coordinates
1263 // The content to use as target if we start a d&d (what we drag).
1264 RefPtr<nsIContent> mGestureDownContent;
1265 // The content of the frame where the mouse-down event occurred. It's the same
1266 // as the target in most cases but not always - for example when dragging
1267 // an <area> of an image map this is the image. (bug 289667)
1268 nsCOMPtr<nsIContent> mGestureDownFrameOwner;
1269 // Data associated with a drag started in a content process.
1270 RefPtr<dom::RemoteDragStartData> mGestureDownDragStartData;
1271 // State of keys when the original gesture-down happened
1272 Modifiers mGestureModifiers;
1273 uint16_t mGestureDownButtons;
1275 LastMouseDownInfo mLastLeftMouseDownInfo;
1276 LastMouseDownInfo mLastMiddleMouseDownInfo;
1277 LastMouseDownInfo mLastRightMouseDownInfo;
1279 nsCOMPtr<nsIContent> mActiveContent;
1280 nsCOMPtr<nsIContent> mHoverContent;
1281 static nsCOMPtr<nsIContent> sDragOverContent;
1282 nsCOMPtr<nsIContent> mURLTargetContent;
1283 nsCOMPtr<nsINode> mPopoverPointerDownTarget;
1285 nsPresContext* mPresContext; // Not refcnted
1286 RefPtr<dom::Document> mDocument; // Doesn't necessarily need to be owner
1288 RefPtr<IMEContentObserver> mIMEContentObserver;
1290 bool mShouldAlwaysUseLineDeltas : 1;
1291 bool mShouldAlwaysUseLineDeltasInitialized : 1;
1293 bool mGestureDownInTextControl : 1;
1295 bool mInTouchDrag;
1297 bool m_haveShutdown;
1299 RefPtr<OverOutElementsWrapper> mMouseEnterLeaveHelper;
1300 nsRefPtrHashtable<nsUint32HashKey, OverOutElementsWrapper>
1301 mPointersEnterLeaveHelper;
1303 // Array for accesskey support
1304 nsCOMArray<dom::Element> mAccessKeys;
1306 bool ShouldAlwaysUseLineDeltas();
1308 public:
1309 static nsresult UpdateUserActivityTimer(void);
1311 static bool sNormalLMouseEventInProcess;
1312 static int16_t sCurrentMouseBtn;
1314 static EventStateManager* sActiveESM;
1316 static void ClearGlobalActiveContent(EventStateManager* aClearer);
1318 // Functions used for click hold context menus
1319 nsCOMPtr<nsITimer> mClickHoldTimer;
1320 void CreateClickHoldTimer(nsPresContext* aPresContext, nsIFrame* aDownFrame,
1321 WidgetGUIEvent* aMouseDownEvent);
1322 void KillClickHoldTimer();
1323 MOZ_CAN_RUN_SCRIPT_BOUNDARY void FireContextClick();
1325 MOZ_CAN_RUN_SCRIPT static void SetPointerLock(nsIWidget* aWidget,
1326 nsPresContext* aPresContext);
1327 static void sClickHoldCallback(nsITimer* aTimer, void* aESM);
1330 } // namespace mozilla
1332 // Click and double-click events need to be handled even for content that
1333 // has no frame. This is required for Web compatibility.
1334 #define NS_EVENT_NEEDS_FRAME(event) \
1335 ((event)->mMessage != eMouseClick && \
1336 (event)->mMessage != eMouseDoubleClick && \
1337 (event)->mMessage != eMouseAuxClick)
1339 #endif // mozilla_EventStateManager_h_