Bug 1859954 - Use XP_DARWIN rather than XP_MACOS in PHC r=glandium
[gecko.git] / widget / BasicEvents.h
blob04711fad54a5bcd774b884bcdac331ad61ed397a
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__
9 #include <stdint.h>
10 #include <type_traits>
12 #include "mozilla/EventForwards.h"
13 #include "mozilla/TimeStamp.h"
14 #include "mozilla/dom/EventTarget.h"
15 #include "mozilla/layers/LayersTypes.h"
16 #include "nsCOMPtr.h"
17 #include "nsAtom.h"
18 #include "nsISupportsImpl.h"
19 #include "nsIWidget.h"
20 #include "nsString.h"
21 #include "Units.h"
23 #ifdef DEBUG
24 # include "nsXULAppAPI.h"
25 #endif // #ifdef DEBUG
27 class nsIPrincipal;
29 namespace IPC {
30 template <typename T>
31 struct ParamTraits;
32 } // namespace IPC
34 namespace mozilla {
36 class EventTargetChainItem;
38 enum class CrossProcessForwarding {
39 // eStop prevents the event to be sent to remote process.
40 eStop,
41 // eAllow keeps current state of the event whether it's sent to remote
42 // process. In other words, eAllow does NOT mean that making the event
43 // sent to remote process when IsCrossProcessForwardingStopped() returns
44 // true.
45 eAllow,
48 /******************************************************************************
49 * mozilla::BaseEventFlags
51 * BaseEventFlags must be a POD struct for safe to use memcpy (including
52 * in ParamTraits<BaseEventFlags>). So don't make virtual methods, constructor,
53 * destructor and operators.
54 * This is necessary for VC which is NOT C++0x compiler.
55 ******************************************************************************/
57 struct BaseEventFlags {
58 public:
59 // If mIsTrusted is true, the event is a trusted event. Otherwise, it's
60 // an untrusted event.
61 bool mIsTrusted : 1;
62 // If mInBubblingPhase is true, the event is in bubbling phase or target
63 // phase.
64 bool mInBubblingPhase : 1;
65 // If mInCapturePhase is true, the event is in capture phase or target phase.
66 bool mInCapturePhase : 1;
67 // If mInTargetPhase is true, the event is in target phase.
68 bool mInTargetPhase : 1;
69 // If mInSystemGroup is true, the event is being dispatched in system group.
70 bool mInSystemGroup : 1;
71 // If mCancelable is true, the event can be consumed. I.e., calling
72 // dom::Event::PreventDefault() can prevent the default action.
73 bool mCancelable : 1;
74 // If mBubbles is true, the event can bubble. Otherwise, cannot be handled
75 // in bubbling phase.
76 bool mBubbles : 1;
77 // If mPropagationStopped is true, dom::Event::StopPropagation() or
78 // dom::Event::StopImmediatePropagation() has been called.
79 bool mPropagationStopped : 1;
80 // If mImmediatePropagationStopped is true,
81 // dom::Event::StopImmediatePropagation() has been called.
82 // Note that mPropagationStopped must be true when this is true.
83 bool mImmediatePropagationStopped : 1;
84 // If mDefaultPrevented is true, the event has been consumed.
85 // E.g., dom::Event::PreventDefault() has been called or
86 // the default action has been performed.
87 bool mDefaultPrevented : 1;
88 // If mDefaultPreventedByContent is true, the event has been
89 // consumed by content.
90 // Note that mDefaultPrevented must be true when this is true.
91 bool mDefaultPreventedByContent : 1;
92 // If mDefaultPreventedByChrome is true, the event has been
93 // consumed by chrome.
94 // Note that mDefaultPrevented must be true when this is true.
95 bool mDefaultPreventedByChrome : 1;
96 // mMultipleActionsPrevented may be used when default handling don't want to
97 // be prevented, but only one of the event targets should handle the event.
98 // For example, when a <label> element is in another <label> element and
99 // the first <label> element is clicked, that one may set this true.
100 // Then, the second <label> element won't handle the event.
101 bool mMultipleActionsPrevented : 1;
102 // Similar to above but expected to be used during PreHandleEvent phase.
103 bool mMultiplePreActionsPrevented : 1;
104 // If mIsBeingDispatched is true, the DOM event created from the event is
105 // dispatching into the DOM tree and not completed.
106 bool mIsBeingDispatched : 1;
107 // If mDispatchedAtLeastOnce is true, the event has been dispatched
108 // as a DOM event and the dispatch has been completed in the process.
109 // So, this is false even if the event has already been dispatched
110 // in another process.
111 bool mDispatchedAtLeastOnce : 1;
112 // If mIsSynthesizedForTests is true, the event has been synthesized for
113 // automated tests or something hacky approach of an add-on.
114 bool mIsSynthesizedForTests : 1;
115 // If mExceptionWasRaised is true, one of the event handlers has raised an
116 // exception.
117 bool mExceptionWasRaised : 1;
118 // If mRetargetToNonNativeAnonymous is true and the target is in a non-native
119 // native anonymous subtree, the event target is set to mOriginalTarget.
120 bool mRetargetToNonNativeAnonymous : 1;
121 // If mNoContentDispatch is true, the event is never dispatched to the
122 // event handlers which are added to the contents, onfoo attributes and
123 // properties. Note that this flag is ignored when
124 // EventChainPreVisitor::mForceContentDispatch is set true. For exapmle,
125 // window and document object sets it true. Therefore, web applications
126 // can handle the event if they add event listeners to the window or the
127 // document.
128 // XXX This is an ancient and broken feature, don't use this for new bug
129 // as far as possible.
130 bool mNoContentDispatch : 1;
131 // If mOnlyChromeDispatch is true, the event is dispatched to only chrome.
132 bool mOnlyChromeDispatch : 1;
133 // Indicates if the key combination is reserved by chrome. This is set by
134 // MarkAsReservedByChrome().
135 bool mIsReservedByChrome : 1;
136 // If mOnlySystemGroupDispatchInContent is true, event listeners added to
137 // the default group for non-chrome EventTarget won't be called.
138 // Be aware, if this is true, EventDispatcher needs to check if each event
139 // listener is added to chrome node, so, don't set this to true for the
140 // events which are fired a lot of times like eMouseMove.
141 bool mOnlySystemGroupDispatchInContent : 1;
142 // If mOnlySystemGroupDispatch is true, the event will be dispatched only to
143 // event listeners added in the system group.
144 bool mOnlySystemGroupDispatch : 1;
145 // The event's action will be handled by APZ. The main thread should not
146 // perform its associated action.
147 bool mHandledByAPZ : 1;
148 // True if the event is currently being handled by an event listener that
149 // was registered as a passive listener.
150 bool mInPassiveListener : 1;
151 // If mComposed is true, the event fired by nodes in shadow DOM can cross the
152 // boundary of shadow DOM and light DOM.
153 bool mComposed : 1;
154 // Similar to mComposed. Set it to true to allow events cross the boundary
155 // between native non-anonymous content and native anonymouse content
156 bool mComposedInNativeAnonymousContent : 1;
157 // Set to true for events which are suppressed or delayed so that later a
158 // DelayedEvent of it is dispatched. This is used when parent side process
159 // the key event after content side, and may drop the event if the event
160 // was suppressed or delayed in contents side.
161 // It is also set to true for the events (in a DelayedInputEvent), which will
162 // be dispatched afterwards.
163 bool mIsSuppressedOrDelayed : 1;
164 // Certain mouse events can be marked as positionless to return 0 from
165 // coordinate related getters.
166 bool mIsPositionless : 1;
168 // Flags managing state of propagation between processes.
169 // Note the the following flags shouldn't be referred directly. Use utility
170 // methods instead.
172 // If mNoRemoteProcessDispatch is true, the event is not allowed to be sent
173 // to remote process.
174 bool mNoRemoteProcessDispatch : 1;
175 // If mWantReplyFromContentProcess is true, the event will be redispatched
176 // in the parent process after the content process has handled it. Useful
177 // for when the parent process need the know first how the event was used
178 // by content before handling it itself.
179 bool mWantReplyFromContentProcess : 1;
180 // If mPostedToRemoteProcess is true, the event has been posted to the
181 // remote process (but it's not handled yet if it's not a duplicated event
182 // instance).
183 bool mPostedToRemoteProcess : 1;
184 // If mCameFromAnotherProcess is true, the event came from another process.
185 bool mCameFromAnotherProcess : 1;
188 * Helper methods for methods of DOM Event.
190 inline void StopPropagation() { mPropagationStopped = true; }
191 inline void StopImmediatePropagation() {
192 StopPropagation();
193 mImmediatePropagationStopped = true;
195 inline void PreventDefault(bool aCalledByDefaultHandler = true) {
196 if (!mCancelable) {
197 return;
199 mDefaultPrevented = true;
200 // Note that even if preventDefault() has already been called by chrome,
201 // a call of preventDefault() by content needs to overwrite
202 // mDefaultPreventedByContent to true because in such case, defaultPrevented
203 // must be true when web apps check it after they call preventDefault().
204 if (aCalledByDefaultHandler) {
205 StopCrossProcessForwarding();
206 mDefaultPreventedByChrome = true;
207 } else {
208 mDefaultPreventedByContent = true;
211 // This should be used only before dispatching events into the DOM tree.
212 inline void PreventDefaultBeforeDispatch(
213 CrossProcessForwarding aCrossProcessForwarding) {
214 if (!mCancelable) {
215 return;
217 mDefaultPrevented = true;
218 if (aCrossProcessForwarding == CrossProcessForwarding::eStop) {
219 StopCrossProcessForwarding();
222 inline bool DefaultPrevented() const { return mDefaultPrevented; }
223 inline bool DefaultPreventedByContent() const {
224 MOZ_ASSERT(!mDefaultPreventedByContent || DefaultPrevented());
225 return mDefaultPreventedByContent;
227 inline bool IsTrusted() const { return mIsTrusted; }
228 inline bool PropagationStopped() const { return mPropagationStopped; }
230 // Helper methods to access flags managing state of propagation between
231 // processes.
234 * Prevent to be dispatched to remote process.
236 inline void StopCrossProcessForwarding() {
237 MOZ_ASSERT(!mPostedToRemoteProcess);
238 mNoRemoteProcessDispatch = true;
239 mWantReplyFromContentProcess = false;
242 * Return true if the event shouldn't be dispatched to remote process.
244 inline bool IsCrossProcessForwardingStopped() const {
245 return mNoRemoteProcessDispatch;
248 * Mark the event as waiting reply from remote process.
249 * If the caller needs to win other keyboard event handlers in chrome,
250 * the caller should call StopPropagation() too.
251 * Otherwise, if the caller just needs to know if the event is consumed by
252 * either content or chrome, it should just call this because the event
253 * may be reserved by chrome and it needs to be dispatched into the DOM
254 * tree in chrome for checking if it's reserved before being sent to any
255 * remote processes.
257 inline void MarkAsWaitingReplyFromRemoteProcess() {
258 MOZ_ASSERT(!mPostedToRemoteProcess);
259 mNoRemoteProcessDispatch = false;
260 mWantReplyFromContentProcess = true;
263 * Reset "waiting reply from remote process" state. This is useful when
264 * you dispatch a copy of an event coming from different process.
266 inline void ResetWaitingReplyFromRemoteProcessState() {
267 if (IsWaitingReplyFromRemoteProcess()) {
268 // FYI: mWantReplyFromContentProcess is also used for indicating
269 // "handled in remote process" state. Therefore, only when
270 // IsWaitingReplyFromRemoteProcess() returns true, this should
271 // reset the flag.
272 mWantReplyFromContentProcess = false;
276 * Return true if the event handler should wait reply event. I.e., if this
277 * returns true, any event handler should do nothing with the event.
279 inline bool IsWaitingReplyFromRemoteProcess() const {
280 return !mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
283 * Mark the event as already handled in the remote process. This should be
284 * called when initializing reply events.
286 inline void MarkAsHandledInRemoteProcess() {
287 mNoRemoteProcessDispatch = true;
288 mWantReplyFromContentProcess = true;
289 mPostedToRemoteProcess = false;
292 * Return true if the event has already been handled in the remote process.
294 inline bool IsHandledInRemoteProcess() const {
295 return mNoRemoteProcessDispatch && mWantReplyFromContentProcess;
298 * Return true if the event should be sent back to its parent process.
300 inline bool WantReplyFromContentProcess() const {
301 MOZ_ASSERT(!XRE_IsParentProcess());
302 return IsWaitingReplyFromRemoteProcess();
305 * Mark the event has already posted to a remote process.
307 inline void MarkAsPostedToRemoteProcess() {
308 MOZ_ASSERT(!IsCrossProcessForwardingStopped());
309 mPostedToRemoteProcess = true;
312 * Reset the cross process dispatching state. This should be used when a
313 * process receives the event because the state is in the sender.
315 inline void ResetCrossProcessDispatchingState() {
316 MOZ_ASSERT(!IsCrossProcessForwardingStopped());
317 mPostedToRemoteProcess = false;
318 // Ignore propagation state in the remote process if it's marked as
319 // "waiting reply from remote process" because the process needs to
320 // stop propagation in the process until receiving a reply event.
321 // Note that the propagation stopped flag is important for the reply event
322 // handler in the main process because it's used for making whether it's
323 // ignored by the remote process or not.
324 if (!XRE_IsParentProcess() && IsWaitingReplyFromRemoteProcess()) {
325 mPropagationStopped = mImmediatePropagationStopped = false;
327 // mDispatchedAtLeastOnce indicates the state in current process.
328 mDispatchedAtLeastOnce = false;
331 * Return true if the event has been posted to a remote process.
332 * Note that MarkAsPostedToRemoteProcess() is called by
333 * ParamTraits<mozilla::WidgetEvent>. Therefore, it *might* be possible
334 * that posting the event failed even if this returns true. But that must
335 * really rare. If that'd be problem for you, you should unmark this in
336 * BrowserParent or somewhere.
338 inline bool HasBeenPostedToRemoteProcess() const {
339 return mPostedToRemoteProcess;
342 * Return true if the event came from another process.
344 inline bool CameFromAnotherProcess() const { return mCameFromAnotherProcess; }
346 * Mark the event as coming from another process.
348 inline void MarkAsComingFromAnotherProcess() {
349 mCameFromAnotherProcess = true;
352 * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
353 * content because it shouldn't be cancelable.
355 inline void MarkAsReservedByChrome() {
356 MOZ_ASSERT(!mPostedToRemoteProcess);
357 mIsReservedByChrome = true;
358 // For reserved commands (such as Open New Tab), we don't need to wait for
359 // the content to answer, neither to give a chance for content to override
360 // its behavior.
361 StopCrossProcessForwarding();
362 // If the event is reserved by chrome, we shouldn't expose the event to
363 // web contents because such events shouldn't be cancelable. So, it's not
364 // good behavior to fire such events but to ignore the defaultPrevented
365 // attribute value in chrome.
366 mOnlySystemGroupDispatchInContent = true;
369 * Return true if the event is reserved by chrome.
371 inline bool IsReservedByChrome() const {
372 MOZ_ASSERT(!mIsReservedByChrome || (IsCrossProcessForwardingStopped() &&
373 mOnlySystemGroupDispatchInContent));
374 return mIsReservedByChrome;
377 inline void Clear() { SetRawFlags(0); }
378 // Get if either the instance's bit or the aOther's bit is true, the
379 // instance's bit becomes true. In other words, this works like:
380 // eventFlags |= aOther;
381 inline void Union(const BaseEventFlags& aOther) {
382 RawFlags rawFlags = GetRawFlags() | aOther.GetRawFlags();
383 SetRawFlags(rawFlags);
386 private:
387 typedef uint64_t RawFlags;
389 inline void SetRawFlags(RawFlags aRawFlags) {
390 static_assert(sizeof(BaseEventFlags) <= sizeof(RawFlags),
391 "mozilla::EventFlags must not be bigger than the RawFlags");
392 memcpy(this, &aRawFlags, sizeof(BaseEventFlags));
394 inline RawFlags GetRawFlags() const {
395 RawFlags result = 0;
396 memcpy(&result, this, sizeof(BaseEventFlags));
397 return result;
401 /******************************************************************************
402 * mozilla::EventFlags
403 ******************************************************************************/
405 struct EventFlags : public BaseEventFlags {
406 EventFlags() { Clear(); }
409 /******************************************************************************
410 * mozilla::WidgetEventTime
411 ******************************************************************************/
413 class WidgetEventTime {
414 public:
415 // Timestamp when the message was created.
416 TimeStamp mTimeStamp;
418 WidgetEventTime() : mTimeStamp(TimeStamp::Now()) {}
420 explicit WidgetEventTime(const WidgetEventTime* aTime)
421 : mTimeStamp(aTime ? aTime->mTimeStamp : TimeStamp::Now()) {
422 MOZ_ASSERT(aTime != this);
423 MOZ_ASSERT_IF(aTime, !aTime->mTimeStamp.IsNull());
426 explicit WidgetEventTime(TimeStamp aTimeStamp) : mTimeStamp(aTimeStamp) {}
428 void AssignEventTime(const WidgetEventTime& aOther) {
429 mTimeStamp = aOther.mTimeStamp;
433 /******************************************************************************
434 * mozilla::WidgetEvent
435 ******************************************************************************/
437 class WidgetEvent : public WidgetEventTime {
438 private:
439 void SetDefaultCancelableAndBubbles() {
440 switch (mClass) {
441 case eEditorInputEventClass:
442 mFlags.mCancelable = false;
443 mFlags.mBubbles = mFlags.mIsTrusted;
444 break;
445 case eMouseEventClass:
446 mFlags.mCancelable =
447 (mMessage != eMouseEnter && mMessage != eMouseLeave);
448 mFlags.mBubbles = (mMessage != eMouseEnter && mMessage != eMouseLeave);
449 break;
450 case ePointerEventClass:
451 mFlags.mCancelable =
452 (mMessage != ePointerEnter && mMessage != ePointerLeave &&
453 mMessage != ePointerCancel && mMessage != ePointerGotCapture &&
454 mMessage != ePointerLostCapture);
455 mFlags.mBubbles =
456 (mMessage != ePointerEnter && mMessage != ePointerLeave);
457 break;
458 case eDragEventClass:
459 mFlags.mCancelable = (mMessage != eDragExit && mMessage != eDragLeave &&
460 mMessage != eDragEnd);
461 mFlags.mBubbles = true;
462 break;
463 case eSMILTimeEventClass:
464 mFlags.mCancelable = false;
465 mFlags.mBubbles = false;
466 break;
467 case eTransitionEventClass:
468 case eAnimationEventClass:
469 mFlags.mCancelable = false;
470 mFlags.mBubbles = true;
471 break;
472 case eCompositionEventClass:
473 // XXX compositionstart is cancelable in draft of DOM3 Events.
474 // However, it doesn't make sense for us, we cannot cancel
475 // composition when we send compositionstart event.
476 mFlags.mCancelable = false;
477 mFlags.mBubbles = true;
478 break;
479 default:
480 if (mMessage == eResize || mMessage == eMozVisualResize ||
481 mMessage == eMozVisualScroll || mMessage == eEditorInput ||
482 mMessage == eFormSelect) {
483 mFlags.mCancelable = false;
484 } else {
485 mFlags.mCancelable = true;
487 mFlags.mBubbles = true;
488 break;
492 protected:
493 WidgetEvent(bool aIsTrusted, EventMessage aMessage,
494 EventClassID aEventClassID,
495 const WidgetEventTime* aTime = nullptr)
496 : WidgetEventTime(aTime),
497 mClass(aEventClassID),
498 mMessage(aMessage),
499 mRefPoint(0, 0),
500 mLastRefPoint(0, 0),
501 mFocusSequenceNumber(0),
502 mSpecifiedEventType(nullptr),
503 mPath(nullptr),
504 mLayersId(layers::LayersId{0}) {
505 MOZ_COUNT_CTOR(WidgetEvent);
506 mFlags.Clear();
507 mFlags.mIsTrusted = aIsTrusted;
508 SetDefaultCancelableAndBubbles();
509 SetDefaultComposed();
510 SetDefaultComposedInNativeAnonymousContent();
513 WidgetEvent() : mPath(nullptr) { MOZ_COUNT_CTOR(WidgetEvent); }
515 public:
516 WidgetEvent(bool aIsTrusted, EventMessage aMessage,
517 const WidgetEventTime* aTime = nullptr)
518 : WidgetEvent(aIsTrusted, aMessage, eBasicEventClass, aTime) {}
520 MOZ_COUNTED_DTOR_VIRTUAL(WidgetEvent)
522 WidgetEvent(const WidgetEvent& aOther) : WidgetEventTime(aOther) {
523 MOZ_COUNT_CTOR(WidgetEvent);
524 *this = aOther;
526 WidgetEvent& operator=(const WidgetEvent& aOther) = default;
528 WidgetEvent(WidgetEvent&& aOther)
529 : WidgetEventTime(std::move(aOther)),
530 mClass(aOther.mClass),
531 mMessage(aOther.mMessage),
532 mRefPoint(std::move(aOther.mRefPoint)),
533 mLastRefPoint(std::move(aOther.mLastRefPoint)),
534 mFocusSequenceNumber(aOther.mFocusSequenceNumber),
535 mFlags(std::move(aOther.mFlags)),
536 mSpecifiedEventType(std::move(aOther.mSpecifiedEventType)),
537 mSpecifiedEventTypeString(std::move(aOther.mSpecifiedEventTypeString)),
538 mTarget(std::move(aOther.mTarget)),
539 mCurrentTarget(std::move(aOther.mCurrentTarget)),
540 mOriginalTarget(std::move(aOther.mOriginalTarget)),
541 mRelatedTarget(std::move(aOther.mRelatedTarget)),
542 mOriginalRelatedTarget(std::move(aOther.mOriginalRelatedTarget)),
543 mPath(std::move(aOther.mPath)) {
544 MOZ_COUNT_CTOR(WidgetEvent);
546 WidgetEvent& operator=(WidgetEvent&& aOther) = default;
548 virtual WidgetEvent* Duplicate() const {
549 MOZ_ASSERT(mClass == eBasicEventClass,
550 "Duplicate() must be overridden by sub class");
551 WidgetEvent* result = new WidgetEvent(false, mMessage, this);
552 result->AssignEventData(*this, true);
553 result->mFlags = mFlags;
554 return result;
557 EventClassID mClass;
558 EventMessage mMessage;
559 // Relative to the widget of the event, or if there is no widget then it is
560 // in screen coordinates. Not modified by layout code.
561 // This is in visual coordinates, i.e. the correct RelativeTo value that
562 // expresses what this is relative to is `{viewportFrame, Visual}`, where
563 // `viewportFrame` is the viewport frame of the widget's root document.
564 LayoutDeviceIntPoint mRefPoint;
565 // The previous mRefPoint, if known, used to calculate mouse movement deltas.
566 LayoutDeviceIntPoint mLastRefPoint;
567 // The sequence number of the last potentially focus changing event handled
568 // by APZ. This is used to track when that event has been processed by
569 // content, and focus can be reconfirmed for async keyboard scrolling.
570 uint64_t mFocusSequenceNumber;
571 // See BaseEventFlags definition for the detail.
572 BaseEventFlags mFlags;
574 // If JS creates an event with unknown event type or known event type but
575 // for different event interface, the event type is stored to this.
576 // NOTE: This is always used if the instance is a WidgetCommandEvent instance
577 // or "input" event is dispatched with dom::Event class.
578 RefPtr<nsAtom> mSpecifiedEventType;
580 // nsAtom isn't available on non-main thread due to unsafe. Therefore,
581 // mSpecifiedEventTypeString is used instead of mSpecifiedEventType if
582 // the event is created in non-main thread.
583 nsString mSpecifiedEventTypeString;
585 // Event targets, needed by DOM Events
586 // Note that when you need event target for DOM event, you should use
587 // Get*DOMEventTarget() instead of accessing these members directly.
588 nsCOMPtr<dom::EventTarget> mTarget;
589 nsCOMPtr<dom::EventTarget> mCurrentTarget;
590 nsCOMPtr<dom::EventTarget> mOriginalTarget;
592 /// The possible related target
593 nsCOMPtr<dom::EventTarget> mRelatedTarget;
594 nsCOMPtr<dom::EventTarget> mOriginalRelatedTarget;
596 nsTArray<EventTargetChainItem>* mPath;
598 // The LayersId of the content process that this event should be
599 // dispatched to. This field is only used in the chrome process
600 // and doesn't get remoted to child processes.
601 layers::LayersId mLayersId;
603 dom::EventTarget* GetDOMEventTarget() const;
604 dom::EventTarget* GetCurrentDOMEventTarget() const;
605 dom::EventTarget* GetOriginalDOMEventTarget() const;
607 void AssignEventData(const WidgetEvent& aEvent, bool aCopyTargets) {
608 // mClass should be initialized with the constructor.
609 // mMessage should be initialized with the constructor.
610 mRefPoint = aEvent.mRefPoint;
611 // mLastRefPoint doesn't need to be copied.
612 mFocusSequenceNumber = aEvent.mFocusSequenceNumber;
613 // mLayersId intentionally not copied, since it's not used within content
614 AssignEventTime(aEvent);
615 // mFlags should be copied manually if it's necessary.
616 mSpecifiedEventType = aEvent.mSpecifiedEventType;
617 // mSpecifiedEventTypeString should be copied manually if it's necessary.
618 mTarget = aCopyTargets ? aEvent.mTarget : nullptr;
619 mCurrentTarget = aCopyTargets ? aEvent.mCurrentTarget : nullptr;
620 mOriginalTarget = aCopyTargets ? aEvent.mOriginalTarget : nullptr;
621 mRelatedTarget = aCopyTargets ? aEvent.mRelatedTarget : nullptr;
622 mOriginalRelatedTarget =
623 aCopyTargets ? aEvent.mOriginalRelatedTarget : nullptr;
627 * Helper methods for methods of DOM Event.
629 void StopPropagation() { mFlags.StopPropagation(); }
630 void StopImmediatePropagation() { mFlags.StopImmediatePropagation(); }
631 void PreventDefault(bool aCalledByDefaultHandler = true,
632 nsIPrincipal* aPrincipal = nullptr);
634 void PreventDefaultBeforeDispatch(
635 CrossProcessForwarding aCrossProcessForwarding) {
636 mFlags.PreventDefaultBeforeDispatch(aCrossProcessForwarding);
638 bool DefaultPrevented() const { return mFlags.DefaultPrevented(); }
639 bool DefaultPreventedByContent() const {
640 return mFlags.DefaultPreventedByContent();
642 bool IsTrusted() const { return mFlags.IsTrusted(); }
643 bool PropagationStopped() const { return mFlags.PropagationStopped(); }
646 * Prevent to be dispatched to remote process.
648 inline void StopCrossProcessForwarding() {
649 mFlags.StopCrossProcessForwarding();
652 * Return true if the event shouldn't be dispatched to remote process.
654 inline bool IsCrossProcessForwardingStopped() const {
655 return mFlags.IsCrossProcessForwardingStopped();
658 * Mark the event as waiting reply from remote process.
659 * Note that this also stops immediate propagation in current process.
661 inline void MarkAsWaitingReplyFromRemoteProcess() {
662 mFlags.MarkAsWaitingReplyFromRemoteProcess();
665 * Reset "waiting reply from remote process" state. This is useful when
666 * you dispatch a copy of an event coming from different process.
668 inline void ResetWaitingReplyFromRemoteProcessState() {
669 mFlags.ResetWaitingReplyFromRemoteProcessState();
672 * Return true if the event handler should wait reply event. I.e., if this
673 * returns true, any event handler should do nothing with the event.
675 inline bool IsWaitingReplyFromRemoteProcess() const {
676 return mFlags.IsWaitingReplyFromRemoteProcess();
679 * Mark the event as already handled in the remote process. This should be
680 * called when initializing reply events.
682 inline void MarkAsHandledInRemoteProcess() {
683 mFlags.MarkAsHandledInRemoteProcess();
686 * Return true if the event has already been handled in the remote process.
687 * I.e., if this returns true, the event is a reply event.
689 inline bool IsHandledInRemoteProcess() const {
690 return mFlags.IsHandledInRemoteProcess();
693 * Return true if the event should be sent back to its parent process.
694 * So, usual event handlers shouldn't call this.
696 inline bool WantReplyFromContentProcess() const {
697 return mFlags.WantReplyFromContentProcess();
700 * Mark the event has already posted to a remote process.
702 inline void MarkAsPostedToRemoteProcess() {
703 mFlags.MarkAsPostedToRemoteProcess();
706 * Reset the cross process dispatching state. This should be used when a
707 * process receives the event because the state is in the sender.
709 inline void ResetCrossProcessDispatchingState() {
710 mFlags.ResetCrossProcessDispatchingState();
713 * Return true if the event has been posted to a remote process.
715 inline bool HasBeenPostedToRemoteProcess() const {
716 return mFlags.HasBeenPostedToRemoteProcess();
719 * Return true if the event came from another process.
721 inline bool CameFromAnotherProcess() const {
722 return mFlags.CameFromAnotherProcess();
725 * Mark the event as coming from another process.
727 inline void MarkAsComingFromAnotherProcess() {
728 mFlags.MarkAsComingFromAnotherProcess();
731 * Mark the event is reserved by chrome. I.e., shouldn't be dispatched to
732 * content because it shouldn't be cancelable.
734 inline void MarkAsReservedByChrome() { mFlags.MarkAsReservedByChrome(); }
736 * Return true if the event is reserved by chrome.
738 inline bool IsReservedByChrome() const { return mFlags.IsReservedByChrome(); }
741 * Utils for checking event types
745 * As*Event() returns the pointer of the instance only when the instance is
746 * the class or one of its derived class.
748 #define NS_ROOT_EVENT_CLASS(aPrefix, aName)
749 #define NS_EVENT_CLASS(aPrefix, aName) \
750 virtual aPrefix##aName* As##aName(); \
751 const aPrefix##aName* As##aName() const;
753 #include "mozilla/EventClassList.h"
755 #undef NS_EVENT_CLASS
756 #undef NS_ROOT_EVENT_CLASS
759 * Returns true if the event is a query content event.
761 bool IsQueryContentEvent() const;
763 * Returns true if the event is a selection event.
765 bool IsSelectionEvent() const;
767 * Returns true if the event is a content command event.
769 bool IsContentCommandEvent() const;
772 * Returns true if the event mMessage is one of mouse events.
774 bool HasMouseEventMessage() const;
776 * Returns true if the event mMessage is one of drag events.
778 bool HasDragEventMessage() const;
780 * Returns true if aMessage or mMessage is one of key events.
782 static bool IsKeyEventMessage(EventMessage aMessage);
783 bool HasKeyEventMessage() const { return IsKeyEventMessage(mMessage); }
785 * Returns true if the event mMessage is one of composition events or text
786 * event.
788 bool HasIMEEventMessage() const;
791 * Returns true if the event can be sent to remote process.
793 bool CanBeSentToRemoteProcess() const;
795 * Returns true if the original target is a remote process and the event
796 * will be posted to the remote process later.
798 bool WillBeSentToRemoteProcess() const;
800 * Returns true if the event is related to IME handling. It includes
801 * IME events, query content events and selection events.
802 * Be careful when you use this.
804 bool IsIMERelatedEvent() const;
807 * Whether the event should be handled by the frame of the mouse cursor
808 * position or not. When it should be handled there (e.g., the mouse events),
809 * this returns true.
811 bool IsUsingCoordinates() const;
813 * Whether the event should be handled by the focused DOM window in the
814 * same top level window's or not. E.g., key events, IME related events
815 * (including the query content events, they are used in IME transaction)
816 * should be handled by the (last) focused window rather than the dispatched
817 * window.
819 * NOTE: Even if this returns true, the event isn't going to be handled by the
820 * application level active DOM window which is on another top level window.
821 * So, when the event is fired on a deactive window, the event is going to be
822 * handled by the last focused DOM window in the last focused window.
824 bool IsTargetedAtFocusedWindow() const;
826 * Whether the event should be handled by the focused content or not. E.g.,
827 * key events, IME related events and other input events which are not handled
828 * by the frame of the mouse cursor position.
830 * NOTE: Even if this returns true, the event isn't going to be handled by the
831 * application level active DOM window which is on another top level window.
832 * So, when the event is fired on a deactive window, the event is going to be
833 * handled by the last focused DOM element of the last focused DOM window in
834 * the last focused window.
836 bool IsTargetedAtFocusedContent() const;
838 * Whether the event should cause a DOM event.
840 bool IsAllowedToDispatchDOMEvent() const;
842 * Whether the event should be dispatched in system group.
844 bool IsAllowedToDispatchInSystemGroup() const;
846 * Whether the event should be blocked for fingerprinting resistance.
848 bool IsBlockedForFingerprintingResistance() const;
850 * Whether the event handler can flush pending notifications or not.
852 bool AllowFlushingPendingNotifications() const;
854 * Initialize mComposed
856 void SetDefaultComposed() {
857 switch (mClass) {
858 case eClipboardEventClass:
859 mFlags.mComposed = true;
860 break;
861 case eCompositionEventClass:
862 mFlags.mComposed =
863 mMessage == eCompositionStart || mMessage == eCompositionUpdate ||
864 mMessage == eCompositionChange || mMessage == eCompositionEnd;
865 break;
866 case eDragEventClass:
867 // All drag & drop events are composed
868 mFlags.mComposed = mMessage == eDrag || mMessage == eDragEnd ||
869 mMessage == eDragEnter || mMessage == eDragExit ||
870 mMessage == eDragLeave || mMessage == eDragOver ||
871 mMessage == eDragStart || mMessage == eDrop;
872 break;
873 case eEditorInputEventClass:
874 mFlags.mComposed =
875 mMessage == eEditorInput || mMessage == eEditorBeforeInput;
876 break;
877 case eFocusEventClass:
878 mFlags.mComposed = mMessage == eBlur || mMessage == eFocus ||
879 mMessage == eFocusOut || mMessage == eFocusIn;
880 break;
881 case eKeyboardEventClass:
882 mFlags.mComposed =
883 mMessage == eKeyDown || mMessage == eKeyUp || mMessage == eKeyPress;
884 break;
885 case eMouseEventClass:
886 mFlags.mComposed =
887 mMessage == eMouseClick || mMessage == eMouseDoubleClick ||
888 mMessage == eMouseAuxClick || mMessage == eMouseDown ||
889 mMessage == eMouseUp || mMessage == eMouseOver ||
890 mMessage == eMouseOut || mMessage == eMouseMove ||
891 mMessage == eContextMenu || mMessage == eXULPopupShowing ||
892 mMessage == eXULPopupHiding || mMessage == eXULPopupShown ||
893 mMessage == eXULPopupHidden;
894 break;
895 case ePointerEventClass:
896 // All pointer events are composed
897 mFlags.mComposed =
898 mMessage == ePointerDown || mMessage == ePointerMove ||
899 mMessage == ePointerUp || mMessage == ePointerCancel ||
900 mMessage == ePointerOver || mMessage == ePointerOut ||
901 mMessage == ePointerGotCapture || mMessage == ePointerLostCapture;
902 break;
903 case eTouchEventClass:
904 // All touch events are composed
905 mFlags.mComposed = mMessage == eTouchStart || mMessage == eTouchEnd ||
906 mMessage == eTouchMove || mMessage == eTouchCancel;
907 break;
908 case eUIEventClass:
909 mFlags.mComposed = mMessage == eLegacyDOMFocusIn ||
910 mMessage == eLegacyDOMFocusOut ||
911 mMessage == eLegacyDOMActivate;
912 break;
913 case eWheelEventClass:
914 // All wheel events are composed
915 mFlags.mComposed = mMessage == eWheel;
916 break;
917 case eMouseScrollEventClass:
918 // Legacy mouse scroll events are composed too, for consistency with
919 // wheel.
920 mFlags.mComposed = mMessage == eLegacyMouseLineOrPageScroll ||
921 mMessage == eLegacyMousePixelScroll;
922 break;
923 default:
924 mFlags.mComposed = false;
925 break;
929 void SetComposed(const nsAString& aEventTypeArg) {
930 mFlags.mComposed = // composition events
931 aEventTypeArg.EqualsLiteral("compositionstart") ||
932 aEventTypeArg.EqualsLiteral("compositionupdate") ||
933 aEventTypeArg.EqualsLiteral("compositionend") ||
934 aEventTypeArg.EqualsLiteral("text") ||
935 // drag and drop events
936 aEventTypeArg.EqualsLiteral("dragstart") ||
937 aEventTypeArg.EqualsLiteral("drag") ||
938 aEventTypeArg.EqualsLiteral("dragenter") ||
939 aEventTypeArg.EqualsLiteral("dragexit") ||
940 aEventTypeArg.EqualsLiteral("dragleave") ||
941 aEventTypeArg.EqualsLiteral("dragover") ||
942 aEventTypeArg.EqualsLiteral("drop") ||
943 aEventTypeArg.EqualsLiteral("dropend") ||
944 // editor input events
945 aEventTypeArg.EqualsLiteral("input") ||
946 aEventTypeArg.EqualsLiteral("beforeinput") ||
947 // focus events
948 aEventTypeArg.EqualsLiteral("blur") ||
949 aEventTypeArg.EqualsLiteral("focus") ||
950 aEventTypeArg.EqualsLiteral("focusin") ||
951 aEventTypeArg.EqualsLiteral("focusout") ||
952 // keyboard events
953 aEventTypeArg.EqualsLiteral("keydown") ||
954 aEventTypeArg.EqualsLiteral("keyup") ||
955 aEventTypeArg.EqualsLiteral("keypress") ||
956 // mouse events
957 aEventTypeArg.EqualsLiteral("click") ||
958 aEventTypeArg.EqualsLiteral("dblclick") ||
959 aEventTypeArg.EqualsLiteral("mousedown") ||
960 aEventTypeArg.EqualsLiteral("mouseup") ||
961 aEventTypeArg.EqualsLiteral("mouseenter") ||
962 aEventTypeArg.EqualsLiteral("mouseleave") ||
963 aEventTypeArg.EqualsLiteral("mouseover") ||
964 aEventTypeArg.EqualsLiteral("mouseout") ||
965 aEventTypeArg.EqualsLiteral("mousemove") ||
966 aEventTypeArg.EqualsLiteral("contextmenu") ||
967 // pointer events
968 aEventTypeArg.EqualsLiteral("pointerdown") ||
969 aEventTypeArg.EqualsLiteral("pointermove") ||
970 aEventTypeArg.EqualsLiteral("pointerup") ||
971 aEventTypeArg.EqualsLiteral("pointercancel") ||
972 aEventTypeArg.EqualsLiteral("pointerover") ||
973 aEventTypeArg.EqualsLiteral("pointerout") ||
974 aEventTypeArg.EqualsLiteral("pointerenter") ||
975 aEventTypeArg.EqualsLiteral("pointerleave") ||
976 aEventTypeArg.EqualsLiteral("gotpointercapture") ||
977 aEventTypeArg.EqualsLiteral("lostpointercapture") ||
978 // touch events
979 aEventTypeArg.EqualsLiteral("touchstart") ||
980 aEventTypeArg.EqualsLiteral("touchend") ||
981 aEventTypeArg.EqualsLiteral("touchmove") ||
982 aEventTypeArg.EqualsLiteral("touchcancel") ||
983 // UI legacy events
984 aEventTypeArg.EqualsLiteral("DOMFocusIn") ||
985 aEventTypeArg.EqualsLiteral("DOMFocusOut") ||
986 aEventTypeArg.EqualsLiteral("DOMActivate") ||
987 // wheel events
988 aEventTypeArg.EqualsLiteral("wheel");
991 void SetComposed(bool aComposed) { mFlags.mComposed = aComposed; }
993 void SetDefaultComposedInNativeAnonymousContent() {
994 // For compatibility concerns, we set mComposedInNativeAnonymousContent to
995 // false for those events we want to stop propagation.
997 // nsVideoFrame may create anonymous image element which fires eLoad,
998 // eLoadStart, eLoadEnd, eLoadError. We don't want these events cross
999 // the boundary of NAC
1000 mFlags.mComposedInNativeAnonymousContent =
1001 mMessage != eLoad && mMessage != eLoadStart && mMessage != eLoadEnd &&
1002 mMessage != eLoadError;
1005 bool IsUserAction() const;
1008 /******************************************************************************
1009 * mozilla::WidgetGUIEvent
1010 ******************************************************************************/
1012 class WidgetGUIEvent : public WidgetEvent {
1013 protected:
1014 WidgetGUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
1015 EventClassID aEventClassID,
1016 const WidgetEventTime* aTime = nullptr)
1017 : WidgetEvent(aIsTrusted, aMessage, aEventClassID, aTime),
1018 mWidget(aWidget) {}
1020 WidgetGUIEvent() = default;
1022 public:
1023 virtual WidgetGUIEvent* AsGUIEvent() override { return this; }
1025 WidgetGUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
1026 const WidgetEventTime* aTime = nullptr)
1027 : WidgetEvent(aIsTrusted, aMessage, eGUIEventClass, aTime),
1028 mWidget(aWidget) {}
1030 virtual WidgetEvent* Duplicate() const override {
1031 MOZ_ASSERT(mClass == eGUIEventClass,
1032 "Duplicate() must be overridden by sub class");
1033 // Not copying widget, it is a weak reference.
1034 WidgetGUIEvent* result = new WidgetGUIEvent(false, mMessage, nullptr, this);
1035 result->AssignGUIEventData(*this, true);
1036 result->mFlags = mFlags;
1037 return result;
1040 // Originator of the event
1041 nsCOMPtr<nsIWidget> mWidget;
1043 void AssignGUIEventData(const WidgetGUIEvent& aEvent, bool aCopyTargets) {
1044 AssignEventData(aEvent, aCopyTargets);
1045 // widget should be initialized with the constructor.
1049 /******************************************************************************
1050 * mozilla::Modifier
1052 * All modifier keys should be defined here. This is used for managing
1053 * modifier states for DOM Level 3 or later.
1054 ******************************************************************************/
1056 enum Modifier {
1057 MODIFIER_NONE = 0x0000,
1058 MODIFIER_ALT = 0x0001,
1059 MODIFIER_ALTGRAPH = 0x0002,
1060 MODIFIER_CAPSLOCK = 0x0004,
1061 MODIFIER_CONTROL = 0x0008,
1062 MODIFIER_FN = 0x0010,
1063 MODIFIER_FNLOCK = 0x0020,
1064 MODIFIER_META = 0x0040,
1065 MODIFIER_NUMLOCK = 0x0080,
1066 MODIFIER_SCROLLLOCK = 0x0100,
1067 MODIFIER_SHIFT = 0x0200,
1068 MODIFIER_SYMBOL = 0x0400,
1069 MODIFIER_SYMBOLLOCK = 0x0800,
1072 /******************************************************************************
1073 * Modifier key names.
1074 ******************************************************************************/
1076 #define NS_DOM_KEYNAME_ALT "Alt"
1077 #define NS_DOM_KEYNAME_ALTGRAPH "AltGraph"
1078 #define NS_DOM_KEYNAME_CAPSLOCK "CapsLock"
1079 #define NS_DOM_KEYNAME_CONTROL "Control"
1080 #define NS_DOM_KEYNAME_FN "Fn"
1081 #define NS_DOM_KEYNAME_FNLOCK "FnLock"
1082 #define NS_DOM_KEYNAME_META "Meta"
1083 #define NS_DOM_KEYNAME_NUMLOCK "NumLock"
1084 #define NS_DOM_KEYNAME_SCROLLLOCK "ScrollLock"
1085 #define NS_DOM_KEYNAME_SHIFT "Shift"
1086 #define NS_DOM_KEYNAME_SYMBOL "Symbol"
1087 #define NS_DOM_KEYNAME_SYMBOLLOCK "SymbolLock"
1088 #define NS_DOM_KEYNAME_OS "OS"
1090 /******************************************************************************
1091 * mozilla::Modifiers
1092 ******************************************************************************/
1094 typedef uint16_t Modifiers;
1096 class MOZ_STACK_CLASS GetModifiersName final : public nsAutoCString {
1097 public:
1098 explicit GetModifiersName(Modifiers aModifiers) {
1099 if (aModifiers & MODIFIER_ALT) {
1100 AssignLiteral(NS_DOM_KEYNAME_ALT);
1102 if (aModifiers & MODIFIER_ALTGRAPH) {
1103 MaybeAppendSeparator();
1104 AppendLiteral(NS_DOM_KEYNAME_ALTGRAPH);
1106 if (aModifiers & MODIFIER_CAPSLOCK) {
1107 MaybeAppendSeparator();
1108 AppendLiteral(NS_DOM_KEYNAME_CAPSLOCK);
1110 if (aModifiers & MODIFIER_CONTROL) {
1111 MaybeAppendSeparator();
1112 AppendLiteral(NS_DOM_KEYNAME_CONTROL);
1114 if (aModifiers & MODIFIER_FN) {
1115 MaybeAppendSeparator();
1116 AppendLiteral(NS_DOM_KEYNAME_FN);
1118 if (aModifiers & MODIFIER_FNLOCK) {
1119 MaybeAppendSeparator();
1120 AppendLiteral(NS_DOM_KEYNAME_FNLOCK);
1122 if (aModifiers & MODIFIER_META) {
1123 MaybeAppendSeparator();
1124 AppendLiteral(NS_DOM_KEYNAME_META);
1126 if (aModifiers & MODIFIER_NUMLOCK) {
1127 MaybeAppendSeparator();
1128 AppendLiteral(NS_DOM_KEYNAME_NUMLOCK);
1130 if (aModifiers & MODIFIER_SCROLLLOCK) {
1131 MaybeAppendSeparator();
1132 AppendLiteral(NS_DOM_KEYNAME_SCROLLLOCK);
1134 if (aModifiers & MODIFIER_SHIFT) {
1135 MaybeAppendSeparator();
1136 AppendLiteral(NS_DOM_KEYNAME_SHIFT);
1138 if (aModifiers & MODIFIER_SYMBOL) {
1139 MaybeAppendSeparator();
1140 AppendLiteral(NS_DOM_KEYNAME_SYMBOL);
1142 if (aModifiers & MODIFIER_SYMBOLLOCK) {
1143 MaybeAppendSeparator();
1144 AppendLiteral(NS_DOM_KEYNAME_SYMBOLLOCK);
1146 if (IsEmpty()) {
1147 AssignLiteral("none");
1151 private:
1152 void MaybeAppendSeparator() {
1153 if (!IsEmpty()) {
1154 AppendLiteral(" | ");
1159 /******************************************************************************
1160 * mozilla::WidgetInputEvent
1161 ******************************************************************************/
1163 class WidgetInputEvent : public WidgetGUIEvent {
1164 protected:
1165 WidgetInputEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
1166 EventClassID aEventClassID,
1167 const WidgetEventTime* aTime = nullptr)
1168 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, aEventClassID, aTime),
1169 mModifiers(0) {}
1171 WidgetInputEvent() : mModifiers(0) {}
1173 public:
1174 virtual WidgetInputEvent* AsInputEvent() override { return this; }
1176 WidgetInputEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
1177 const WidgetEventTime* aTime = nullptr)
1178 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eInputEventClass, aTime),
1179 mModifiers(0) {}
1181 virtual WidgetEvent* Duplicate() const override {
1182 MOZ_ASSERT(mClass == eInputEventClass,
1183 "Duplicate() must be overridden by sub class");
1184 // Not copying widget, it is a weak reference.
1185 WidgetInputEvent* result =
1186 new WidgetInputEvent(false, mMessage, nullptr, this);
1187 result->AssignInputEventData(*this, true);
1188 result->mFlags = mFlags;
1189 return result;
1193 * Returns a modifier of "Accel" virtual modifier which is used for shortcut
1194 * key.
1196 static Modifier AccelModifier();
1199 * GetModifier() returns a modifier flag which is activated by aDOMKeyName.
1201 static Modifier GetModifier(const nsAString& aDOMKeyName);
1203 // true indicates the accel key on the environment is down
1204 bool IsAccel() const { return ((mModifiers & AccelModifier()) != 0); }
1206 // true indicates the shift key is down
1207 bool IsShift() const { return ((mModifiers & MODIFIER_SHIFT) != 0); }
1208 // true indicates the control key is down
1209 bool IsControl() const { return ((mModifiers & MODIFIER_CONTROL) != 0); }
1210 // true indicates the alt key is down
1211 bool IsAlt() const { return ((mModifiers & MODIFIER_ALT) != 0); }
1212 // true indicates the meta key is down (Command key on macOS, Windows logo key
1213 // on Windows, Super/Hyper key on Linux, Meta key on Android).
1214 bool IsMeta() const { return ((mModifiers & MODIFIER_META) != 0); }
1215 // true indicates the alt graph key is down
1216 // NOTE: on Mac, the option key press causes both IsAlt() and IsAltGrpah()
1217 // return true.
1218 bool IsAltGraph() const { return ((mModifiers & MODIFIER_ALTGRAPH) != 0); }
1219 // true indicates the CapLock LED is turn on.
1220 bool IsCapsLocked() const { return ((mModifiers & MODIFIER_CAPSLOCK) != 0); }
1221 // true indicates the NumLock LED is turn on.
1222 bool IsNumLocked() const { return ((mModifiers & MODIFIER_NUMLOCK) != 0); }
1223 // true indicates the ScrollLock LED is turn on.
1224 bool IsScrollLocked() const {
1225 return ((mModifiers & MODIFIER_SCROLLLOCK) != 0);
1228 // true indicates the Fn key is down, but this is not supported by native
1229 // key event on any platform.
1230 bool IsFn() const { return ((mModifiers & MODIFIER_FN) != 0); }
1231 // true indicates the FnLock LED is turn on, but we don't know such
1232 // keyboards nor platforms.
1233 bool IsFnLocked() const { return ((mModifiers & MODIFIER_FNLOCK) != 0); }
1234 // true indicates the Symbol is down, but this is not supported by native
1235 // key event on any platforms.
1236 bool IsSymbol() const { return ((mModifiers & MODIFIER_SYMBOL) != 0); }
1237 // true indicates the SymbolLock LED is turn on, but we don't know such
1238 // keyboards nor platforms.
1239 bool IsSymbolLocked() const {
1240 return ((mModifiers & MODIFIER_SYMBOLLOCK) != 0);
1243 void InitBasicModifiers(bool aCtrlKey, bool aAltKey, bool aShiftKey,
1244 bool aMetaKey) {
1245 mModifiers = 0;
1246 if (aCtrlKey) {
1247 mModifiers |= MODIFIER_CONTROL;
1249 if (aAltKey) {
1250 mModifiers |= MODIFIER_ALT;
1252 if (aShiftKey) {
1253 mModifiers |= MODIFIER_SHIFT;
1255 if (aMetaKey) {
1256 mModifiers |= MODIFIER_META;
1260 Modifiers mModifiers;
1262 void AssignInputEventData(const WidgetInputEvent& aEvent, bool aCopyTargets) {
1263 AssignGUIEventData(aEvent, aCopyTargets);
1265 mModifiers = aEvent.mModifiers;
1269 /******************************************************************************
1270 * mozilla::InternalUIEvent
1272 * XXX Why this inherits WidgetGUIEvent rather than WidgetEvent?
1273 ******************************************************************************/
1275 class InternalUIEvent : public WidgetGUIEvent {
1276 protected:
1277 InternalUIEvent() : mDetail(0), mCausedByUntrustedEvent(false) {}
1279 InternalUIEvent(bool aIsTrusted, EventMessage aMessage, nsIWidget* aWidget,
1280 EventClassID aEventClassID,
1281 const WidgetEventTime* aTime = nullptr)
1282 : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, aEventClassID, aTime),
1283 mDetail(0),
1284 mCausedByUntrustedEvent(false) {}
1286 InternalUIEvent(bool aIsTrusted, EventMessage aMessage,
1287 EventClassID aEventClassID,
1288 const WidgetEventTime* aTime = nullptr)
1289 : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, aEventClassID, aTime),
1290 mDetail(0),
1291 mCausedByUntrustedEvent(false) {}
1293 public:
1294 virtual InternalUIEvent* AsUIEvent() override { return this; }
1297 * If the UIEvent is caused by another event (e.g., click event),
1298 * aEventCausesThisEvent should be the event. If there is no such event,
1299 * this should be nullptr.
1301 InternalUIEvent(bool aIsTrusted, EventMessage aMessage,
1302 const WidgetEvent* aEventCausesThisEvent,
1303 const WidgetEventTime* aTime = nullptr)
1304 : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, eUIEventClass, aTime),
1305 mDetail(0),
1306 mCausedByUntrustedEvent(aEventCausesThisEvent &&
1307 !aEventCausesThisEvent->IsTrusted()) {}
1309 virtual WidgetEvent* Duplicate() const override {
1310 MOZ_ASSERT(mClass == eUIEventClass,
1311 "Duplicate() must be overridden by sub class");
1312 InternalUIEvent* result =
1313 new InternalUIEvent(false, mMessage, nullptr, this);
1314 result->AssignUIEventData(*this, true);
1315 result->mFlags = mFlags;
1316 return result;
1319 int32_t mDetail;
1320 // mCausedByUntrustedEvent is true if the event is caused by untrusted event.
1321 bool mCausedByUntrustedEvent;
1323 // If you check the event is a trusted event and NOT caused by an untrusted
1324 // event, IsTrustable() returns what you expected.
1325 bool IsTrustable() const { return IsTrusted() && !mCausedByUntrustedEvent; }
1327 void AssignUIEventData(const InternalUIEvent& aEvent, bool aCopyTargets) {
1328 AssignGUIEventData(aEvent, aCopyTargets);
1330 mDetail = aEvent.mDetail;
1331 mCausedByUntrustedEvent = aEvent.mCausedByUntrustedEvent;
1335 } // namespace mozilla
1337 #endif // mozilla_BasicEvents_h__