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_MouseEvents_h__
7 #define mozilla_MouseEvents_h__
11 #include "mozilla/BasicEvents.h"
12 #include "mozilla/MathAlgorithms.h"
13 #include "mozilla/dom/DataTransfer.h"
15 #include "nsIDOMMouseEvent.h"
16 #include "nsIDOMWheelEvent.h"
18 /******************************************************************************
19 * nsDragDropEventStatus
20 ******************************************************************************/
22 enum nsDragDropEventStatus
24 // The event is a enter
25 nsDragDropEventStatus_eDragEntered
,
27 nsDragDropEventStatus_eDragExited
,
29 nsDragDropEventStatus_eDrop
39 /******************************************************************************
40 * mozilla::WidgetPointerHelper
41 ******************************************************************************/
43 class WidgetPointerHelper
46 bool convertToPointer
;
50 bool retargetedByPointerCapture
;
52 WidgetPointerHelper() : convertToPointer(true), pointerId(0), tiltX(0), tiltY(0),
53 retargetedByPointerCapture(false) {}
55 void AssignPointerHelperData(const WidgetPointerHelper
& aEvent
)
57 convertToPointer
= aEvent
.convertToPointer
;
58 pointerId
= aEvent
.pointerId
;
61 retargetedByPointerCapture
= aEvent
.retargetedByPointerCapture
;
65 /******************************************************************************
66 * mozilla::WidgetMouseEventBase
67 ******************************************************************************/
69 class WidgetMouseEventBase
: public WidgetInputEvent
72 friend class dom::PBrowserParent
;
73 friend class dom::PBrowserChild
;
76 WidgetMouseEventBase()
80 WidgetMouseEventBase(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
81 EventClassID aEventClassID
)
82 : WidgetInputEvent(aIsTrusted
, aMessage
, aWidget
, aEventClassID
)
86 , inputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE
)
91 virtual WidgetMouseEventBase
* AsMouseEventBase() MOZ_OVERRIDE
{ return this; }
93 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
95 MOZ_CRASH("WidgetMouseEventBase must not be most-subclass");
99 /// The possible related target
100 nsCOMPtr
<nsISupports
> relatedTarget
;
108 // Pressed button ID of mousedown or mouseup event.
109 // This is set only when pressing a button causes the event.
113 eLeftButtonFlag
= 0x01,
114 eRightButtonFlag
= 0x02,
115 eMiddleButtonFlag
= 0x04,
116 // typicall, "back" button being left side of 5-button
117 // mice, see "buttons" attribute document of DOM3 Events.
118 e4thButtonFlag
= 0x08,
119 // typicall, "forward" button being right side of 5-button
120 // mice, see "buttons" attribute document of DOM3 Events.
121 e5thButtonFlag
= 0x10
124 // Flags of all pressed buttons at the event fired.
125 // This is set at any mouse event, don't be confused with |button|.
128 // Finger or touch pressure of event. It ranges between 0.0 and 1.0.
131 // Possible values at nsIDOMMouseEvent
132 uint16_t inputSource
;
134 // ID of the canvas HitRegion
137 void AssignMouseEventBaseData(const WidgetMouseEventBase
& aEvent
,
140 AssignInputEventData(aEvent
, aCopyTargets
);
142 relatedTarget
= aCopyTargets
? aEvent
.relatedTarget
: nullptr;
143 button
= aEvent
.button
;
144 buttons
= aEvent
.buttons
;
145 pressure
= aEvent
.pressure
;
146 inputSource
= aEvent
.inputSource
;
150 * Returns true if left click event.
152 bool IsLeftClickEvent() const
154 return message
== NS_MOUSE_CLICK
&& button
== eLeftButton
;
158 /******************************************************************************
159 * mozilla::WidgetMouseEvent
160 ******************************************************************************/
162 class WidgetMouseEvent
: public WidgetMouseEventBase
, public WidgetPointerHelper
165 friend class mozilla::dom::PBrowserParent
;
166 friend class mozilla::dom::PBrowserChild
;
192 WidgetMouseEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
193 EventClassID aEventClassID
, reasonType aReason
)
194 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, aEventClassID
)
195 , acceptActivation(false)
196 , ignoreRootScrollFrame(false)
205 mFlags
.mBubbles
= false;
206 mFlags
.mCancelable
= false;
214 virtual WidgetMouseEvent
* AsMouseEvent() MOZ_OVERRIDE
{ return this; }
216 WidgetMouseEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
217 reasonType aReason
, contextType aContext
= eNormal
) :
218 WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, eMouseEventClass
),
219 acceptActivation(false), ignoreRootScrollFrame(false),
220 reason(aReason
), context(aContext
), exit(eChild
), clickCount(0)
225 mFlags
.mBubbles
= false;
226 mFlags
.mCancelable
= false;
229 button
= (context
== eNormal
) ? eRightButton
: eLeftButton
;
237 virtual ~WidgetMouseEvent()
239 NS_WARN_IF_FALSE(message
!= NS_CONTEXTMENU
||
241 ((context
== eNormal
) ? eRightButton
: eLeftButton
),
242 "Wrong button set to NS_CONTEXTMENU event?");
246 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
248 MOZ_ASSERT(mClass
== eMouseEventClass
,
249 "Duplicate() must be overridden by sub class");
250 // Not copying widget, it is a weak reference.
251 WidgetMouseEvent
* result
=
252 new WidgetMouseEvent(false, message
, nullptr, reason
, context
);
253 result
->AssignMouseEventData(*this, true);
254 result
->mFlags
= mFlags
;
258 // Special return code for MOUSE_ACTIVATE to signal.
259 // If the target accepts activation (1), or denies it (0).
260 bool acceptActivation
;
261 // Whether the event should ignore scroll frame bounds during dispatch.
262 bool ignoreRootScrollFrame
;
264 reasonType reason
: 4;
265 contextType context
: 4;
268 /// The number of mouse clicks.
271 void AssignMouseEventData(const WidgetMouseEvent
& aEvent
, bool aCopyTargets
)
273 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
274 AssignPointerHelperData(aEvent
);
276 acceptActivation
= aEvent
.acceptActivation
;
277 ignoreRootScrollFrame
= aEvent
.ignoreRootScrollFrame
;
278 clickCount
= aEvent
.clickCount
;
282 * Returns true if the event is a context menu event caused by key.
284 bool IsContextMenuKeyEvent() const
286 return message
== NS_CONTEXTMENU
&& context
== eContextMenuKey
;
290 * Returns true if the event is a real mouse event. Otherwise, i.e., it's
291 * a synthesized event by scroll or something, returns false.
295 return reason
== eReal
;
299 /******************************************************************************
300 * mozilla::WidgetDragEvent
301 ******************************************************************************/
303 class WidgetDragEvent
: public WidgetMouseEvent
306 virtual WidgetDragEvent
* AsDragEvent() MOZ_OVERRIDE
{ return this; }
308 WidgetDragEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
)
309 : WidgetMouseEvent(aIsTrusted
, aMessage
, aWidget
, eDragEventClass
, eReal
)
310 , userCancelled(false)
311 , mDefaultPreventedOnContent(false)
314 (aMessage
!= NS_DRAGDROP_EXIT_SYNTH
&&
315 aMessage
!= NS_DRAGDROP_LEAVE_SYNTH
&&
316 aMessage
!= NS_DRAGDROP_END
);
319 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
321 MOZ_ASSERT(mClass
== eDragEventClass
,
322 "Duplicate() must be overridden by sub class");
323 // Not copying widget, it is a weak reference.
324 WidgetDragEvent
* result
= new WidgetDragEvent(false, message
, nullptr);
325 result
->AssignDragEventData(*this, true);
326 result
->mFlags
= mFlags
;
330 // The dragging data.
331 nsCOMPtr
<dom::DataTransfer
> dataTransfer
;
333 // If this is true, user has cancelled the drag operation.
335 // If this is true, the drag event's preventDefault() is called on content.
336 bool mDefaultPreventedOnContent
;
338 // XXX Not tested by test_assign_event_data.html
339 void AssignDragEventData(const WidgetDragEvent
& aEvent
, bool aCopyTargets
)
341 AssignMouseEventData(aEvent
, aCopyTargets
);
343 dataTransfer
= aEvent
.dataTransfer
;
344 // XXX userCancelled isn't copied, is this instentionally?
345 userCancelled
= false;
346 mDefaultPreventedOnContent
= aEvent
.mDefaultPreventedOnContent
;
350 /******************************************************************************
351 * mozilla::WidgetMouseScrollEvent
353 * This is used for legacy DOM mouse scroll events, i.e.,
354 * DOMMouseScroll and MozMousePixelScroll event. These events are NOT hanbled
355 * by ESM even if widget dispatches them. Use new WidgetWheelEvent instead.
356 ******************************************************************************/
358 class WidgetMouseScrollEvent
: public WidgetMouseEventBase
361 WidgetMouseScrollEvent()
366 virtual WidgetMouseScrollEvent
* AsMouseScrollEvent() MOZ_OVERRIDE
371 WidgetMouseScrollEvent(bool aIsTrusted
, uint32_t aMessage
,
373 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
,
374 eMouseScrollEventClass
)
376 , isHorizontal(false)
380 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
382 MOZ_ASSERT(mClass
== eMouseScrollEventClass
,
383 "Duplicate() must be overridden by sub class");
384 // Not copying widget, it is a weak reference.
385 WidgetMouseScrollEvent
* result
=
386 new WidgetMouseScrollEvent(false, message
, nullptr);
387 result
->AssignMouseScrollEventData(*this, true);
388 result
->mFlags
= mFlags
;
392 // The delta value of mouse scroll event.
393 // If the event message is NS_MOUSE_SCROLL, the value indicates scroll amount
394 // in lines. However, if the value is nsIDOMUIEvent::SCROLL_PAGE_UP or
395 // nsIDOMUIEvent::SCROLL_PAGE_DOWN, the value inducates one page scroll.
396 // If the event message is NS_MOUSE_PIXEL_SCROLL, the value indicates scroll
400 // If this is true, it may cause to scroll horizontally.
401 // Otherwise, vertically.
404 void AssignMouseScrollEventData(const WidgetMouseScrollEvent
& aEvent
,
407 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
409 delta
= aEvent
.delta
;
410 isHorizontal
= aEvent
.isHorizontal
;
414 /******************************************************************************
415 * mozilla::WidgetWheelEvent
416 ******************************************************************************/
418 class WidgetWheelEvent
: public WidgetMouseEventBase
421 friend class mozilla::dom::PBrowserParent
;
422 friend class mozilla::dom::PBrowserChild
;
429 virtual WidgetWheelEvent
* AsWheelEvent() MOZ_OVERRIDE
{ return this; }
431 WidgetWheelEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
)
432 : WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, eWheelEventClass
)
436 , deltaMode(nsIDOMWheelEvent::DOM_DELTA_PIXEL
)
437 , customizedByUserPrefs(false)
439 , mIsNoLineOrPageDelta(false)
440 , lineOrPageDeltaX(0)
441 , lineOrPageDeltaY(0)
442 , scrollType(SCROLL_DEFAULT
)
443 , overflowDeltaX(0.0)
444 , overflowDeltaY(0.0)
445 , mViewPortIsOverscrolled(false)
449 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
451 MOZ_ASSERT(mClass
== eWheelEventClass
,
452 "Duplicate() must be overridden by sub class");
453 // Not copying widget, it is a weak reference.
454 WidgetWheelEvent
* result
= new WidgetWheelEvent(false, message
, nullptr);
455 result
->AssignWheelEventData(*this, true);
456 result
->mFlags
= mFlags
;
460 // NOTE: deltaX, deltaY and deltaZ may be customized by
461 // mousewheel.*.delta_multiplier_* prefs which are applied by
462 // EventStateManager. So, after widget dispatches this event,
463 // these delta values may have different values than before.
468 // Should be one of nsIDOMWheelEvent::DOM_DELTA_*
471 // Following members are for internal use only, not for DOM event.
473 // If the delta values are computed from prefs, this value is true.
474 // Otherwise, i.e., they are computed from native events, false.
475 bool customizedByUserPrefs
;
477 // true if the event is caused by momentum.
480 // If device event handlers don't know when they should set lineOrPageDeltaX
481 // and lineOrPageDeltaY, this is true. Otherwise, false.
482 // If mIsNoLineOrPageDelta is true, ESM will generate NS_MOUSE_SCROLL events
483 // when accumulated delta values reach a line height.
484 bool mIsNoLineOrPageDelta
;
486 // If widget sets lineOrPageDelta, EventStateManager will dispatch
487 // NS_MOUSE_SCROLL event for compatibility. Note that the delta value means
488 // pages if the deltaMode is DOM_DELTA_PAGE, otherwise, lines.
489 int32_t lineOrPageDeltaX
;
490 int32_t lineOrPageDeltaY
;
492 // When the default action for an wheel event is moving history or zooming,
493 // need to chose a delta value for doing it.
494 int32_t GetPreferredIntDelta()
496 if (!lineOrPageDeltaX
&& !lineOrPageDeltaY
) {
499 if (lineOrPageDeltaY
&& !lineOrPageDeltaX
) {
500 return lineOrPageDeltaY
;
502 if (lineOrPageDeltaX
&& !lineOrPageDeltaY
) {
503 return lineOrPageDeltaX
;
505 if ((lineOrPageDeltaX
< 0 && lineOrPageDeltaY
> 0) ||
506 (lineOrPageDeltaX
> 0 && lineOrPageDeltaY
< 0)) {
507 return 0; // We cannot guess the answer in this case.
509 return (Abs(lineOrPageDeltaX
) > Abs(lineOrPageDeltaY
)) ?
510 lineOrPageDeltaX
: lineOrPageDeltaY
;
514 // The default value is SCROLL_DEFAULT, which means EventStateManager will
515 // select preferred scroll type automatically.
519 SCROLL_SYNCHRONOUSLY
,
520 SCROLL_ASYNCHRONOUSELY
,
523 ScrollType scrollType
;
525 // overflowed delta values for scroll, these values are set by
526 // nsEventStateManger. If the default action of the wheel event isn't scroll,
527 // these values always zero. Otherwise, remaning delta values which are
528 // not used by scroll are set.
529 // NOTE: deltaX, deltaY and deltaZ may be modified by EventStateManager.
530 // However, overflowDeltaX and overflowDeltaY indicate unused original
531 // delta values which are not applied the delta_multiplier prefs.
532 // So, if widget wanted to know the actual direction to be scrolled,
533 // it would need to check the deltaX and deltaY.
534 double overflowDeltaX
;
535 double overflowDeltaY
;
537 // Whether or not the parent of the currently overscrolled frame is the
538 // ViewPort. This is false in situations when an element on the page is being
539 // overscrolled (such as a text field), but true when the 'page' is being
541 bool mViewPortIsOverscrolled
;
543 void AssignWheelEventData(const WidgetWheelEvent
& aEvent
, bool aCopyTargets
)
545 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
547 deltaX
= aEvent
.deltaX
;
548 deltaY
= aEvent
.deltaY
;
549 deltaZ
= aEvent
.deltaZ
;
550 deltaMode
= aEvent
.deltaMode
;
551 customizedByUserPrefs
= aEvent
.customizedByUserPrefs
;
552 isMomentum
= aEvent
.isMomentum
;
553 mIsNoLineOrPageDelta
= aEvent
.mIsNoLineOrPageDelta
;
554 lineOrPageDeltaX
= aEvent
.lineOrPageDeltaX
;
555 lineOrPageDeltaY
= aEvent
.lineOrPageDeltaY
;
556 scrollType
= aEvent
.scrollType
;
557 overflowDeltaX
= aEvent
.overflowDeltaX
;
558 overflowDeltaY
= aEvent
.overflowDeltaY
;
559 mViewPortIsOverscrolled
= aEvent
.mViewPortIsOverscrolled
;
563 /******************************************************************************
564 * mozilla::WidgetPointerEvent
565 ******************************************************************************/
567 class WidgetPointerEvent
: public WidgetMouseEvent
569 friend class mozilla::dom::PBrowserParent
;
570 friend class mozilla::dom::PBrowserChild
;
577 virtual WidgetPointerEvent
* AsPointerEvent() MOZ_OVERRIDE
{ return this; }
579 WidgetPointerEvent(bool aIsTrusted
, uint32_t aMsg
, nsIWidget
* w
)
580 : WidgetMouseEvent(aIsTrusted
, aMsg
, w
, ePointerEventClass
, eReal
)
588 explicit WidgetPointerEvent(const WidgetMouseEvent
& aEvent
)
589 : WidgetMouseEvent(aEvent
)
594 mClass
= ePointerEventClass
;
601 case NS_POINTER_ENTER
:
602 case NS_POINTER_LEAVE
:
603 mFlags
.mBubbles
= false;
604 mFlags
.mCancelable
= false;
606 case NS_POINTER_CANCEL
:
607 case NS_POINTER_GOT_CAPTURE
:
608 case NS_POINTER_LOST_CAPTURE
:
609 mFlags
.mCancelable
= false;
616 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
618 MOZ_ASSERT(mClass
== ePointerEventClass
,
619 "Duplicate() must be overridden by sub class");
620 // Not copying widget, it is a weak reference.
621 WidgetPointerEvent
* result
=
622 new WidgetPointerEvent(false, message
, nullptr);
623 result
->AssignPointerEventData(*this, true);
624 result
->mFlags
= mFlags
;
632 // XXX Not tested by test_assign_event_data.html
633 void AssignPointerEventData(const WidgetPointerEvent
& aEvent
,
636 AssignMouseEventData(aEvent
, aCopyTargets
);
638 width
= aEvent
.width
;
639 height
= aEvent
.height
;
640 isPrimary
= aEvent
.isPrimary
;
644 } // namespace mozilla
646 #endif // mozilla_MouseEvents_h__