1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_BasicEvents_h__
7 #define mozilla_BasicEvents_h__
11 #include "mozilla/dom/EventTarget.h"
12 #include "mozilla/layers/LayersTypes.h"
13 #include "mozilla/EventForwards.h"
14 #include "mozilla/TimeStamp.h"
17 #include "nsISupportsImpl.h"
18 #include "nsIWidget.h"
23 # include "nsXULAppAPI.h"
24 #endif // #ifdef DEBUG
33 class EventTargetChainItem
;
35 enum class CrossProcessForwarding
{
36 // eStop prevents the event to be sent to remote process.
38 // eAllow keeps current state of the event whether it's sent to remote
39 // process. In other words, eAllow does NOT mean that making the event
40 // sent to remote process when IsCrossProcessForwardingStopped() returns
45 /******************************************************************************
46 * mozilla::BaseEventFlags
48 * BaseEventFlags must be a POD struct for safe to use memcpy (including
49 * in ParamTraits<BaseEventFlags>). So don't make virtual methods, constructor,
50 * destructor and operators.
51 * This is necessary for VC which is NOT C++0x compiler.
52 ******************************************************************************/
54 struct BaseEventFlags
{
56 // If mIsTrusted is true, the event is a trusted event. Otherwise, it's
57 // an untrusted event.
59 // If mInBubblingPhase is true, the event is in bubbling phase or target
61 bool mInBubblingPhase
: 1;
62 // If mInCapturePhase is true, the event is in capture phase or target phase.
63 bool mInCapturePhase
: 1;
64 // If mInSystemGroup is true, the event is being dispatched in system group.
65 bool mInSystemGroup
: 1;
66 // If mCancelable is true, the event can be consumed. I.e., calling
67 // dom::Event::PreventDefault() can prevent the default action.
69 // If mBubbles is true, the event can bubble. Otherwise, cannot be handled
72 // If mPropagationStopped is true, dom::Event::StopPropagation() or
73 // dom::Event::StopImmediatePropagation() has been called.
74 bool mPropagationStopped
: 1;
75 // If mImmediatePropagationStopped is true,
76 // dom::Event::StopImmediatePropagation() has been called.
77 // Note that mPropagationStopped must be true when this is true.
78 bool mImmediatePropagationStopped
: 1;
79 // If mDefaultPrevented is true, the event has been consumed.
80 // E.g., dom::Event::PreventDefault() has been called or
81 // the default action has been performed.
82 bool mDefaultPrevented
: 1;
83 // If mDefaultPreventedByContent is true, the event has been
84 // consumed by content.
85 // Note that mDefaultPrevented must be true when this is true.
86 bool mDefaultPreventedByContent
: 1;
87 // If mDefaultPreventedByChrome is true, the event has been
88 // consumed by chrome.
89 // Note that mDefaultPrevented must be true when this is true.
90 bool mDefaultPreventedByChrome
: 1;
91 // mMultipleActionsPrevented may be used when default handling don't want to
92 // be prevented, but only one of the event targets should handle the event.
93 // For example, when a <label> element is in another <label> element and
94 // the first <label> element is clicked, that one may set this true.
95 // Then, the second <label> element won't handle the event.
96 bool mMultipleActionsPrevented
: 1;
97 // Similar to above but expected to be used during PreHandleEvent phase.
98 bool mMultiplePreActionsPrevented
: 1;
99 // If mIsBeingDispatched is true, the DOM event created from the event is
100 // dispatching into the DOM tree and not completed.
101 bool mIsBeingDispatched
: 1;
102 // If mDispatchedAtLeastOnce is true, the event has been dispatched
103 // as a DOM event and the dispatch has been completed.
104 bool mDispatchedAtLeastOnce
: 1;
105 // If mIsSynthesizedForTests is true, the event has been synthesized for
106 // automated tests or something hacky approach of an add-on.
107 bool mIsSynthesizedForTests
: 1;
108 // If mExceptionWasRaised is true, one of the event handlers has raised an
110 bool mExceptionWasRaised
: 1;
111 // If mRetargetToNonNativeAnonymous is true and the target is in a non-native
112 // native anonymous subtree, the event target is set to mOriginalTarget.
113 bool mRetargetToNonNativeAnonymous
: 1;
114 // If mNoContentDispatch is true, the event is never dispatched to the
115 // event handlers which are added to the contents, onfoo attributes and
116 // properties. Note that this flag is ignored when
117 // EventChainPreVisitor::mForceContentDispatch is set true. For exapmle,
118 // window and document object sets it true. Therefore, web applications
119 // can handle the event if they add event listeners to the window or the
121 // XXX This is an ancient and broken feature, don't use this for new bug
122 // as far as possible.
123 bool mNoContentDispatch
: 1;
124 // If mOnlyChromeDispatch is true, the event is dispatched to only chrome.
125 bool mOnlyChromeDispatch
: 1;
126 // Indicates if the key combination is reserved by chrome. This is set by
127 // MarkAsReservedByChrome().
128 bool mIsReservedByChrome
: 1;
129 // If mOnlySystemGroupDispatchInContent is true, event listeners added to
130 // the default group for non-chrome EventTarget won't be called.
131 // Be aware, if this is true, EventDispatcher needs to check if each event
132 // listener is added to chrome node, so, don't set this to true for the
133 // events which are fired a lot of times like eMouseMove.
134 bool mOnlySystemGroupDispatchInContent
: 1;
135 // If mOnlySystemGroupDispatch is true, the event will be dispatched only to
136 // event listeners added in the system group.
137 bool mOnlySystemGroupDispatch
: 1;
138 // The event's action will be handled by APZ. The main thread should not
139 // perform its associated action.
140 bool mHandledByAPZ
: 1;
141 // True if the event is currently being handled by an event listener that
142 // was registered as a passive listener.
143 bool mInPassiveListener
: 1;
144 // If mComposed is true, the event fired by nodes in shadow DOM can cross the
145 // boundary of shadow DOM and light DOM.
147 // Similar to mComposed. Set it to true to allow events cross the boundary
148 // between native non-anonymous content and native anonymouse content
149 bool mComposedInNativeAnonymousContent
: 1;
150 // Set to true for events which are suppressed or delayed so that later a
151 // DelayedEvent of it is dispatched. This is used when parent side process
152 // the key event after content side, and may drop the event if the event
153 // was suppressed or delayed in contents side.
154 // It is also set to true for the events (in a DelayedInputEvent), which will
155 // be dispatched afterwards.
156 bool mIsSuppressedOrDelayed
: 1;
157 // Certain mouse events can be marked as positionless to return 0 from
158 // coordinate related getters.
159 bool mIsPositionless
: 1;
161 // Flags managing state of propagation between processes.
162 // Note the the following flags shouldn't be referred directly. Use utility
165 // If mNoRemoteProcessDispatch is true, the event is not allowed to be sent
166 // to remote process.
167 bool mNoRemoteProcessDispatch
: 1;
168 // If mWantReplyFromContentProcess is true, the event will be redispatched
169 // in the parent process after the content process has handled it. Useful
170 // for when the parent process need the know first how the event was used
171 // by content before handling it itself.
172 bool mWantReplyFromContentProcess
: 1;
173 // If mPostedToRemoteProcess is true, the event has been posted to the
174 // remote process (but it's not handled yet if it's not a duplicated event
176 bool mPostedToRemoteProcess
: 1;
178 // If the event is being handled in target phase, returns true.
179 inline bool InTargetPhase() const {
180 return (mInBubblingPhase
&& mInCapturePhase
);
184 * Helper methods for methods of DOM Event.
186 inline void StopPropagation() { mPropagationStopped
= true; }
187 inline void StopImmediatePropagation() {
189 mImmediatePropagationStopped
= true;
191 inline void PreventDefault(bool aCalledByDefaultHandler
= true) {
195 mDefaultPrevented
= true;
196 // Note that even if preventDefault() has already been called by chrome,
197 // a call of preventDefault() by content needs to overwrite
198 // mDefaultPreventedByContent to true because in such case, defaultPrevented
199 // must be true when web apps check it after they call preventDefault().
200 if (aCalledByDefaultHandler
) {
201 StopCrossProcessForwarding();
202 mDefaultPreventedByChrome
= true;
204 mDefaultPreventedByContent
= true;
207 // This should be used only before dispatching events into the DOM tree.
208 inline void PreventDefaultBeforeDispatch(
209 CrossProcessForwarding aCrossProcessForwarding
) {
213 mDefaultPrevented
= true;
214 if (aCrossProcessForwarding
== CrossProcessForwarding::eStop
) {
215 StopCrossProcessForwarding();
218 inline bool DefaultPrevented() const { return mDefaultPrevented
; }
219 inline bool DefaultPreventedByContent() const {
220 MOZ_ASSERT(!mDefaultPreventedByContent
|| DefaultPrevented());
221 return mDefaultPreventedByContent
;
223 inline bool IsTrusted() const { return mIsTrusted
; }
224 inline bool PropagationStopped() const { return mPropagationStopped
; }
226 // Helper methods to access flags managing state of propagation between
230 * Prevent to be dispatched to remote process.
232 inline void StopCrossProcessForwarding() {
233 MOZ_ASSERT(!mPostedToRemoteProcess
);
234 mNoRemoteProcessDispatch
= true;
235 mWantReplyFromContentProcess
= false;
238 * Return true if the event shouldn't be dispatched to remote process.
240 inline bool IsCrossProcessForwardingStopped() const {
241 return mNoRemoteProcessDispatch
;
244 * Mark the event as waiting reply from remote process.
245 * If the caller needs to win other keyboard event handlers in chrome,
246 * the caller should call StopPropagation() too.
247 * Otherwise, if the caller just needs to know if the event is consumed by
248 * either content or chrome, it should just call this because the event
249 * may be reserved by chrome and it needs to be dispatched into the DOM
250 * tree in chrome for checking if it's reserved before being sent to any
253 inline void MarkAsWaitingReplyFromRemoteProcess() {
254 MOZ_ASSERT(!mPostedToRemoteProcess
);
255 mNoRemoteProcessDispatch
= false;
256 mWantReplyFromContentProcess
= true;
259 * Reset "waiting reply from remote process" state. This is useful when
260 * you dispatch a copy of an event coming from different process.
262 inline void ResetWaitingReplyFromRemoteProcessState() {
263 if (IsWaitingReplyFromRemoteProcess()) {
264 // FYI: mWantReplyFromContentProcess is also used for indicating
265 // "handled in remote process" state. Therefore, only when
266 // IsWaitingReplyFromRemoteProcess() returns true, this should
268 mWantReplyFromContentProcess
= false;
272 * Return true if the event handler should wait reply event. I.e., if this
273 * returns true, any event handler should do nothing with the event.
275 inline bool IsWaitingReplyFromRemoteProcess() const {
276 return !mNoRemoteProcessDispatch
&& mWantReplyFromContentProcess
;
279 * Mark the event as already handled in the remote process. This should be
280 * called when initializing reply events.
282 inline void MarkAsHandledInRemoteProcess() {
283 mNoRemoteProcessDispatch
= true;
284 mWantReplyFromContentProcess
= true;
285 mPostedToRemoteProcess
= false;
288 * Return true if the event has already been handled in the remote process.
290 inline bool IsHandledInRemoteProcess() const {
291 return mNoRemoteProcessDispatch
&& mWantReplyFromContentProcess
;
294 * Return true if the event should be sent back to its parent process.
296 inline bool WantReplyFromContentProcess() const {
297 MOZ_ASSERT(!XRE_IsParentProcess());
298 return IsWaitingReplyFromRemoteProcess();
301 * Mark the event has already posted to a remote process.
303 inline void MarkAsPostedToRemoteProcess() {
304 MOZ_ASSERT(!IsCrossProcessForwardingStopped());
305 mPostedToRemoteProcess
= true;
308 * Reset the cross process dispatching state. This should be used when a
309 * process receives the event because the state is in the sender.
311 inline void ResetCrossProcessDispatchingState() {
312 MOZ_ASSERT(!IsCrossProcessForwardingStopped());
313 mPostedToRemoteProcess
= false;
314 // Ignore propagation state in the different process if it's marked as
315 // "waiting reply from remote process" because the process needs to
316 // stop propagation in the process until receiving a reply event.
317 if (IsWaitingReplyFromRemoteProcess()) {
318 mPropagationStopped
= mImmediatePropagationStopped
= false;
322 * Return true if the event has been posted to a remote process.
323 * Note that MarkAsPostedToRemoteProcess() is called by
324 * ParamTraits<mozilla::WidgetEvent>. Therefore, it *might* be possible
325 * that posting the event failed even if this returns true. But that must
326 * really rare. If that'd be problem for you, you should unmark this in
327 * TabParent or somewhere.
329 inline bool HasBeenPostedToRemoteProcess() const {
330 return mPostedToRemoteProcess
;
333 * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
334 * content because it shouldn't be cancelable.
336 inline void MarkAsReservedByChrome() {
337 MOZ_ASSERT(!mPostedToRemoteProcess
);
338 mIsReservedByChrome
= true;
339 // For reserved commands (such as Open New Tab), we don't need to wait for
340 // the content to answer, neither to give a chance for content to override
342 StopCrossProcessForwarding();
343 // If the event is reserved by chrome, we shouldn't expose the event to
344 // web contents because such events shouldn't be cancelable. So, it's not
345 // good behavior to fire such events but to ignore the defaultPrevented
346 // attribute value in chrome.
347 mOnlySystemGroupDispatchInContent
= true;
350 * Return true if the event is reserved by chrome.
352 inline bool IsReservedByChrome() const {
353 MOZ_ASSERT(!mIsReservedByChrome
|| (IsCrossProcessForwardingStopped() &&
354 mOnlySystemGroupDispatchInContent
));
355 return mIsReservedByChrome
;
358 inline void Clear() { SetRawFlags(0); }
359 // Get if either the instance's bit or the aOther's bit is true, the
360 // instance's bit becomes true. In other words, this works like:
361 // eventFlags |= aOther;
362 inline void Union(const BaseEventFlags
& aOther
) {
363 RawFlags rawFlags
= GetRawFlags() | aOther
.GetRawFlags();
364 SetRawFlags(rawFlags
);
368 typedef uint32_t RawFlags
;
370 inline void SetRawFlags(RawFlags aRawFlags
) {
371 static_assert(sizeof(BaseEventFlags
) <= sizeof(RawFlags
),
372 "mozilla::EventFlags must not be bigger than the RawFlags");
373 memcpy(this, &aRawFlags
, sizeof(BaseEventFlags
));
375 inline RawFlags
GetRawFlags() const {
377 memcpy(&result
, this, sizeof(BaseEventFlags
));
382 /******************************************************************************
383 * mozilla::EventFlags
384 ******************************************************************************/
386 struct EventFlags
: public BaseEventFlags
{
387 EventFlags() { Clear(); }
390 /******************************************************************************
391 * mozilla::WidgetEventTime
392 ******************************************************************************/
394 class WidgetEventTime
{
396 // Elapsed time, in milliseconds, from a platform-specific zero time
397 // to the time the message was created
399 // Timestamp when the message was created. Set in parallel to 'time' until we
400 // determine if it is safe to drop 'time' (see bug 77992).
401 TimeStamp mTimeStamp
;
403 WidgetEventTime() : mTime(0), mTimeStamp(TimeStamp::Now()) {}
405 WidgetEventTime(uint64_t aTime
, TimeStamp aTimeStamp
)
406 : mTime(aTime
), mTimeStamp(aTimeStamp
) {}
408 void AssignEventTime(const WidgetEventTime
& aOther
) {
409 mTime
= aOther
.mTime
;
410 mTimeStamp
= aOther
.mTimeStamp
;
414 /******************************************************************************
415 * mozilla::WidgetEvent
416 ******************************************************************************/
418 class WidgetEvent
: public WidgetEventTime
{
420 void SetDefaultCancelableAndBubbles() {
422 case eEditorInputEventClass
:
423 mFlags
.mCancelable
= false;
424 mFlags
.mBubbles
= mFlags
.mIsTrusted
;
426 case eMouseEventClass
:
428 (mMessage
!= eMouseEnter
&& mMessage
!= eMouseLeave
);
429 mFlags
.mBubbles
= (mMessage
!= eMouseEnter
&& mMessage
!= eMouseLeave
);
431 case ePointerEventClass
:
433 (mMessage
!= ePointerEnter
&& mMessage
!= ePointerLeave
&&
434 mMessage
!= ePointerCancel
&& mMessage
!= ePointerGotCapture
&&
435 mMessage
!= ePointerLostCapture
);
437 (mMessage
!= ePointerEnter
&& mMessage
!= ePointerLeave
);
439 case eDragEventClass
:
440 mFlags
.mCancelable
= (mMessage
!= eDragExit
&& mMessage
!= eDragLeave
&&
441 mMessage
!= eDragEnd
);
442 mFlags
.mBubbles
= true;
444 case eSMILTimeEventClass
:
445 mFlags
.mCancelable
= false;
446 mFlags
.mBubbles
= false;
448 case eTransitionEventClass
:
449 case eAnimationEventClass
:
450 mFlags
.mCancelable
= false;
451 mFlags
.mBubbles
= true;
453 case eCompositionEventClass
:
454 // XXX compositionstart is cancelable in draft of DOM3 Events.
455 // However, it doesn't make sense for us, we cannot cancel
456 // composition when we send compositionstart event.
457 mFlags
.mCancelable
= false;
458 mFlags
.mBubbles
= true;
461 if (mMessage
== eResize
|| mMessage
== eMozVisualResize
||
462 mMessage
== eMozVisualScroll
|| mMessage
== eEditorInput
) {
463 mFlags
.mCancelable
= false;
465 mFlags
.mCancelable
= true;
467 mFlags
.mBubbles
= true;
473 WidgetEvent(bool aIsTrusted
, EventMessage aMessage
,
474 EventClassID aEventClassID
)
476 mClass(aEventClassID
),
480 mFocusSequenceNumber(0),
481 mSpecifiedEventType(nullptr),
483 mLayersId(layers::LayersId
{0}) {
484 MOZ_COUNT_CTOR(WidgetEvent
);
486 mFlags
.mIsTrusted
= aIsTrusted
;
487 SetDefaultCancelableAndBubbles();
488 SetDefaultComposed();
489 SetDefaultComposedInNativeAnonymousContent();
492 WidgetEvent() : WidgetEventTime(), mPath(nullptr) {
493 MOZ_COUNT_CTOR(WidgetEvent
);
497 WidgetEvent(bool aIsTrusted
, EventMessage aMessage
)
498 : WidgetEvent(aIsTrusted
, aMessage
, eBasicEventClass
) {}
500 virtual ~WidgetEvent() { MOZ_COUNT_DTOR(WidgetEvent
); }
502 WidgetEvent(const WidgetEvent
& aOther
) : WidgetEventTime() {
503 MOZ_COUNT_CTOR(WidgetEvent
);
506 WidgetEvent
& operator=(const WidgetEvent
& aOther
) = default;
508 WidgetEvent(WidgetEvent
&& aOther
)
509 : WidgetEventTime(std::move(aOther
)),
510 mClass(aOther
.mClass
),
511 mMessage(aOther
.mMessage
),
512 mRefPoint(std::move(aOther
.mRefPoint
)),
513 mLastRefPoint(std::move(aOther
.mLastRefPoint
)),
514 mFocusSequenceNumber(aOther
.mFocusSequenceNumber
),
515 mFlags(std::move(aOther
.mFlags
)),
516 mSpecifiedEventType(std::move(aOther
.mSpecifiedEventType
)),
517 mSpecifiedEventTypeString(std::move(aOther
.mSpecifiedEventTypeString
)),
518 mTarget(std::move(aOther
.mTarget
)),
519 mCurrentTarget(std::move(aOther
.mCurrentTarget
)),
520 mOriginalTarget(std::move(aOther
.mOriginalTarget
)),
521 mRelatedTarget(std::move(aOther
.mRelatedTarget
)),
522 mOriginalRelatedTarget(std::move(aOther
.mOriginalRelatedTarget
)),
523 mPath(std::move(aOther
.mPath
)) {
524 MOZ_COUNT_CTOR(WidgetEvent
);
526 WidgetEvent
& operator=(WidgetEvent
&& aOther
) = default;
528 virtual WidgetEvent
* Duplicate() const {
529 MOZ_ASSERT(mClass
== eBasicEventClass
,
530 "Duplicate() must be overridden by sub class");
531 WidgetEvent
* result
= new WidgetEvent(false, mMessage
);
532 result
->AssignEventData(*this, true);
533 result
->mFlags
= mFlags
;
538 EventMessage mMessage
;
539 // Relative to the widget of the event, or if there is no widget then it is
540 // in screen coordinates. Not modified by layout code.
541 LayoutDeviceIntPoint mRefPoint
;
542 // The previous mRefPoint, if known, used to calculate mouse movement deltas.
543 LayoutDeviceIntPoint mLastRefPoint
;
544 // The sequence number of the last potentially focus changing event handled
545 // by APZ. This is used to track when that event has been processed by
546 // content, and focus can be reconfirmed for async keyboard scrolling.
547 uint64_t mFocusSequenceNumber
;
548 // See BaseEventFlags definition for the detail.
549 BaseEventFlags mFlags
;
551 // If JS creates an event with unknown event type or known event type but
552 // for different event interface, the event type is stored to this.
553 // NOTE: This is always used if the instance is a WidgetCommandEvent instance
554 // or "input" event is dispatched with dom::Event class.
555 RefPtr
<nsAtom
> mSpecifiedEventType
;
557 // nsAtom isn't available on non-main thread due to unsafe. Therefore,
558 // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if
559 // the event is created in non-main thread.
560 nsString mSpecifiedEventTypeString
;
562 // Event targets, needed by DOM Events
563 // Note that when you need event target for DOM event, you should use
564 // Get*DOMEventTarget() instead of accessing these members directly.
565 nsCOMPtr
<dom::EventTarget
> mTarget
;
566 nsCOMPtr
<dom::EventTarget
> mCurrentTarget
;
567 nsCOMPtr
<dom::EventTarget
> mOriginalTarget
;
569 /// The possible related target
570 nsCOMPtr
<dom::EventTarget
> mRelatedTarget
;
571 nsCOMPtr
<dom::EventTarget
> mOriginalRelatedTarget
;
573 nsTArray
<EventTargetChainItem
>* mPath
;
575 // The LayersId of the content process that this event should be
576 // dispatched to. This field is only used in the chrome process
577 // and doesn't get remoted to child processes.
578 layers::LayersId mLayersId
;
580 dom::EventTarget
* GetDOMEventTarget() const;
581 dom::EventTarget
* GetCurrentDOMEventTarget() const;
582 dom::EventTarget
* GetOriginalDOMEventTarget() const;
584 void AssignEventData(const WidgetEvent
& aEvent
, bool aCopyTargets
) {
585 // mClass should be initialized with the constructor.
586 // mMessage should be initialized with the constructor.
587 mRefPoint
= aEvent
.mRefPoint
;
588 // mLastRefPoint doesn't need to be copied.
589 mFocusSequenceNumber
= aEvent
.mFocusSequenceNumber
;
590 // mLayersId intentionally not copied, since it's not used within content
591 AssignEventTime(aEvent
);
592 // mFlags should be copied manually if it's necessary.
593 mSpecifiedEventType
= aEvent
.mSpecifiedEventType
;
594 // mSpecifiedEventTypeString should be copied manually if it's necessary.
595 mTarget
= aCopyTargets
? aEvent
.mTarget
: nullptr;
596 mCurrentTarget
= aCopyTargets
? aEvent
.mCurrentTarget
: nullptr;
597 mOriginalTarget
= aCopyTargets
? aEvent
.mOriginalTarget
: nullptr;
598 mRelatedTarget
= aCopyTargets
? aEvent
.mRelatedTarget
: nullptr;
599 mOriginalRelatedTarget
=
600 aCopyTargets
? aEvent
.mOriginalRelatedTarget
: nullptr;
604 * Helper methods for methods of DOM Event.
606 void StopPropagation() { mFlags
.StopPropagation(); }
607 void StopImmediatePropagation() { mFlags
.StopImmediatePropagation(); }
608 void PreventDefault(bool aCalledByDefaultHandler
= true,
609 nsIPrincipal
* aPrincipal
= nullptr);
611 void PreventDefaultBeforeDispatch(
612 CrossProcessForwarding aCrossProcessForwarding
) {
613 mFlags
.PreventDefaultBeforeDispatch(aCrossProcessForwarding
);
615 bool DefaultPrevented() const { return mFlags
.DefaultPrevented(); }
616 bool DefaultPreventedByContent() const {
617 return mFlags
.DefaultPreventedByContent();
619 bool IsTrusted() const { return mFlags
.IsTrusted(); }
620 bool PropagationStopped() const { return mFlags
.PropagationStopped(); }
623 * Prevent to be dispatched to remote process.
625 inline void StopCrossProcessForwarding() {
626 mFlags
.StopCrossProcessForwarding();
629 * Return true if the event shouldn't be dispatched to remote process.
631 inline bool IsCrossProcessForwardingStopped() const {
632 return mFlags
.IsCrossProcessForwardingStopped();
635 * Mark the event as waiting reply from remote process.
636 * Note that this also stops immediate propagation in current process.
638 inline void MarkAsWaitingReplyFromRemoteProcess() {
639 mFlags
.MarkAsWaitingReplyFromRemoteProcess();
642 * Reset "waiting reply from remote process" state. This is useful when
643 * you dispatch a copy of an event coming from different process.
645 inline void ResetWaitingReplyFromRemoteProcessState() {
646 mFlags
.ResetWaitingReplyFromRemoteProcessState();
649 * Return true if the event handler should wait reply event. I.e., if this
650 * returns true, any event handler should do nothing with the event.
652 inline bool IsWaitingReplyFromRemoteProcess() const {
653 return mFlags
.IsWaitingReplyFromRemoteProcess();
656 * Mark the event as already handled in the remote process. This should be
657 * called when initializing reply events.
659 inline void MarkAsHandledInRemoteProcess() {
660 mFlags
.MarkAsHandledInRemoteProcess();
663 * Return true if the event has already been handled in the remote process.
664 * I.e., if this returns true, the event is a reply event.
666 inline bool IsHandledInRemoteProcess() const {
667 return mFlags
.IsHandledInRemoteProcess();
670 * Return true if the event should be sent back to its parent process.
671 * So, usual event handlers shouldn't call this.
673 inline bool WantReplyFromContentProcess() const {
674 return mFlags
.WantReplyFromContentProcess();
677 * Mark the event has already posted to a remote process.
679 inline void MarkAsPostedToRemoteProcess() {
680 mFlags
.MarkAsPostedToRemoteProcess();
683 * Reset the cross process dispatching state. This should be used when a
684 * process receives the event because the state is in the sender.
686 inline void ResetCrossProcessDispatchingState() {
687 mFlags
.ResetCrossProcessDispatchingState();
690 * Return true if the event has been posted to a remote process.
692 inline bool HasBeenPostedToRemoteProcess() const {
693 return mFlags
.HasBeenPostedToRemoteProcess();
696 * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
697 * content because it shouldn't be cancelable.
699 inline void MarkAsReservedByChrome() { mFlags
.MarkAsReservedByChrome(); }
701 * Return true if the event is reserved by chrome.
703 inline bool IsReservedByChrome() const { return mFlags
.IsReservedByChrome(); }
706 * Utils for checking event types
710 * As*Event() returns the pointer of the instance only when the instance is
711 * the class or one of its derived class.
713 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
714 #define NS_EVENT_CLASS(aPrefix, aName) \
715 virtual aPrefix##aName* As##aName(); \
716 const aPrefix##aName* As##aName() const;
718 #include "mozilla/EventClassList.h"
720 #undef NS_EVENT_CLASS
721 #undef NS_ROOT_EVENT_CLASS
724 * Returns true if the event is a query content event.
726 bool IsQueryContentEvent() const;
728 * Returns true if the event is a selection event.
730 bool IsSelectionEvent() const;
732 * Returns true if the event is a content command event.
734 bool IsContentCommandEvent() const;
736 * Returns true if the event is a native event deliverer event for plugin.
738 bool IsNativeEventDelivererForPlugin() const;
741 * Returns true if the event mMessage is one of mouse events.
743 bool HasMouseEventMessage() const;
745 * Returns true if the event mMessage is one of drag events.
747 bool HasDragEventMessage() const;
749 * Returns true if aMessage or mMessage is one of key events.
751 static bool IsKeyEventMessage(EventMessage aMessage
);
752 bool HasKeyEventMessage() const { return IsKeyEventMessage(mMessage
); }
754 * Returns true if the event mMessage is one of composition events or text
757 bool HasIMEEventMessage() const;
759 * Returns true if the event mMessage is one of plugin activation events.
761 bool HasPluginActivationEventMessage() const;
764 * Returns true if the event can be sent to remote process.
766 bool CanBeSentToRemoteProcess() const;
768 * Returns true if the original target is a remote process and the event
769 * will be posted to the remote process later.
771 bool WillBeSentToRemoteProcess() const;
773 * Returns true if the event is native event deliverer event for plugin and
774 * it should be retarted to focused document.
776 bool IsRetargetedNativeEventDelivererForPlugin() const;
778 * Returns true if the event is native event deliverer event for plugin and
779 * it should NOT be retarted to focused document.
781 bool IsNonRetargetedNativeEventDelivererForPlugin() const;
783 * Returns true if the event is related to IME handling. It includes
784 * IME events, query content events and selection events.
785 * Be careful when you use this.
787 bool IsIMERelatedEvent() const;
790 * Whether the event should be handled by the frame of the mouse cursor
791 * position or not. When it should be handled there (e.g., the mouse events),
794 bool IsUsingCoordinates() const;
796 * Whether the event should be handled by the focused DOM window in the
797 * same top level window's or not. E.g., key events, IME related events
798 * (including the query content events, they are used in IME transaction)
799 * should be handled by the (last) focused window rather than the dispatched
802 * NOTE: Even if this returns true, the event isn't going to be handled by the
803 * application level active DOM window which is on another top level window.
804 * So, when the event is fired on a deactive window, the event is going to be
805 * handled by the last focused DOM window in the last focused window.
807 bool IsTargetedAtFocusedWindow() const;
809 * Whether the event should be handled by the focused content or not. E.g.,
810 * key events, IME related events and other input events which are not handled
811 * by the frame of the mouse cursor position.
813 * NOTE: Even if this returns true, the event isn't going to be handled by the
814 * application level active DOM window which is on another top level window.
815 * So, when the event is fired on a deactive window, the event is going to be
816 * handled by the last focused DOM element of the last focused DOM window in
817 * the last focused window.
819 bool IsTargetedAtFocusedContent() const;
821 * Whether the event should cause a DOM event.
823 bool IsAllowedToDispatchDOMEvent() const;
825 * Whether the event should be dispatched in system group.
827 bool IsAllowedToDispatchInSystemGroup() const;
829 * Whether the event should be blocked for fingerprinting resistance.
831 bool IsBlockedForFingerprintingResistance() const;
833 * Initialize mComposed
835 void SetDefaultComposed() {
837 case eCompositionEventClass
:
838 mFlags
.mComposed
= mMessage
== eCompositionStart
||
839 mMessage
== eCompositionUpdate
||
840 mMessage
== eCompositionEnd
;
842 case eDragEventClass
:
843 // All drag & drop events are composed
844 mFlags
.mComposed
= mMessage
== eDrag
|| mMessage
== eDragEnd
||
845 mMessage
== eDragEnter
|| mMessage
== eDragExit
||
846 mMessage
== eDragLeave
|| mMessage
== eDragOver
||
847 mMessage
== eDragStart
|| mMessage
== eDrop
;
849 case eEditorInputEventClass
:
850 mFlags
.mComposed
= mMessage
== eEditorInput
;
852 case eFocusEventClass
:
853 mFlags
.mComposed
= mMessage
== eBlur
|| mMessage
== eFocus
||
854 mMessage
== eFocusOut
|| mMessage
== eFocusIn
;
856 case eKeyboardEventClass
:
858 mMessage
== eKeyDown
|| mMessage
== eKeyUp
|| mMessage
== eKeyPress
;
860 case eMouseEventClass
:
861 mFlags
.mComposed
= mMessage
== eMouseClick
||
862 mMessage
== eMouseDoubleClick
||
863 mMessage
== eMouseAuxClick
||
864 mMessage
== eMouseDown
|| mMessage
== eMouseUp
||
865 mMessage
== eMouseOver
|| mMessage
== eMouseOut
||
866 mMessage
== eMouseMove
|| mMessage
== eContextMenu
;
868 case ePointerEventClass
:
869 // All pointer events are composed
871 mMessage
== ePointerDown
|| mMessage
== ePointerMove
||
872 mMessage
== ePointerUp
|| mMessage
== ePointerCancel
||
873 mMessage
== ePointerOver
|| mMessage
== ePointerOut
||
874 mMessage
== ePointerGotCapture
|| mMessage
== ePointerLostCapture
;
876 case eTouchEventClass
:
877 // All touch events are composed
878 mFlags
.mComposed
= mMessage
== eTouchStart
|| mMessage
== eTouchEnd
||
879 mMessage
== eTouchMove
|| mMessage
== eTouchCancel
;
882 mFlags
.mComposed
= mMessage
== eLegacyDOMFocusIn
||
883 mMessage
== eLegacyDOMFocusOut
||
884 mMessage
== eLegacyDOMActivate
;
886 case eWheelEventClass
:
887 // All wheel events are composed
888 mFlags
.mComposed
= mMessage
== eWheel
;
891 mFlags
.mComposed
= false;
896 void SetComposed(const nsAString
& aEventTypeArg
) {
897 mFlags
.mComposed
= // composition events
898 aEventTypeArg
.EqualsLiteral("compositionstart") ||
899 aEventTypeArg
.EqualsLiteral("compositionupdate") ||
900 aEventTypeArg
.EqualsLiteral("compositionend") ||
901 // drag and drop events
902 aEventTypeArg
.EqualsLiteral("dragstart") ||
903 aEventTypeArg
.EqualsLiteral("drag") ||
904 aEventTypeArg
.EqualsLiteral("dragenter") ||
905 aEventTypeArg
.EqualsLiteral("dragexit") ||
906 aEventTypeArg
.EqualsLiteral("dragleave") ||
907 aEventTypeArg
.EqualsLiteral("dragover") ||
908 aEventTypeArg
.EqualsLiteral("drop") ||
909 aEventTypeArg
.EqualsLiteral("dropend") ||
910 // editor input events
911 aEventTypeArg
.EqualsLiteral("input") ||
912 aEventTypeArg
.EqualsLiteral("beforeinput") ||
914 aEventTypeArg
.EqualsLiteral("blur") ||
915 aEventTypeArg
.EqualsLiteral("focus") ||
916 aEventTypeArg
.EqualsLiteral("focusin") ||
917 aEventTypeArg
.EqualsLiteral("focusout") ||
919 aEventTypeArg
.EqualsLiteral("keydown") ||
920 aEventTypeArg
.EqualsLiteral("keyup") ||
921 aEventTypeArg
.EqualsLiteral("keypress") ||
923 aEventTypeArg
.EqualsLiteral("click") ||
924 aEventTypeArg
.EqualsLiteral("dblclick") ||
925 aEventTypeArg
.EqualsLiteral("mousedown") ||
926 aEventTypeArg
.EqualsLiteral("mouseup") ||
927 aEventTypeArg
.EqualsLiteral("mouseenter") ||
928 aEventTypeArg
.EqualsLiteral("mouseleave") ||
929 aEventTypeArg
.EqualsLiteral("mouseover") ||
930 aEventTypeArg
.EqualsLiteral("mouseout") ||
931 aEventTypeArg
.EqualsLiteral("mousemove") ||
932 aEventTypeArg
.EqualsLiteral("contextmenu") ||
934 aEventTypeArg
.EqualsLiteral("pointerdown") ||
935 aEventTypeArg
.EqualsLiteral("pointermove") ||
936 aEventTypeArg
.EqualsLiteral("pointerup") ||
937 aEventTypeArg
.EqualsLiteral("pointercancel") ||
938 aEventTypeArg
.EqualsLiteral("pointerover") ||
939 aEventTypeArg
.EqualsLiteral("pointerout") ||
940 aEventTypeArg
.EqualsLiteral("pointerenter") ||
941 aEventTypeArg
.EqualsLiteral("pointerleave") ||
942 aEventTypeArg
.EqualsLiteral("gotpointercapture") ||
943 aEventTypeArg
.EqualsLiteral("lostpointercapture") ||
945 aEventTypeArg
.EqualsLiteral("touchstart") ||
946 aEventTypeArg
.EqualsLiteral("touchend") ||
947 aEventTypeArg
.EqualsLiteral("touchmove") ||
948 aEventTypeArg
.EqualsLiteral("touchcancel") ||
950 aEventTypeArg
.EqualsLiteral("DOMFocusIn") ||
951 aEventTypeArg
.EqualsLiteral("DOMFocusOut") ||
952 aEventTypeArg
.EqualsLiteral("DOMActivate") ||
954 aEventTypeArg
.EqualsLiteral("wheel");
957 void SetComposed(bool aComposed
) { mFlags
.mComposed
= aComposed
; }
959 void SetDefaultComposedInNativeAnonymousContent() {
960 // For compatibility concerns, we set mComposedInNativeAnonymousContent to
961 // false for those events we want to stop propagation.
963 // nsVideoFrame may create anonymous image element which fires eLoad,
964 // eLoadStart, eLoadEnd, eLoadError. We don't want these events cross
965 // the boundary of NAC
966 mFlags
.mComposedInNativeAnonymousContent
=
967 mMessage
!= eLoad
&& mMessage
!= eLoadStart
&& mMessage
!= eLoadEnd
&&
968 mMessage
!= eLoadError
;
971 bool IsUserAction() const;
974 /******************************************************************************
975 * mozilla::NativeEventData
977 * WidgetGUIEvent's mPluginEvent member used to be a void* pointer,
978 * used to reference external, OS-specific data structures.
980 * That void* pointer wasn't serializable by itself, causing
981 * certain plugin events not to function in e10s. See bug 586656.
983 * To make this serializable, we changed this void* pointer into
984 * a proper buffer, and copy these external data structures into this
987 * That buffer is NativeEventData::mBuffer below.
989 * We wrap this in that NativeEventData class providing operators to
990 * be compatible with existing code that was written around
991 * the old void* field.
992 ******************************************************************************/
994 class NativeEventData final
{
995 nsTArray
<uint8_t> mBuffer
;
997 friend struct IPC::ParamTraits
<mozilla::NativeEventData
>;
1000 explicit operator bool() const { return !mBuffer
.IsEmpty(); }
1002 template <typename T
>
1003 explicit operator const T
*() const {
1004 return mBuffer
.IsEmpty() ? nullptr
1005 : reinterpret_cast<const T
*>(mBuffer
.Elements());
1008 template <typename T
>
1009 void Copy(const T
& other
) {
1010 static_assert(!mozilla::IsPointer
<T
>::value
, "Don't want a pointer!");
1011 mBuffer
.SetLength(sizeof(T
));
1012 memcpy(mBuffer
.Elements(), &other
, mBuffer
.Length());
1015 void Clear() { mBuffer
.Clear(); }
1018 /******************************************************************************
1019 * mozilla::WidgetGUIEvent
1020 ******************************************************************************/
1022 class WidgetGUIEvent
: public WidgetEvent
{
1024 WidgetGUIEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
1025 EventClassID aEventClassID
)
1026 : WidgetEvent(aIsTrusted
, aMessage
, aEventClassID
), mWidget(aWidget
) {}
1031 virtual WidgetGUIEvent
* AsGUIEvent() override
{ return this; }
1033 WidgetGUIEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
)
1034 : WidgetEvent(aIsTrusted
, aMessage
, eGUIEventClass
), mWidget(aWidget
) {}
1036 virtual WidgetEvent
* Duplicate() const override
{
1037 MOZ_ASSERT(mClass
== eGUIEventClass
,
1038 "Duplicate() must be overridden by sub class");
1039 // Not copying widget, it is a weak reference.
1040 WidgetGUIEvent
* result
= new WidgetGUIEvent(false, mMessage
, nullptr);
1041 result
->AssignGUIEventData(*this, true);
1042 result
->mFlags
= mFlags
;
1046 // Originator of the event
1047 nsCOMPtr
<nsIWidget
> mWidget
;
1050 * Ideally though, we wouldn't allow arbitrary reinterpret_cast'ing here;
1051 * instead, we would at least store type information here so that
1052 * this class can't be used to reinterpret one structure type into another.
1053 * We can also wonder if it would be possible to properly extend
1054 * WidgetGUIEvent and other Event classes to remove the need for this
1055 * mPluginEvent field.
1057 typedef NativeEventData PluginEvent
;
1059 // Event for NPAPI plugin
1060 PluginEvent mPluginEvent
;
1062 void AssignGUIEventData(const WidgetGUIEvent
& aEvent
, bool aCopyTargets
) {
1063 AssignEventData(aEvent
, aCopyTargets
);
1065 // widget should be initialized with the constructor.
1067 mPluginEvent
= aEvent
.mPluginEvent
;
1071 /******************************************************************************
1074 * All modifier keys should be defined here. This is used for managing
1075 * modifier states for DOM Level 3 or later.
1076 ******************************************************************************/
1079 MODIFIER_NONE
= 0x0000,
1080 MODIFIER_ALT
= 0x0001,
1081 MODIFIER_ALTGRAPH
= 0x0002,
1082 MODIFIER_CAPSLOCK
= 0x0004,
1083 MODIFIER_CONTROL
= 0x0008,
1084 MODIFIER_FN
= 0x0010,
1085 MODIFIER_FNLOCK
= 0x0020,
1086 MODIFIER_META
= 0x0040,
1087 MODIFIER_NUMLOCK
= 0x0080,
1088 MODIFIER_SCROLLLOCK
= 0x0100,
1089 MODIFIER_SHIFT
= 0x0200,
1090 MODIFIER_SYMBOL
= 0x0400,
1091 MODIFIER_SYMBOLLOCK
= 0x0800,
1092 MODIFIER_OS
= 0x1000
1095 /******************************************************************************
1096 * Modifier key names.
1097 ******************************************************************************/
1099 #define NS_DOM_KEYNAME_ALT "Alt"
1100 #define NS_DOM_KEYNAME_ALTGRAPH "AltGraph"
1101 #define NS_DOM_KEYNAME_CAPSLOCK "CapsLock"
1102 #define NS_DOM_KEYNAME_CONTROL "Control"
1103 #define NS_DOM_KEYNAME_FN "Fn"
1104 #define NS_DOM_KEYNAME_FNLOCK "FnLock"
1105 #define NS_DOM_KEYNAME_META "Meta"
1106 #define NS_DOM_KEYNAME_NUMLOCK "NumLock"
1107 #define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock"
1108 #define NS_DOM_KEYNAME_SHIFT "Shift"
1109 #define NS_DOM_KEYNAME_SYMBOL "Symbol"
1110 #define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock"
1111 #define NS_DOM_KEYNAME_OS "OS"
1113 /******************************************************************************
1114 * mozilla::Modifiers
1115 ******************************************************************************/
1117 typedef uint16_t Modifiers
;
1119 class MOZ_STACK_CLASS GetModifiersName final
: public nsAutoCString
{
1121 explicit GetModifiersName(Modifiers aModifiers
) {
1122 if (aModifiers
& MODIFIER_ALT
) {
1123 AssignLiteral(NS_DOM_KEYNAME_ALT
);
1125 if (aModifiers
& MODIFIER_ALTGRAPH
) {
1126 MaybeAppendSeparator();
1127 AppendLiteral(NS_DOM_KEYNAME_ALTGRAPH
);
1129 if (aModifiers
& MODIFIER_CAPSLOCK
) {
1130 MaybeAppendSeparator();
1131 AppendLiteral(NS_DOM_KEYNAME_CAPSLOCK
);
1133 if (aModifiers
& MODIFIER_CONTROL
) {
1134 MaybeAppendSeparator();
1135 AppendLiteral(NS_DOM_KEYNAME_CONTROL
);
1137 if (aModifiers
& MODIFIER_FN
) {
1138 MaybeAppendSeparator();
1139 AppendLiteral(NS_DOM_KEYNAME_FN
);
1141 if (aModifiers
& MODIFIER_FNLOCK
) {
1142 MaybeAppendSeparator();
1143 AppendLiteral(NS_DOM_KEYNAME_FNLOCK
);
1145 if (aModifiers
& MODIFIER_META
) {
1146 MaybeAppendSeparator();
1147 AppendLiteral(NS_DOM_KEYNAME_META
);
1149 if (aModifiers
& MODIFIER_NUMLOCK
) {
1150 MaybeAppendSeparator();
1151 AppendLiteral(NS_DOM_KEYNAME_NUMLOCK
);
1153 if (aModifiers
& MODIFIER_SCROLLLOCK
) {
1154 MaybeAppendSeparator();
1155 AppendLiteral(NS_DOM_KEYNAME_SCROLLLOCK
);
1157 if (aModifiers
& MODIFIER_SHIFT
) {
1158 MaybeAppendSeparator();
1159 AppendLiteral(NS_DOM_KEYNAME_SHIFT
);
1161 if (aModifiers
& MODIFIER_SYMBOL
) {
1162 MaybeAppendSeparator();
1163 AppendLiteral(NS_DOM_KEYNAME_SYMBOL
);
1165 if (aModifiers
& MODIFIER_SYMBOLLOCK
) {
1166 MaybeAppendSeparator();
1167 AppendLiteral(NS_DOM_KEYNAME_SYMBOLLOCK
);
1169 if (aModifiers
& MODIFIER_OS
) {
1170 MaybeAppendSeparator();
1171 AppendLiteral(NS_DOM_KEYNAME_OS
);
1174 AssignLiteral("none");
1179 void MaybeAppendSeparator() {
1181 AppendLiteral(" | ");
1186 /******************************************************************************
1187 * mozilla::WidgetInputEvent
1188 ******************************************************************************/
1190 class WidgetInputEvent
: public WidgetGUIEvent
{
1192 WidgetInputEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
1193 EventClassID aEventClassID
)
1194 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
),
1197 WidgetInputEvent() : mModifiers(0) {}
1200 virtual WidgetInputEvent
* AsInputEvent() override
{ return this; }
1202 WidgetInputEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
)
1203 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, eInputEventClass
),
1206 virtual WidgetEvent
* Duplicate() const override
{
1207 MOZ_ASSERT(mClass
== eInputEventClass
,
1208 "Duplicate() must be overridden by sub class");
1209 // Not copying widget, it is a weak reference.
1210 WidgetInputEvent
* result
= new WidgetInputEvent(false, mMessage
, nullptr);
1211 result
->AssignInputEventData(*this, true);
1212 result
->mFlags
= mFlags
;
1217 * Returns a modifier of "Accel" virtual modifier which is used for shortcut
1220 static Modifier
AccelModifier();
1223 * GetModifier() returns a modifier flag which is activated by aDOMKeyName.
1225 static Modifier
GetModifier(const nsAString
& aDOMKeyName
);
1227 // true indicates the accel key on the environment is down
1228 bool IsAccel() const { return ((mModifiers
& AccelModifier()) != 0); }
1230 // true indicates the shift key is down
1231 bool IsShift() const { return ((mModifiers
& MODIFIER_SHIFT
) != 0); }
1232 // true indicates the control key is down
1233 bool IsControl() const { return ((mModifiers
& MODIFIER_CONTROL
) != 0); }
1234 // true indicates the alt key is down
1235 bool IsAlt() const { return ((mModifiers
& MODIFIER_ALT
) != 0); }
1236 // true indicates the meta key is down (or, on Mac, the Command key)
1237 bool IsMeta() const { return ((mModifiers
& MODIFIER_META
) != 0); }
1238 // true indicates the win key is down on Windows. Or the Super or Hyper key
1239 // is down on Linux.
1240 bool IsOS() const { return ((mModifiers
& MODIFIER_OS
) != 0); }
1241 // true indicates the alt graph key is down
1242 // NOTE: on Mac, the option key press causes both IsAlt() and IsAltGrpah()
1244 bool IsAltGraph() const { return ((mModifiers
& MODIFIER_ALTGRAPH
) != 0); }
1245 // true indicates the CapLock LED is turn on.
1246 bool IsCapsLocked() const { return ((mModifiers
& MODIFIER_CAPSLOCK
) != 0); }
1247 // true indicates the NumLock LED is turn on.
1248 bool IsNumLocked() const { return ((mModifiers
& MODIFIER_NUMLOCK
) != 0); }
1249 // true indicates the ScrollLock LED is turn on.
1250 bool IsScrollLocked() const {
1251 return ((mModifiers
& MODIFIER_SCROLLLOCK
) != 0);
1254 // true indicates the Fn key is down, but this is not supported by native
1255 // key event on any platform.
1256 bool IsFn() const { return ((mModifiers
& MODIFIER_FN
) != 0); }
1257 // true indicates the FnLock LED is turn on, but we don't know such
1258 // keyboards nor platforms.
1259 bool IsFnLocked() const { return ((mModifiers
& MODIFIER_FNLOCK
) != 0); }
1260 // true indicates the Symbol is down, but this is not supported by native
1261 // key event on any platforms.
1262 bool IsSymbol() const { return ((mModifiers
& MODIFIER_SYMBOL
) != 0); }
1263 // true indicates the SymbolLock LED is turn on, but we don't know such
1264 // keyboards nor platforms.
1265 bool IsSymbolLocked() const {
1266 return ((mModifiers
& MODIFIER_SYMBOLLOCK
) != 0);
1269 void InitBasicModifiers(bool aCtrlKey
, bool aAltKey
, bool aShiftKey
,
1273 mModifiers
|= MODIFIER_CONTROL
;
1276 mModifiers
|= MODIFIER_ALT
;
1279 mModifiers
|= MODIFIER_SHIFT
;
1282 mModifiers
|= MODIFIER_META
;
1286 Modifiers mModifiers
;
1288 void AssignInputEventData(const WidgetInputEvent
& aEvent
, bool aCopyTargets
) {
1289 AssignGUIEventData(aEvent
, aCopyTargets
);
1291 mModifiers
= aEvent
.mModifiers
;
1295 /******************************************************************************
1296 * mozilla::InternalUIEvent
1298 * XXX Why this inherits WidgetGUIEvent rather than WidgetEvent?
1299 ******************************************************************************/
1301 class InternalUIEvent
: public WidgetGUIEvent
{
1303 InternalUIEvent() : mDetail(0), mCausedByUntrustedEvent(false) {}
1305 InternalUIEvent(bool aIsTrusted
, EventMessage aMessage
, nsIWidget
* aWidget
,
1306 EventClassID aEventClassID
)
1307 : WidgetGUIEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
),
1309 mCausedByUntrustedEvent(false) {}
1311 InternalUIEvent(bool aIsTrusted
, EventMessage aMessage
,
1312 EventClassID aEventClassID
)
1313 : WidgetGUIEvent(aIsTrusted
, aMessage
, nullptr, aEventClassID
),
1315 mCausedByUntrustedEvent(false) {}
1318 virtual InternalUIEvent
* AsUIEvent() override
{ return this; }
1321 * If the UIEvent is caused by another event (e.g., click event),
1322 * aEventCausesThisEvent should be the event. If there is no such event,
1323 * this should be nullptr.
1325 InternalUIEvent(bool aIsTrusted
, EventMessage aMessage
,
1326 const WidgetEvent
* aEventCausesThisEvent
)
1327 : WidgetGUIEvent(aIsTrusted
, aMessage
, nullptr, eUIEventClass
),
1329 mCausedByUntrustedEvent(aEventCausesThisEvent
&&
1330 !aEventCausesThisEvent
->IsTrusted()) {}
1332 virtual WidgetEvent
* Duplicate() const override
{
1333 MOZ_ASSERT(mClass
== eUIEventClass
,
1334 "Duplicate() must be overridden by sub class");
1335 InternalUIEvent
* result
= new InternalUIEvent(false, mMessage
, nullptr);
1336 result
->AssignUIEventData(*this, true);
1337 result
->mFlags
= mFlags
;
1342 // mCausedByUntrustedEvent is true if the event is caused by untrusted event.
1343 bool mCausedByUntrustedEvent
;
1345 // If you check the event is a trusted event and NOT caused by an untrusted
1346 // event, IsTrustable() returns what you expected.
1347 bool IsTrustable() const { return IsTrusted() && !mCausedByUntrustedEvent
; }
1349 void AssignUIEventData(const InternalUIEvent
& aEvent
, bool aCopyTargets
) {
1350 AssignGUIEventData(aEvent
, aCopyTargets
);
1352 mDetail
= aEvent
.mDetail
;
1353 mCausedByUntrustedEvent
= aEvent
.mCausedByUntrustedEvent
;
1357 } // namespace mozilla
1359 #endif // mozilla_BasicEvents_h__