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"
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"
23 #include "WheelHandlingHelper.h" // for WheelDeltaAdjustmentStrategy
27 class nsICookieJarSettings
;
29 class nsIDocShellTreeItem
;
32 class nsIDocumentViewer
;
33 class nsIScrollableFrame
;
37 enum class FormControlType
: uint8_t;
42 class EnterLeaveDispatcher
;
43 class IMEContentObserver
;
44 class ScrollbarsForWheel
;
45 class TextControlElement
;
46 class WheelTransaction
;
54 class RemoteDragStartData
;
58 class OverOutElementsWrapper final
: public nsISupports
{
59 ~OverOutElementsWrapper();
62 OverOutElementsWrapper();
64 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
65 NS_DECL_CYCLE_COLLECTION_CLASS(OverOutElementsWrapper
)
67 void ContentRemoved(nsIContent
& aContent
);
68 void WillDispatchOverAndEnterEvent(nsIContent
* aOverEventTarget
) {
69 mDeepestEnterEventTarget
= aOverEventTarget
;
70 // Store the first "over" event target we fire and don't refire "over" event
71 // to that element while the first "over" event is still ongoing.
72 mDispatchingOverEventTarget
= aOverEventTarget
;
73 mDeepestEnterEventTargetIsOverEventTarget
= true;
75 void DidDispatchOverAndEnterEvent() { mDispatchingOverEventTarget
= nullptr; }
76 [[nodiscard
]] bool IsDispatchingOverEventOn(
77 nsIContent
* aOverEventTarget
) const {
78 MOZ_ASSERT(aOverEventTarget
);
79 return mDeepestEnterEventTargetIsOverEventTarget
&&
80 mDeepestEnterEventTarget
== aOverEventTarget
;
82 void WillDispatchOutAndOrLeaveEvent() {
83 // Store the first "out" event target or the deepest "leave" event target
84 // which we fire and don't refire "out" event to that element while the
85 // first "out" event is still ongoing.
86 mDispatchingOutOrDeepestLeaveEventTarget
= mDeepestEnterEventTarget
;
88 void DidDispatchOutAndOrLeaveEvent() {
89 mLastOverFrame
= nullptr;
90 mDeepestEnterEventTarget
= mDispatchingOutOrDeepestLeaveEventTarget
=
93 [[nodiscard
]] bool IsDispatchingOutEventOnLastOverEventTarget() const {
94 return mDispatchingOutOrDeepestLeaveEventTarget
&&
95 mDispatchingOutOrDeepestLeaveEventTarget
== mDeepestEnterEventTarget
;
97 void OverrideOverEventTarget(nsIContent
* aOverEventTarget
) {
98 mDeepestEnterEventTarget
= aOverEventTarget
;
99 mDeepestEnterEventTargetIsOverEventTarget
= true;
102 [[nodiscard
]] nsIContent
* GetDeepestLeaveEventTarget() const {
103 // The last deepest "enter" event targe (it may be same as the last "over"
104 // target) is the deepest "leave" event target.
105 return mDeepestEnterEventTarget
;
107 [[nodiscard
]] nsIContent
* GetOutEventTarget() const {
108 // The last deepest "enter" event target is same as the "over" event target
109 // unless it's never been removed from the DOM tree. If and only if the
110 // last "over" event target has not been removed from the DOM tree, it's
111 // the next "out" event target. Once the last "over" target is removed,
112 // "out" event should not be fired on the target nor its ancestor.
113 return mDeepestEnterEventTargetIsOverEventTarget
114 ? mDeepestEnterEventTarget
.get()
119 WeakFrame mLastOverFrame
;
122 // The deepest event target of the last "enter" event. If
123 // mDeepestEnterEventTargetIsOverEventTarget is true, this is the last "over"
124 // event target too. If it's set to false, this is an ancestor of the last
125 // "over" event target which has not been removed from the DOM tree.
126 nsCOMPtr
<nsIContent
> mDeepestEnterEventTarget
;
128 // While we're dispatching "over" and "enter" events, this is set to the
129 // "over" event target. If it's removed from the DOM tree, this is set to
131 nsCOMPtr
<nsIContent
> mDispatchingOverEventTarget
;
133 // While we're dispatching "out" and/or "leave" events, this is set to the
134 // "out" event target or the deepest leave event target. If it's removed from
135 // the DOM tree, this is set to nullptr.
136 nsCOMPtr
<nsIContent
> mDispatchingOutOrDeepestLeaveEventTarget
;
138 // Once the last "over" element is removed from the tree, this is set
139 // to false. Then, mDeepestEnterEventTarget may be an ancestor of the
140 // "over" element which should be the deepest target of next "leave"
141 // element but shouldn't be target of "out" event.
142 bool mDeepestEnterEventTargetIsOverEventTarget
= true;
145 class EventStateManager
: public nsSupportsWeakReference
, public nsIObserver
{
146 friend class mozilla::EnterLeaveDispatcher
;
147 friend class mozilla::ScrollbarsForWheel
;
148 friend class mozilla::WheelTransaction
;
150 using ElementState
= dom::ElementState
;
152 virtual ~EventStateManager();
157 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
163 /* The PreHandleEvent method is called before event dispatch to either
164 * the DOM or frames. Any processing which must not be prevented or
165 * cancelled should occur here. Any processing which is intended to
166 * be conditional based on either DOM or frame processing should occur in
167 * PostHandleEvent. Any centralized event processing which must occur before
168 * DOM or frame event handling should occur here as well.
170 * aOverrideClickTarget can be used to indicate which element should be
171 * used as the *up target when deciding whether to send click event.
172 * This is used when releasing pointer capture. Otherwise null.
175 nsresult
PreHandleEvent(nsPresContext
* aPresContext
, WidgetEvent
* aEvent
,
176 nsIFrame
* aTargetFrame
, nsIContent
* aTargetContent
,
177 nsEventStatus
* aStatus
,
178 nsIContent
* aOverrideClickTarget
);
180 /* The PostHandleEvent method should contain all system processing which
181 * should occur conditionally based on DOM or frame processing. It should
182 * also contain any centralized event processing which must occur after
183 * DOM and frame processing.
186 nsresult
PostHandleEvent(nsPresContext
* aPresContext
, WidgetEvent
* aEvent
,
187 nsIFrame
* aTargetFrame
, nsEventStatus
* aStatus
,
188 nsIContent
* aOverrideClickTarget
);
190 MOZ_CAN_RUN_SCRIPT
void PostHandleKeyboardEvent(
191 WidgetKeyboardEvent
* aKeyboardEvent
, nsIFrame
* aTargetFrame
,
192 nsEventStatus
& aStatus
);
195 * DispatchLegacyMouseScrollEvents() dispatches eLegacyMouseLineOrPageScroll
196 * event and eLegacyMousePixelScroll event for compatibility with old Gecko.
198 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void DispatchLegacyMouseScrollEvents(
199 nsIFrame
* aTargetFrame
, WidgetWheelEvent
* aEvent
, nsEventStatus
* aStatus
);
201 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void NotifyDestroyPresContext(
202 nsPresContext
* aPresContext
);
204 void ResetHoverState();
206 void SetPresContext(nsPresContext
* aPresContext
);
207 void ClearFrameRefs(nsIFrame
* aFrame
);
209 nsIFrame
* GetEventTarget();
210 already_AddRefed
<nsIContent
> GetEventTargetContent(WidgetEvent
* aEvent
);
212 // We manage 4 states here: ACTIVE, HOVER, DRAGOVER, URLTARGET
213 static bool ManagesState(ElementState aState
) {
214 return aState
== ElementState::ACTIVE
|| aState
== ElementState::HOVER
||
215 aState
== ElementState::DRAGOVER
||
216 aState
== ElementState::URLTARGET
;
220 * Notify that the given ElementState::* bit has changed for this content.
221 * @param aContent Content which has changed states
222 * @param aState Corresponding state flags such as ElementState::FOCUS
223 * @return Whether the content was able to change all states. Returns false
224 * if a resulting DOM event causes the content node passed in
225 * to not change states. Note, the frame for the content may
226 * change as a result of the content state change, because of
227 * frame reconstructions that may occur, but this does not
228 * affect the return value.
230 bool SetContentState(nsIContent
* aContent
, ElementState aState
);
232 nsIContent
* GetActiveContent() const { return mActiveContent
; }
234 void NativeAnonymousContentRemoved(nsIContent
* aAnonContent
);
235 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void ContentRemoved(dom::Document
* aDocument
,
236 nsIContent
* aContent
);
239 * Called when a native anonymous <div> element which is root element of
240 * text editor will be removed.
242 void TextControlRootWillBeRemoved(TextControlElement
& aTextControlElement
);
245 * Called when a native anonymous <div> element which is root element of
246 * text editor is created.
248 void TextControlRootAdded(dom::Element
& aAnonymousDivElement
,
249 TextControlElement
& aTextControlElement
);
251 bool EventStatusOK(WidgetGUIEvent
* aEvent
);
254 * EventStateManager stores IMEContentObserver while it's observing contents.
255 * Following mehtods are called by IMEContentObserver when it starts to
256 * observe or stops observing the content.
258 void OnStartToObserveContent(IMEContentObserver
* aIMEContentObserver
);
259 void OnStopObservingContent(IMEContentObserver
* aIMEContentObserver
);
262 * TryToFlushPendingNotificationsToIME() suggests flushing pending
263 * notifications to IME to IMEContentObserver.
264 * Doesn't do anything in child processes where flushing happens
267 void TryToFlushPendingNotificationsToIME();
269 static bool IsKeyboardEventUserActivity(WidgetEvent
* aEvent
);
272 * Register accesskey on the given element. When accesskey is activated then
273 * the element will be notified via Element::PerformAccesskey() method.
275 * @param aElement the given element
276 * @param aKey accesskey
278 void RegisterAccessKey(dom::Element
* aElement
, uint32_t aKey
);
281 * Unregister accesskey for the given element.
283 * @param aElement the given element
284 * @param aKey accesskey
286 void UnregisterAccessKey(dom::Element
* aElement
, uint32_t aKey
);
289 * Get accesskey registered on the given element or 0 if there is none.
291 * @param aElement the given element (must not be null)
292 * @return registered accesskey
294 uint32_t GetRegisteredAccessKey(dom::Element
* aContent
);
296 static void GetAccessKeyLabelPrefix(dom::Element
* aElement
,
300 * HandleAccessKey() looks for access keys which matches with aEvent and
301 * execute when it matches with a chrome access key or some content access
303 * If the event may match chrome access keys, this handles the access key
304 * synchronously (if there are nested ESMs, their HandleAccessKey() are
305 * also called recursively).
306 * If the event may match content access keys and focused target is a remote
307 * process, this does nothing for the content because when this is called,
308 * it should already have been handled in the remote process.
309 * If the event may match content access keys and focused target is not in
310 * remote process but there are some remote children, this will post
311 * HandleAccessKey messages to all remote children.
313 * @return true if there is accesskey which aEvent and
314 * aAccessCharCodes match with. Otherwise, false.
315 * I.e., when this returns true, a target is executed
317 * Note that even if this returns false, a target in
318 * remote process may be executed or focused
321 bool HandleAccessKey(WidgetKeyboardEvent
* aEvent
, nsPresContext
* aPresContext
,
322 nsTArray
<uint32_t>& aAccessCharCodes
) {
323 return WalkESMTreeToHandleAccessKey(aEvent
, aPresContext
, aAccessCharCodes
,
324 nullptr, eAccessKeyProcessingNormal
,
329 * CheckIfEventMatchesAccessKey() looks for access key which matches with
330 * aEvent in the process but won't execute it.
332 * @return true if there is accesskey which aEvent matches with
333 * in this process. Otherwise, false.
335 bool CheckIfEventMatchesAccessKey(WidgetKeyboardEvent
* aEvent
,
336 nsPresContext
* aPresContext
);
338 nsresult
SetCursor(StyleCursorKind
, imgIContainer
*, const ImageResolution
&,
339 const Maybe
<gfx::IntPoint
>& aHotspot
, nsIWidget
* aWidget
,
342 void StartHidingCursorWhileTyping(nsIWidget
*);
345 * Checks if the current mouse over element matches the given
346 * Element (which has a remote frame), and if so, notifies
347 * the BrowserParent of the mouse enter.
348 * Called when we reconstruct the BrowserParent and need to
349 * recompute state on the new object.
351 void RecomputeMouseEnterStateForRemoteFrame(dom::Element
& aElement
);
353 nsPresContext
* GetPresContext() { return mPresContext
; }
355 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(EventStateManager
, nsIObserver
)
357 // The manager in this process that is setting the cursor. In the parent
358 // process it might be null if a remote process is setting the cursor.
359 static EventStateManager
* sCursorSettingManager
;
360 static void ClearCursorSettingManager() { sCursorSettingManager
= nullptr; }
362 static EventStateManager
* GetActiveEventStateManager() { return sActiveESM
; }
364 // Sets aNewESM to be the active event state manager, and
365 // if aContent is non-null, marks the object as active.
366 static void SetActiveManager(EventStateManager
* aNewESM
,
367 nsIContent
* aContent
);
369 static bool IsRemoteTarget(nsIContent
* target
);
371 static bool IsTopLevelRemoteTarget(nsIContent
* aTarget
);
373 // Returns the kind of APZ action the given WidgetWheelEvent will perform.
374 static Maybe
<layers::APZWheelAction
> APZWheelActionFor(
375 const WidgetWheelEvent
* aEvent
);
377 // For some kinds of scrollings, the delta values of WidgetWheelEvent are
378 // possbile to be adjusted. This function is used to detect such scrollings
379 // and returns a wheel delta adjustment strategy to use, which is corresponded
380 // to the kind of the scrolling.
381 // It returns WheelDeltaAdjustmentStrategy::eAutoDir if the current default
382 // action is auto-dir scrolling which honours the scrolling target(The
383 // comments in WheelDeltaAdjustmentStrategy describes the concept in detail).
384 // It returns WheelDeltaAdjustmentStrategy::eAutoDirWithRootHonour if the
385 // current action is auto-dir scrolling which honours the root element in the
386 // document where the scrolling target is(The comments in
387 // WheelDeltaAdjustmentStrategy describes the concept in detail).
388 // It returns WheelDeltaAdjustmentStrategy::eHorizontalize if the current
389 // default action is horizontalized scrolling.
390 // It returns WheelDeltaAdjustmentStrategy::eNone to mean no delta adjustment
391 // strategy should be used if the scrolling is just a tranditional scrolling
392 // whose delta values are never possible to be adjusted.
393 static WheelDeltaAdjustmentStrategy
GetWheelDeltaAdjustmentStrategy(
394 const WidgetWheelEvent
& aEvent
);
396 // Returns user-set multipliers for a wheel event.
397 static void GetUserPrefsForWheelEvent(const WidgetWheelEvent
* aEvent
,
398 double* aOutMultiplierX
,
399 double* aOutMultiplierY
);
401 // Holds the point in screen coords that a mouse event was dispatched to,
402 // before we went into pointer lock mode. This is constantly updated while
403 // the pointer is not locked, but we don't update it while the pointer is
404 // locked. This is used by dom::Event::GetScreenCoords() to make mouse
405 // events' screen coord appear frozen at the last mouse position while
406 // the pointer is locked.
407 static CSSIntPoint sLastScreenPoint
;
409 // Holds the point in client coords of the last mouse event. Used by
410 // dom::Event::GetClientCoords() to make mouse events' client coords appear
411 // frozen at the last mouse position while the pointer is locked.
412 static CSSIntPoint sLastClientPoint
;
415 * If the absolute values of mMultiplierX and/or mMultiplierY are equal or
416 * larger than this value, the computed scroll amount isn't rounded down to
417 * the page width or height.
419 static constexpr double MIN_MULTIPLIER_VALUE_ALLOWING_OVER_ONE_PAGE_SCROLL
=
423 * HandleMiddleClickPaste() handles middle mouse button event as pasting
424 * clipboard text. Note that if aEditorBase is nullptr, this only
425 * dispatches ePaste event because it's necessary for some web apps which
426 * want to implement their own editor and supports middle click paste.
428 * @param aPresShell The PresShell for the ESM. This lifetime
429 * should be guaranteed by the caller.
430 * @param aMouseEvent The eMouseClick event which caused the
432 * @param aStatus The event status of aMouseEvent.
433 * @param aEditorBase EditorBase which may be pasted the
434 * clipboard text by the middle click.
435 * If there is no editor for aMouseEvent,
439 nsresult
HandleMiddleClickPaste(PresShell
* aPresShell
,
440 WidgetMouseEvent
* aMouseEvent
,
441 nsEventStatus
* aStatus
,
442 EditorBase
* aEditorBase
);
444 static void ConsumeInteractionData(
445 dom::Record
<nsString
, dom::InteractionData
>& aInteractions
);
447 // Stop tracking a possible drag. If aClearInChildProcesses is true, send
448 // a notification to any child processes that are in the drag service that
449 // tried to start a drag.
450 void StopTrackingDragGesture(bool aClearInChildProcesses
);
454 * If aTargetFrame's widget has a cached cursor value, resets the cursor
455 * such that the next call to SetCursor on the widget will force an update
456 * of the native cursor. For use in getting puppet widget to update its
457 * cursor between mouse exit / enter transitions. This call basically wraps
458 * nsIWidget ClearCachedCursor.
460 void ClearCachedWidgetCursor(nsIFrame
* aTargetFrame
);
462 void UpdateCursor(nsPresContext
*, WidgetMouseEvent
*, nsIFrame
* aTargetFrame
,
463 nsEventStatus
* aStatus
);
465 * Turn a GUI mouse/pointer event into a mouse/pointer event targeted at the
466 * specified content. This returns the primary frame for the content (or null
467 * if it goes away during the event).
469 MOZ_CAN_RUN_SCRIPT nsIFrame
* DispatchMouseOrPointerEvent(
470 WidgetMouseEvent
* aMouseEvent
, EventMessage aMessage
,
471 nsIContent
* aTargetContent
, nsIContent
* aRelatedContent
);
473 * Synthesize DOM pointerover and pointerout events
475 void GeneratePointerEnterExit(EventMessage aMessage
,
476 WidgetMouseEvent
* aEvent
);
478 * Synthesize DOM and frame mouseover and mouseout events from this
479 * MOUSE_MOVE or MOUSE_EXIT event.
481 void GenerateMouseEnterExit(WidgetMouseEvent
* aMouseEvent
);
483 * Tell this ESM and ESMs in parent documents that the mouse is
484 * over some content in this document.
486 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void NotifyMouseOver(
487 WidgetMouseEvent
* aMouseEvent
, nsIContent
* aContent
);
489 * Tell this ESM and ESMs in affected child documents that the mouse
490 * has exited this document's currently hovered content.
491 * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
493 * @param aMouseEvent the event that triggered the mouseout
494 * @param aMovingInto the content node we've moved into. This is used to set
495 * the relatedTarget for mouseout events. Also, if it's non-null
496 * NotifyMouseOut will NOT change the current hover content to null;
497 * in that case the caller is responsible for updating hover state.
499 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void NotifyMouseOut(WidgetMouseEvent
* aMouseEvent
,
500 nsIContent
* aMovingInto
);
501 MOZ_CAN_RUN_SCRIPT
void GenerateDragDropEnterExit(
502 nsPresContext
* aPresContext
, WidgetDragEvent
* aDragEvent
);
505 * Return mMouseEnterLeaveHelper or relevant mPointersEnterLeaveHelper
506 * elements wrapper. If mPointersEnterLeaveHelper does not contain wrapper for
507 * pointerId it create new one
509 OverOutElementsWrapper
* GetWrapperByEventID(WidgetMouseEvent
* aMouseEvent
);
512 * Fire the dragenter and dragexit/dragleave events when the mouse moves to a
515 * @param aRelatedTarget relatedTarget to set for the event
516 * @param aTargetContent target to set for the event
517 * @param aTargetFrame target frame for the event
519 MOZ_CAN_RUN_SCRIPT
void FireDragEnterOrExit(nsPresContext
* aPresContext
,
520 WidgetDragEvent
* aDragEvent
,
521 EventMessage aMessage
,
522 nsIContent
* aRelatedTarget
,
523 nsIContent
* aTargetContent
,
524 AutoWeakFrame
& aTargetFrame
);
526 * Update the initial drag session data transfer with any changes that occur
527 * on cloned data transfer objects used for events.
529 void UpdateDragDataTransfer(WidgetDragEvent
* dragEvent
);
532 * InitAndDispatchClickEvent() dispatches a click event.
534 * @param aMouseUpEvent eMouseUp event which causes the click event.
535 * EventCausesClickEvents() must return true
536 * if this event is set to it.
537 * @param aStatus Returns the result of click event.
538 * If the status indicates consumed, the
539 * value won't be overwritten with
540 * nsEventStatus_eIgnore.
541 * @param aMessage Should be eMouseClick, eMouseDoubleClick or
543 * @param aPresShell The PresShell.
544 * @param aMouseUpContent The event target of aMouseUpEvent.
545 * @param aCurrentTarget Current target of the caller.
546 * @param aNoContentDispatch true if the event shouldn't be exposed to
547 * web contents (although will be fired on
548 * document and window).
549 * @param aOverrideClickTarget Preferred click event target. If this is
550 * not nullptr, aMouseUpContent and
551 * aCurrentTarget are ignored.
554 static nsresult
InitAndDispatchClickEvent(
555 WidgetMouseEvent
* aMouseUpEvent
, nsEventStatus
* aStatus
,
556 EventMessage aMessage
, PresShell
* aPresShell
, nsIContent
* aMouseUpContent
,
557 AutoWeakFrame aCurrentTarget
, bool aNoContentDispatch
,
558 nsIContent
* aOverrideClickTarget
);
560 nsresult
SetClickCount(WidgetMouseEvent
* aEvent
, nsEventStatus
* aStatus
,
561 nsIContent
* aOverrideClickTarget
= nullptr);
564 * EventCausesClickEvents() returns true when aMouseEvent is an eMouseUp
565 * event and it should cause eMouseClick, eMouseDoubleClick and/or
566 * eMouseAuxClick events. Note that this method assumes that
567 * aMouseEvent.mClickCount has already been initialized with SetClickCount().
569 static bool EventCausesClickEvents(const WidgetMouseEvent
& aMouseEvent
);
572 * PostHandleMouseUp() handles default actions of eMouseUp event.
574 * @param aMouseUpEvent eMouseUp event which causes the click event.
575 * EventCausesClickEvents() must return true
576 * if this event is set to it.
577 * @param aStatus Returns the result of event status.
578 * If one of dispatching event is consumed or
579 * this does something as default action,
580 * returns nsEventStatus_eConsumeNoDefault.
581 * @param aOverrideClickTarget Preferred click event target. If nullptr,
582 * aMouseUpEvent target and current target
586 nsresult
PostHandleMouseUp(WidgetMouseEvent
* aMouseUpEvent
,
587 nsEventStatus
* aStatus
,
588 nsIContent
* aOverrideClickTarget
);
591 * DispatchClickEvents() dispatches eMouseClick, eMouseDoubleClick and
592 * eMouseAuxClick events for aMouseUpEvent. aMouseUpEvent should cause
595 * @param aPresShell The PresShell.
596 * @param aMouseUpEvent eMouseUp event which causes the click event.
597 * EventCausesClickEvents() must return true
598 * if this event is set to it.
599 * @param aStatus Returns the result of event status.
600 * If one of dispatching click event is
602 * nsEventStatus_eConsumeNoDefault.
603 * @param aMouseUpContent The event target of aMouseUpEvent.
604 * @param aOverrideClickTarget Preferred click event target. If this is
605 * not nullptr, aMouseUpContent and
606 * current target frame of the ESM are ignored.
609 nsresult
DispatchClickEvents(PresShell
* aPresShell
,
610 WidgetMouseEvent
* aMouseUpEvent
,
611 nsEventStatus
* aStatus
,
612 nsIContent
* aMouseUpContent
,
613 nsIContent
* aOverrideClickTarget
);
615 void EnsureDocument(nsPresContext
* aPresContext
);
616 MOZ_CAN_RUN_SCRIPT_BOUNDARY
617 void FlushLayout(nsPresContext
* aPresContext
);
620 * The phases of WalkESMTreeToHandleAccessKey processing. See below.
622 enum ProcessingAccessKeyState
{
623 eAccessKeyProcessingNormal
= 0,
624 eAccessKeyProcessingUp
,
625 eAccessKeyProcessingDown
629 * Walk EMS to look for access key and execute found access key when aExecute
631 * If there is registered element for the accesskey given by the key event
632 * and modifier mask then call element.PerformAccesskey(), otherwise call
633 * WalkESMTreeToHandleAccessKey() recursively, on descendant docshells first,
634 * then on the ancestor (with |aBubbledFrom| set to the docshell associated
635 * with |this|), until something matches.
637 * @param aEvent the keyboard event triggering the acccess key
638 * @param aPresContext the presentation context
639 * @param aAccessCharCodes list of charcode candidates
640 * @param aBubbledFrom is used by an ancestor to avoid calling
641 * WalkESMTreeToHandleAccessKey() on the child the call originally
642 * came from, i.e. this is the child that recursively called us in
643 * its Up phase. The initial caller passes |nullptr| here. This is to
644 * avoid an infinite loop.
645 * @param aAccessKeyState Normal, Down or Up processing phase (see enums
646 * above). The initial event receiver uses 'normal', then 'down' when
647 * processing children and Up when recursively calling its ancestor.
648 * @param aExecute is true, execute an accesskey if it's found. Otherwise,
649 * found accesskey won't be executed.
651 * @return true if there is a target which aEvent and
652 * aAccessCharCodes match with in this process.
653 * Otherwise, false. I.e., when this returns true and
654 * aExecute is true, a target is executed or focused.
655 * Note that even if this returns false, a target in
656 * remote process may be executed or focused
659 bool WalkESMTreeToHandleAccessKey(WidgetKeyboardEvent
* aEvent
,
660 nsPresContext
* aPresContext
,
661 nsTArray
<uint32_t>& aAccessCharCodes
,
662 nsIDocShellTreeItem
* aBubbledFrom
,
663 ProcessingAccessKeyState aAccessKeyState
,
667 * Look for access key and execute found access key if aExecute is true in
670 * @return true if there is a target which matches with
671 * aAccessCharCodes and aIsTrustedEvent. Otherwise,
672 * false. I.e., when this returns true and aExecute
673 * is true, a target is executed or focused.
675 MOZ_CAN_RUN_SCRIPT_BOUNDARY
bool LookForAccessKeyAndExecute(
676 nsTArray
<uint32_t>& aAccessCharCodes
, bool aIsTrustedEvent
,
677 bool aIsRepeat
, bool aExecute
);
679 //---------------------------------------------
680 // DocShell Focus Traversal Methods
681 //---------------------------------------------
683 dom::Element
* GetFocusedElement();
684 bool IsShellVisible(nsIDocShell
* aShell
);
686 // These functions are for mousewheel and pixel scrolling
690 static WheelPrefs
* GetInstance();
691 static void Shutdown();
694 * ApplyUserPrefsToDelta() overrides the wheel event's delta values with
697 void ApplyUserPrefsToDelta(WidgetWheelEvent
* aEvent
);
700 * Returns whether or not ApplyUserPrefsToDelta() would change the delta
701 * values of an event.
703 void GetUserPrefsForEvent(const WidgetWheelEvent
* aEvent
,
704 double* aOutMultiplierX
, double* aOutMultiplierY
);
707 * If ApplyUserPrefsToDelta() changed the delta values with customized
708 * prefs, the overflowDelta values would be inflated.
709 * CancelApplyingUserPrefsFromOverflowDelta() cancels the inflation.
711 void CancelApplyingUserPrefsFromOverflowDelta(WidgetWheelEvent
* aEvent
);
714 * Computes the default action for the aEvent with the prefs.
716 enum Action
: uint8_t {
721 // Horizontalized scrolling means treating vertical wheel scrolling as
722 // horizontal scrolling during the process of its default action and
723 // plugins handling scrolling. Note that delta values as the event object
724 // in a DOM event listener won't be affected, and will be still the
725 // original values. For more details, refer to
726 // mozilla::WheelDeltaAdjustmentStrategy::eHorizontalize
727 ACTION_HORIZONTALIZED_SCROLL
,
729 ACTION_LAST
= ACTION_PINCH_ZOOM
,
730 // Following actions are used only by internal processing. So, cannot
731 // specified by prefs.
732 ACTION_SEND_TO_PLUGIN
,
734 Action
ComputeActionFor(const WidgetWheelEvent
* aEvent
);
737 * NeedToComputeLineOrPageDelta() returns if the aEvent needs to be
738 * computed the lineOrPageDelta values.
740 bool NeedToComputeLineOrPageDelta(const WidgetWheelEvent
* aEvent
);
743 * IsOverOnePageScrollAllowed*() checks whether wheel scroll amount should
744 * be rounded down to the page width/height (false) or not (true).
746 bool IsOverOnePageScrollAllowedX(const WidgetWheelEvent
* aEvent
);
747 bool IsOverOnePageScrollAllowedY(const WidgetWheelEvent
* aEvent
);
753 static void OnPrefChanged(const char* aPrefName
, void* aClosure
);
765 * GetIndexFor() returns the index of the members which should be used for
766 * the aEvent. When only one modifier key of MODIFIER_ALT,
767 * MODIFIER_CONTROL, MODIFIER_META or MODIFIER_SHIFT is pressed, returns the
768 * index for the modifier. Otherwise, this return the default index which
769 * is used at either no modifier key is pressed or two or modifier keys are
772 Index
GetIndexFor(const WidgetWheelEvent
* aEvent
);
775 * GetPrefNameBase() returns the base pref name for aEvent.
776 * It's decided by GetModifierForPref() which modifier should be used for
779 * @param aBasePrefName The result, must be "mousewheel.with_*." or
780 * "mousewheel.default.".
782 void GetBasePrefName(Index aIndex
, nsACString
& aBasePrefName
);
784 void Init(Index aIndex
);
789 * Retrieve multiplier for aEvent->mDeltaX and aEvent->mDeltaY.
791 * Note that if the default action is ACTION_HORIZONTALIZED_SCROLL and the
792 * delta values have been adjusted by WheelDeltaHorizontalizer() before this
793 * function is called, this function will swap the X and Y multipliers. By
794 * doing this, multipliers will still apply to the delta values they
795 * originally corresponded to.
797 * @param aEvent The event which is being handled.
798 * @param aIndex The index of mMultiplierX and mMultiplierY.
799 * Should be result of GetIndexFor(aEvent).
800 * @param aMultiplierForDeltaX Will be set to multiplier for
802 * @param aMultiplierForDeltaY Will be set to multiplier for
805 void GetMultiplierForDeltaXAndY(const WidgetWheelEvent
* aEvent
,
806 Index aIndex
, double* aMultiplierForDeltaX
,
807 double* aMultiplierForDeltaY
);
809 bool mInit
[COUNT_OF_MULTIPLIERS
];
810 double mMultiplierX
[COUNT_OF_MULTIPLIERS
];
811 double mMultiplierY
[COUNT_OF_MULTIPLIERS
];
812 double mMultiplierZ
[COUNT_OF_MULTIPLIERS
];
813 Action mActions
[COUNT_OF_MULTIPLIERS
];
815 * action values overridden by .override_x pref.
816 * If an .override_x value is -1, same as the
817 * corresponding mActions value.
819 Action mOverriddenActionsX
[COUNT_OF_MULTIPLIERS
];
821 static WheelPrefs
* sInstance
;
825 * DeltaDirection is used for specifying whether the called method should
826 * handle vertical delta or horizontal delta.
827 * This is clearer than using bool.
829 enum DeltaDirection
{ DELTA_DIRECTION_X
= 0, DELTA_DIRECTION_Y
};
831 struct MOZ_STACK_CLASS EventState
{
832 bool mDefaultPrevented
;
833 bool mDefaultPreventedByContent
;
836 : mDefaultPrevented(false), mDefaultPreventedByContent(false) {}
840 * SendLineScrollEvent() dispatches a DOMMouseScroll event for the
841 * WidgetWheelEvent. This method shouldn't be called for non-trusted
842 * wheel event because it's not necessary for compatiblity.
844 * @param aTargetFrame The event target of wheel event.
845 * @param aEvent The original Wheel event.
846 * @param aState The event which should be set to the dispatching
847 * event. This also returns the dispatched event
849 * @param aDelta The delta value of the event.
850 * @param aDeltaDirection The X/Y direction of dispatching event.
852 MOZ_CAN_RUN_SCRIPT
void SendLineScrollEvent(nsIFrame
* aTargetFrame
,
853 WidgetWheelEvent
* aEvent
,
856 DeltaDirection aDeltaDirection
);
859 * SendPixelScrollEvent() dispatches a MozMousePixelScroll event for the
860 * WidgetWheelEvent. This method shouldn't be called for non-trusted
861 * wheel event because it's not necessary for compatiblity.
863 * @param aTargetFrame The event target of wheel event.
864 * @param aEvent The original Wheel event.
865 * @param aState The event which should be set to the dispatching
866 * event. This also returns the dispatched event
868 * @param aPixelDelta The delta value of the event.
869 * @param aDeltaDirection The X/Y direction of dispatching event.
871 MOZ_CAN_RUN_SCRIPT
void SendPixelScrollEvent(nsIFrame
* aTargetFrame
,
872 WidgetWheelEvent
* aEvent
,
875 DeltaDirection aDeltaDirection
);
878 * ComputeScrollTargetAndMayAdjustWheelEvent() returns the scrollable frame
879 * which should be scrolled.
881 * @param aTargetFrame The event target of the wheel event.
882 * @param aEvent The handling mouse wheel event.
883 * @param aOptions The options for finding the scroll target.
884 * Callers should use COMPUTE_*.
885 * @return The scrollable frame which should be scrolled.
887 // These flags are used in ComputeScrollTargetAndMayAdjustWheelEvent().
888 // Callers should use COMPUTE_*.
890 PREFER_MOUSE_WHEEL_TRANSACTION
= 0x00000001,
891 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS
= 0x00000002,
892 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS
= 0x00000004,
893 START_FROM_PARENT
= 0x00000008,
894 INCLUDE_PLUGIN_AS_TARGET
= 0x00000010,
895 // Indicates the wheel scroll event being computed is an auto-dir scroll, so
896 // its delta may be adjusted after being computed.
897 MAY_BE_ADJUSTED_BY_AUTO_DIR
= 0x00000020,
899 enum ComputeScrollTargetOptions
{
900 // At computing scroll target for legacy mouse events, we should return
901 // first scrollable element even when it's not scrollable to the direction.
902 COMPUTE_LEGACY_MOUSE_SCROLL_EVENT_TARGET
= 0,
903 // Default action prefers the scrolled element immediately before if it's
904 // still under the mouse cursor. Otherwise, it prefers the nearest
905 // scrollable ancestor which will be scrolled actually.
906 COMPUTE_DEFAULT_ACTION_TARGET
=
907 (PREFER_MOUSE_WHEEL_TRANSACTION
|
908 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS
|
909 PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS
),
910 COMPUTE_DEFAULT_ACTION_TARGET_WITH_AUTO_DIR
=
911 (COMPUTE_DEFAULT_ACTION_TARGET
| MAY_BE_ADJUSTED_BY_AUTO_DIR
),
912 // Look for the nearest scrollable ancestor which can be scrollable with
914 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS
=
915 (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS
| START_FROM_PARENT
),
916 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS
=
917 (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS
| START_FROM_PARENT
),
918 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS_WITH_AUTO_DIR
=
919 (COMPUTE_SCROLLABLE_ANCESTOR_ALONG_X_AXIS
|
920 MAY_BE_ADJUSTED_BY_AUTO_DIR
),
921 COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS_WITH_AUTO_DIR
=
922 (COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS
|
923 MAY_BE_ADJUSTED_BY_AUTO_DIR
),
926 // Compute the scroll target.
927 // The delta values in the wheel event may be changed if the event is for
928 // auto-dir scrolling. For information on auto-dir,
929 // @see mozilla::WheelDeltaAdjustmentStrategy
930 nsIFrame
* ComputeScrollTargetAndMayAdjustWheelEvent(
931 nsIFrame
* aTargetFrame
, WidgetWheelEvent
* aEvent
,
932 ComputeScrollTargetOptions aOptions
);
934 nsIFrame
* ComputeScrollTargetAndMayAdjustWheelEvent(
935 nsIFrame
* aTargetFrame
, double aDirectionX
, double aDirectionY
,
936 WidgetWheelEvent
* aEvent
, ComputeScrollTargetOptions aOptions
);
938 nsIFrame
* ComputeScrollTarget(nsIFrame
* aTargetFrame
,
939 WidgetWheelEvent
* aEvent
,
940 ComputeScrollTargetOptions aOptions
) {
941 MOZ_ASSERT(!(aOptions
& MAY_BE_ADJUSTED_BY_AUTO_DIR
),
942 "aEvent may be modified by auto-dir");
943 return ComputeScrollTargetAndMayAdjustWheelEvent(aTargetFrame
, aEvent
,
947 nsIFrame
* ComputeScrollTarget(nsIFrame
* aTargetFrame
, double aDirectionX
,
948 double aDirectionY
, WidgetWheelEvent
* aEvent
,
949 ComputeScrollTargetOptions aOptions
) {
950 MOZ_ASSERT(!(aOptions
& MAY_BE_ADJUSTED_BY_AUTO_DIR
),
951 "aEvent may be modified by auto-dir");
952 return ComputeScrollTargetAndMayAdjustWheelEvent(
953 aTargetFrame
, aDirectionX
, aDirectionY
, aEvent
, aOptions
);
957 * GetScrollAmount() returns the scroll amount in app uints of one line or
958 * one page. If the wheel event scrolls a page, returns the page width and
959 * height. Otherwise, returns line height for both its width and height.
961 * @param aScrollableFrame A frame which will be scrolled by the event.
963 * ComputeScrollTargetAndMayAdjustWheelEvent() is
964 * expected for this value.
965 * This can be nullptr if there is no scrollable
966 * frame. Then, this method uses root frame's
967 * line height or visible area's width and height.
969 nsSize
GetScrollAmount(nsPresContext
* aPresContext
, WidgetWheelEvent
* aEvent
,
970 nsIScrollableFrame
* aScrollableFrame
);
973 * DoScrollText() scrolls the scrollable frame for aEvent.
975 void DoScrollText(nsIScrollableFrame
* aScrollableFrame
,
976 WidgetWheelEvent
* aEvent
);
978 void DoScrollHistory(int32_t direction
);
979 void DoScrollZoom(nsIFrame
* aTargetFrame
, int32_t adjustment
);
980 void ChangeZoom(bool aIncrease
);
983 * DeltaAccumulator class manages delta values for dispatching DOMMouseScroll
984 * event. If wheel events are caused by pixel scroll only devices or
985 * the delta values are customized by prefs, this class stores the delta
986 * values and set lineOrPageDelta values.
988 class DeltaAccumulator
{
990 static DeltaAccumulator
* GetInstance() {
992 sInstance
= new DeltaAccumulator
;
997 static void Shutdown() {
1002 bool IsInTransaction() { return mHandlingDeltaMode
!= UINT32_MAX
; }
1005 * InitLineOrPageDelta() stores pixel delta values of WidgetWheelEvents
1006 * which are caused if it's needed. And if the accumulated delta becomes a
1007 * line height, sets lineOrPageDeltaX and lineOrPageDeltaY automatically.
1009 void InitLineOrPageDelta(nsIFrame
* aTargetFrame
, EventStateManager
* aESM
,
1010 WidgetWheelEvent
* aEvent
);
1013 * Reset() resets all members.
1018 * ComputeScrollAmountForDefaultAction() computes the default action's
1019 * scroll amount in device pixels with mPendingScrollAmount*.
1021 nsIntPoint
ComputeScrollAmountForDefaultAction(
1022 WidgetWheelEvent
* aEvent
, const nsIntSize
& aScrollAmountInDevPixels
);
1028 mPendingScrollAmountX(0.0),
1029 mPendingScrollAmountY(0.0),
1030 mHandlingDeltaMode(UINT32_MAX
),
1031 mIsNoLineOrPageDeltaDevice(false) {}
1036 // When default action of a wheel event is scroll but some delta values
1037 // are ignored because the computed amount values are not integer, the
1038 // fractional values are saved by these members.
1039 double mPendingScrollAmountX
;
1040 double mPendingScrollAmountY
;
1042 TimeStamp mLastTime
;
1044 uint32_t mHandlingDeltaMode
;
1045 bool mIsNoLineOrPageDeltaDevice
;
1047 static DeltaAccumulator
* sInstance
;
1050 // end mousewheel functions
1053 * When a touch gesture is about to start, this function determines what
1054 * kind of gesture interaction we will want to use, based on what is
1055 * underneath the initial touch point.
1056 * Currently it decides between panning (finger scrolling) or dragging
1057 * the target element, as well as the orientation to trigger panning and
1058 * display visual boundary feedback. The decision is stored back in aEvent.
1060 void DecideGestureEvent(WidgetGestureNotifyEvent
* aEvent
,
1061 nsIFrame
* targetFrame
);
1063 // routines for the d&d gesture tracking state machine
1064 void BeginTrackingDragGesture(nsPresContext
* aPresContext
,
1065 WidgetMouseEvent
* aDownEvent
,
1066 nsIFrame
* aDownFrame
);
1068 void SetGestureDownPoint(WidgetGUIEvent
* aEvent
);
1070 LayoutDeviceIntPoint
GetEventRefPoint(WidgetEvent
* aEvent
) const;
1072 friend class mozilla::dom::BrowserParent
;
1073 void BeginTrackingRemoteDragGesture(nsIContent
* aContent
,
1074 dom::RemoteDragStartData
* aDragStartData
);
1077 void GenerateDragGesture(nsPresContext
* aPresContext
,
1078 WidgetInputEvent
* aEvent
);
1081 * When starting a dnd session, UA must fire a pointercancel event and stop
1082 * firing the subsequent pointer events.
1085 void MaybeFirePointerCancel(WidgetInputEvent
* aEvent
);
1088 * Determine which node the drag should be targeted at.
1089 * This is either the node clicked when there is a selection, or, for HTML,
1090 * the element with a draggable property set to true.
1092 * aSelectionTarget - target to check for selection
1093 * aDataTransfer - data transfer object that will contain the data to drag
1094 * aAllowEmptyDataTransfer - [out] set to true, if dnd operation can be
1095 * started even if DataTransfer is empty
1096 * aSelection - [out] set to the selection to be dragged
1097 * aTargetNode - [out] the draggable node, or null if there isn't one
1098 * aPrincipal - [out] set to the triggering principal of the drag, or null
1099 * if it's from browser chrome or OS
1100 * aCookieJarSettings - [out] set to the cookieJarSettings of the drag, or
1101 * null if it's from browser chrome or OS.
1103 void DetermineDragTargetAndDefaultData(
1104 nsPIDOMWindowOuter
* aWindow
, nsIContent
* aSelectionTarget
,
1105 dom::DataTransfer
* aDataTransfer
, bool* aAllowEmptyDataTransfer
,
1106 dom::Selection
** aSelection
,
1107 dom::RemoteDragStartData
** aRemoteDragStartData
, nsIContent
** aTargetNode
,
1108 nsIPrincipal
** aPrincipal
, nsIContentSecurityPolicy
** aCsp
,
1109 nsICookieJarSettings
** aCookieJarSettings
);
1112 * Perform the default handling for the dragstart event and set up a
1113 * drag for aDataTransfer if it contains any data. Returns true if a drag has
1116 * aDragEvent - the dragstart event
1117 * aDataTransfer - the data transfer that holds the data to be dragged
1118 * aAllowEmptyDataTransfer - if true, dnd can be started even if there is no
1120 * aDragTarget - the target of the drag
1121 * aSelection - the selection to be dragged
1122 * aData - information pertaining to a drag started in a child process
1123 * aPrincipal - the triggering principal of the drag, or null if it's from
1124 * browser chrome or OS
1125 * aCookieJarSettings - the cookieJarSettings of the drag. or null if it's
1126 * from browser chrome or OS.
1129 bool DoDefaultDragStart(
1130 nsPresContext
* aPresContext
, WidgetDragEvent
* aDragEvent
,
1131 dom::DataTransfer
* aDataTransfer
, bool aAllowEmptyDataTransfer
,
1132 nsIContent
* aDragTarget
, dom::Selection
* aSelection
,
1133 dom::RemoteDragStartData
* aDragStartData
, nsIPrincipal
* aPrincipal
,
1134 nsIContentSecurityPolicy
* aCsp
, nsICookieJarSettings
* aCookieJarSettings
);
1136 bool IsTrackingDragGesture() const { return mGestureDownContent
!= nullptr; }
1138 * Set the fields of aEvent to reflect the mouse position and modifier keys
1139 * that were set when the user first pressed the mouse button (stored by
1140 * BeginTrackingDragGesture). aEvent->mWidget must be
1141 * mCurrentTarget->GetNearestWidget().
1143 void FillInEventFromGestureDown(WidgetMouseEvent
* aEvent
);
1146 nsresult
DoContentCommandEvent(WidgetContentCommandEvent
* aEvent
);
1148 nsresult
DoContentCommandInsertTextEvent(WidgetContentCommandEvent
* aEvent
);
1149 nsresult
DoContentCommandScrollEvent(WidgetContentCommandEvent
* aEvent
);
1151 dom::BrowserParent
* GetCrossProcessTarget();
1152 bool IsTargetCrossProcess(WidgetGUIEvent
* aEvent
);
1155 * DispatchCrossProcessEvent() try to post aEvent to target remote process.
1156 * If you need to check if the event is posted to a remote process, you
1157 * can use aEvent->HasBeenPostedToRemoteProcess().
1159 void DispatchCrossProcessEvent(WidgetEvent
* aEvent
,
1160 dom::BrowserParent
* aRemoteTarget
,
1161 nsEventStatus
* aStatus
);
1163 * HandleCrossProcessEvent() may post aEvent to target remote processes.
1164 * When it succeeded to post the event to at least one remote process,
1165 * returns true. Otherwise, including the case not tried to dispatch to
1166 * post the event, returns false.
1167 * If you need to check if the event is posted to at least one remote
1168 * process, you can use aEvent->HasBeenPostedToRemoteProcess().
1170 bool HandleCrossProcessEvent(WidgetEvent
* aEvent
, nsEventStatus
* aStatus
);
1172 void ReleaseCurrentIMEContentObserver();
1174 MOZ_CAN_RUN_SCRIPT
void HandleQueryContentEvent(
1175 WidgetQueryContentEvent
* aEvent
);
1178 // Removes a node from the :hover / :active chain if needed, notifying if the
1179 // node is not a NAC subtree.
1181 // Only meant to be called from ContentRemoved and
1182 // NativeAnonymousContentRemoved.
1183 void RemoveNodeFromChainIfNeeded(ElementState aState
,
1184 nsIContent
* aContentRemoved
, bool aNotify
);
1186 bool IsEventOutsideDragThreshold(WidgetInputEvent
* aEvent
) const;
1188 static inline void DoStateChange(dom::Element
* aElement
, ElementState aState
,
1190 static inline void DoStateChange(nsIContent
* aContent
, ElementState aState
,
1192 static void UpdateAncestorState(nsIContent
* aStartNode
,
1193 nsIContent
* aStopBefore
, ElementState aState
,
1197 * Update the attribute mLastRefPoint of the mouse event. It should be
1198 * the center of the window while the pointer is locked.
1199 * the same value as mRefPoint while there is no known last ref point.
1200 * the same value as the last known mRefPoint.
1202 static void UpdateLastRefPointOfMouseEvent(WidgetMouseEvent
* aMouseEvent
);
1204 static void ResetPointerToWindowCenterWhilePointerLocked(
1205 WidgetMouseEvent
* aMouseEvent
);
1207 // Update the last known ref point to the current event's mRefPoint.
1208 static void UpdateLastPointerPosition(WidgetMouseEvent
* aMouseEvent
);
1211 * Notify target when user has been interaction with some speicific user
1212 * gestures which are eKeyUp, eMouseUp, eTouchEnd.
1214 void NotifyTargetUserActivation(WidgetEvent
* aEvent
,
1215 nsIContent
* aTargetContent
);
1218 * https://html.spec.whatwg.org/multipage/popover.html#light-dismiss-open-popovers.
1220 MOZ_CAN_RUN_SCRIPT
void LightDismissOpenPopovers(WidgetEvent
* aEvent
,
1221 nsIContent
* aTargetContent
);
1223 already_AddRefed
<EventStateManager
> ESMFromContentOrThis(
1224 nsIContent
* aContent
);
1226 struct LastMouseDownInfo
{
1227 nsCOMPtr
<nsIContent
> mLastMouseDownContent
;
1228 Maybe
<FormControlType
> mLastMouseDownInputControlType
;
1229 uint32_t mClickCount
= 0;
1232 LastMouseDownInfo
& GetLastMouseDownInfo(int16_t aButton
);
1234 // These variables are only relevant if we're the cursor-setting manager.
1235 StyleCursorKind mLockCursor
;
1236 bool mHidingCursorWhileTyping
= false;
1238 // Last mouse event screen point (in device pixel) when mouse was locked, used
1239 // to restore mouse position after unlocking.
1240 static LayoutDeviceIntPoint sPreLockScreenPoint
;
1242 // Stores the mRefPoint of the last synthetic mouse move we dispatched
1243 // to re-center the mouse when we were pointer locked. If this is (-1,-1) it
1244 // means we've not recently dispatched a centering event. We use this to
1245 // detect when we receive the synth event, so we can cancel and not send it
1247 static LayoutDeviceIntPoint sSynthCenteringPoint
;
1249 WeakFrame mCurrentTarget
;
1250 nsCOMPtr
<nsIContent
> mCurrentTargetContent
;
1251 static AutoWeakFrame sLastDragOverFrame
;
1253 // Stores the mRefPoint (the offset from the widget's origin in device
1254 // pixels) of the last mouse event.
1255 static LayoutDeviceIntPoint sLastRefPoint
;
1257 // member variables for the d&d gesture state machine
1258 LayoutDeviceIntPoint mGestureDownPoint
; // screen coordinates
1259 // The content to use as target if we start a d&d (what we drag).
1260 RefPtr
<nsIContent
> mGestureDownContent
;
1261 // The content of the frame where the mouse-down event occurred. It's the same
1262 // as the target in most cases but not always - for example when dragging
1263 // an <area> of an image map this is the image. (bug 289667)
1264 nsCOMPtr
<nsIContent
> mGestureDownFrameOwner
;
1265 // Data associated with a drag started in a content process.
1266 RefPtr
<dom::RemoteDragStartData
> mGestureDownDragStartData
;
1267 // State of keys when the original gesture-down happened
1268 Modifiers mGestureModifiers
;
1269 uint16_t mGestureDownButtons
;
1271 LastMouseDownInfo mLastLeftMouseDownInfo
;
1272 LastMouseDownInfo mLastMiddleMouseDownInfo
;
1273 LastMouseDownInfo mLastRightMouseDownInfo
;
1275 nsCOMPtr
<nsIContent
> mActiveContent
;
1276 nsCOMPtr
<nsIContent
> mHoverContent
;
1277 static nsCOMPtr
<nsIContent
> sDragOverContent
;
1278 nsCOMPtr
<nsIContent
> mURLTargetContent
;
1279 nsCOMPtr
<nsINode
> mPopoverPointerDownTarget
;
1281 nsPresContext
* mPresContext
; // Not refcnted
1282 RefPtr
<dom::Document
> mDocument
; // Doesn't necessarily need to be owner
1284 RefPtr
<IMEContentObserver
> mIMEContentObserver
;
1286 bool mShouldAlwaysUseLineDeltas
: 1;
1287 bool mShouldAlwaysUseLineDeltasInitialized
: 1;
1289 bool mGestureDownInTextControl
: 1;
1293 bool m_haveShutdown
;
1295 RefPtr
<OverOutElementsWrapper
> mMouseEnterLeaveHelper
;
1296 nsRefPtrHashtable
<nsUint32HashKey
, OverOutElementsWrapper
>
1297 mPointersEnterLeaveHelper
;
1299 // Array for accesskey support
1300 nsCOMArray
<dom::Element
> mAccessKeys
;
1302 bool ShouldAlwaysUseLineDeltas();
1305 static nsresult
UpdateUserActivityTimer(void);
1307 static bool sNormalLMouseEventInProcess
;
1308 static int16_t sCurrentMouseBtn
;
1310 static EventStateManager
* sActiveESM
;
1312 static void ClearGlobalActiveContent(EventStateManager
* aClearer
);
1314 // Functions used for click hold context menus
1315 nsCOMPtr
<nsITimer
> mClickHoldTimer
;
1316 void CreateClickHoldTimer(nsPresContext
* aPresContext
, nsIFrame
* aDownFrame
,
1317 WidgetGUIEvent
* aMouseDownEvent
);
1318 void KillClickHoldTimer();
1319 MOZ_CAN_RUN_SCRIPT_BOUNDARY
void FireContextClick();
1321 MOZ_CAN_RUN_SCRIPT
static void SetPointerLock(nsIWidget
* aWidget
,
1322 nsPresContext
* aPresContext
);
1323 static void sClickHoldCallback(nsITimer
* aTimer
, void* aESM
);
1326 } // namespace mozilla
1328 // Click and double-click events need to be handled even for content that
1329 // has no frame. This is required for Web compatibility.
1330 #define NS_EVENT_NEEDS_FRAME(event) \
1331 ((event)->mMessage != eMouseClick && \
1332 (event)->mMessage != eMouseDoubleClick && \
1333 (event)->mMessage != eMouseAuxClick)
1335 #endif // mozilla_EventStateManager_h_