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
;
51 WidgetPointerHelper() : convertToPointer(true), pointerId(0), tiltX(0), tiltY(0) {}
53 void AssignPointerHelperData(const WidgetPointerHelper
& aEvent
)
55 convertToPointer
= aEvent
.convertToPointer
;
56 pointerId
= aEvent
.pointerId
;
62 /******************************************************************************
63 * mozilla::WidgetMouseEventBase
64 ******************************************************************************/
66 class WidgetMouseEventBase
: public WidgetInputEvent
69 friend class dom::PBrowserParent
;
70 friend class dom::PBrowserChild
;
73 WidgetMouseEventBase()
77 WidgetMouseEventBase(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
78 nsEventStructType aStructType
) :
79 WidgetInputEvent(aIsTrusted
, aMessage
, aWidget
, aStructType
),
80 button(0), buttons(0), pressure(0),
81 inputSource(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE
)
86 virtual WidgetMouseEventBase
* AsMouseEventBase() MOZ_OVERRIDE
{ return this; }
88 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
90 MOZ_CRASH("WidgetMouseEventBase must not be most-subclass");
94 /// The possible related target
95 nsCOMPtr
<nsISupports
> relatedTarget
;
103 // Pressed button ID of mousedown or mouseup event.
104 // This is set only when pressing a button causes the event.
108 eLeftButtonFlag
= 0x01,
109 eRightButtonFlag
= 0x02,
110 eMiddleButtonFlag
= 0x04,
111 // typicall, "back" button being left side of 5-button
112 // mice, see "buttons" attribute document of DOM3 Events.
113 e4thButtonFlag
= 0x08,
114 // typicall, "forward" button being right side of 5-button
115 // mice, see "buttons" attribute document of DOM3 Events.
116 e5thButtonFlag
= 0x10
119 // Flags of all pressed buttons at the event fired.
120 // This is set at any mouse event, don't be confused with |button|.
123 // Finger or touch pressure of event. It ranges between 0.0 and 1.0.
126 // Possible values at nsIDOMMouseEvent
127 uint16_t inputSource
;
129 void AssignMouseEventBaseData(const WidgetMouseEventBase
& aEvent
,
132 AssignInputEventData(aEvent
, aCopyTargets
);
134 relatedTarget
= aCopyTargets
? aEvent
.relatedTarget
: nullptr;
135 button
= aEvent
.button
;
136 buttons
= aEvent
.buttons
;
137 pressure
= aEvent
.pressure
;
138 inputSource
= aEvent
.inputSource
;
142 * Returns true if left click event.
144 bool IsLeftClickEvent() const
146 return message
== NS_MOUSE_CLICK
&& button
== eLeftButton
;
150 /******************************************************************************
151 * mozilla::WidgetMouseEvent
152 ******************************************************************************/
154 class WidgetMouseEvent
: public WidgetMouseEventBase
, public WidgetPointerHelper
157 friend class mozilla::dom::PBrowserParent
;
158 friend class mozilla::dom::PBrowserChild
;
184 WidgetMouseEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
185 nsEventStructType aStructType
, reasonType aReason
) :
186 WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, aStructType
),
187 acceptActivation(false), ignoreRootScrollFrame(false),
188 reason(aReason
), context(eNormal
), exit(eChild
), clickCount(0)
192 mFlags
.mCancelable
= false;
196 mFlags
.mBubbles
= false;
197 mFlags
.mCancelable
= false;
205 virtual WidgetMouseEvent
* AsMouseEvent() MOZ_OVERRIDE
{ return this; }
207 WidgetMouseEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
,
208 reasonType aReason
, contextType aContext
= eNormal
) :
209 WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, NS_MOUSE_EVENT
),
210 acceptActivation(false), ignoreRootScrollFrame(false),
211 reason(aReason
), context(aContext
), exit(eChild
), clickCount(0)
215 mFlags
.mCancelable
= false;
219 mFlags
.mBubbles
= false;
220 mFlags
.mCancelable
= false;
223 button
= (context
== eNormal
) ? eRightButton
: eLeftButton
;
231 virtual ~WidgetMouseEvent()
233 NS_WARN_IF_FALSE(message
!= NS_CONTEXTMENU
||
235 ((context
== eNormal
) ? eRightButton
: eLeftButton
),
236 "Wrong button set to NS_CONTEXTMENU event?");
240 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
242 MOZ_ASSERT(eventStructType
== NS_MOUSE_EVENT
,
243 "Duplicate() must be overridden by sub class");
244 // Not copying widget, it is a weak reference.
245 WidgetMouseEvent
* result
=
246 new WidgetMouseEvent(false, message
, nullptr, reason
, context
);
247 result
->AssignMouseEventData(*this, true);
248 result
->mFlags
= mFlags
;
252 // Special return code for MOUSE_ACTIVATE to signal.
253 // If the target accepts activation (1), or denies it (0).
254 bool acceptActivation
;
255 // Whether the event should ignore scroll frame bounds during dispatch.
256 bool ignoreRootScrollFrame
;
258 reasonType reason
: 4;
259 contextType context
: 4;
262 /// The number of mouse clicks.
265 void AssignMouseEventData(const WidgetMouseEvent
& aEvent
, bool aCopyTargets
)
267 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
268 AssignPointerHelperData(aEvent
);
270 acceptActivation
= aEvent
.acceptActivation
;
271 ignoreRootScrollFrame
= aEvent
.ignoreRootScrollFrame
;
272 clickCount
= aEvent
.clickCount
;
276 * Returns true if the event is a context menu event caused by key.
278 bool IsContextMenuKeyEvent() const
280 return message
== NS_CONTEXTMENU
&& context
== eContextMenuKey
;
284 * Returns true if the event is a real mouse event. Otherwise, i.e., it's
285 * a synthesized event by scroll or something, returns false.
289 return reason
== eReal
;
293 /******************************************************************************
294 * mozilla::WidgetDragEvent
295 ******************************************************************************/
297 class WidgetDragEvent
: public WidgetMouseEvent
300 virtual WidgetDragEvent
* AsDragEvent() MOZ_OVERRIDE
{ return this; }
302 WidgetDragEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
) :
303 WidgetMouseEvent(aIsTrusted
, aMessage
, aWidget
, NS_DRAG_EVENT
, eReal
),
304 userCancelled(false), mDefaultPreventedOnContent(false)
307 (aMessage
!= NS_DRAGDROP_EXIT_SYNTH
&&
308 aMessage
!= NS_DRAGDROP_LEAVE_SYNTH
&&
309 aMessage
!= NS_DRAGDROP_END
);
312 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
314 MOZ_ASSERT(eventStructType
== NS_DRAG_EVENT
,
315 "Duplicate() must be overridden by sub class");
316 // Not copying widget, it is a weak reference.
317 WidgetDragEvent
* result
= new WidgetDragEvent(false, message
, nullptr);
318 result
->AssignDragEventData(*this, true);
319 result
->mFlags
= mFlags
;
323 // The dragging data.
324 nsCOMPtr
<dom::DataTransfer
> dataTransfer
;
326 // If this is true, user has cancelled the drag operation.
328 // If this is true, the drag event's preventDefault() is called on content.
329 bool mDefaultPreventedOnContent
;
331 // XXX Not tested by test_assign_event_data.html
332 void AssignDragEventData(const WidgetDragEvent
& aEvent
, bool aCopyTargets
)
334 AssignMouseEventData(aEvent
, aCopyTargets
);
336 dataTransfer
= aEvent
.dataTransfer
;
337 // XXX userCancelled isn't copied, is this instentionally?
338 userCancelled
= false;
339 mDefaultPreventedOnContent
= aEvent
.mDefaultPreventedOnContent
;
343 /******************************************************************************
344 * mozilla::WidgetMouseScrollEvent
346 * This is used for legacy DOM mouse scroll events, i.e.,
347 * DOMMouseScroll and MozMousePixelScroll event. These events are NOT hanbled
348 * by ESM even if widget dispatches them. Use new WidgetWheelEvent instead.
349 ******************************************************************************/
351 class WidgetMouseScrollEvent
: public WidgetMouseEventBase
354 WidgetMouseScrollEvent()
359 virtual WidgetMouseScrollEvent
* AsMouseScrollEvent() MOZ_OVERRIDE
364 WidgetMouseScrollEvent(bool aIsTrusted
, uint32_t aMessage
,
365 nsIWidget
* aWidget
) :
366 WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, NS_MOUSE_SCROLL_EVENT
),
367 delta(0), isHorizontal(false)
371 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
373 MOZ_ASSERT(eventStructType
== NS_MOUSE_SCROLL_EVENT
,
374 "Duplicate() must be overridden by sub class");
375 // Not copying widget, it is a weak reference.
376 WidgetMouseScrollEvent
* result
=
377 new WidgetMouseScrollEvent(false, message
, nullptr);
378 result
->AssignMouseScrollEventData(*this, true);
379 result
->mFlags
= mFlags
;
383 // The delta value of mouse scroll event.
384 // If the event message is NS_MOUSE_SCROLL, the value indicates scroll amount
385 // in lines. However, if the value is nsIDOMUIEvent::SCROLL_PAGE_UP or
386 // nsIDOMUIEvent::SCROLL_PAGE_DOWN, the value inducates one page scroll.
387 // If the event message is NS_MOUSE_PIXEL_SCROLL, the value indicates scroll
391 // If this is true, it may cause to scroll horizontally.
392 // Otherwise, vertically.
395 void AssignMouseScrollEventData(const WidgetMouseScrollEvent
& aEvent
,
398 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
400 delta
= aEvent
.delta
;
401 isHorizontal
= aEvent
.isHorizontal
;
405 /******************************************************************************
406 * mozilla::WidgetWheelEvent
407 ******************************************************************************/
409 class WidgetWheelEvent
: public WidgetMouseEventBase
412 friend class mozilla::dom::PBrowserParent
;
413 friend class mozilla::dom::PBrowserChild
;
420 virtual WidgetWheelEvent
* AsWheelEvent() MOZ_OVERRIDE
{ return this; }
422 WidgetWheelEvent(bool aIsTrusted
, uint32_t aMessage
, nsIWidget
* aWidget
) :
423 WidgetMouseEventBase(aIsTrusted
, aMessage
, aWidget
, NS_WHEEL_EVENT
),
424 deltaX(0.0), deltaY(0.0), deltaZ(0.0),
425 deltaMode(nsIDOMWheelEvent::DOM_DELTA_PIXEL
),
426 customizedByUserPrefs(false), isMomentum(false), isPixelOnlyDevice(false),
427 lineOrPageDeltaX(0), lineOrPageDeltaY(0), scrollType(SCROLL_DEFAULT
),
428 overflowDeltaX(0.0), overflowDeltaY(0.0),
429 mViewPortIsOverscrolled(false)
433 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
435 MOZ_ASSERT(eventStructType
== NS_WHEEL_EVENT
,
436 "Duplicate() must be overridden by sub class");
437 // Not copying widget, it is a weak reference.
438 WidgetWheelEvent
* result
= new WidgetWheelEvent(false, message
, nullptr);
439 result
->AssignWheelEventData(*this, true);
440 result
->mFlags
= mFlags
;
444 // NOTE: deltaX, deltaY and deltaZ may be customized by
445 // mousewheel.*.delta_multiplier_* prefs which are applied by
446 // EventStateManager. So, after widget dispatches this event,
447 // these delta values may have different values than before.
452 // Should be one of nsIDOMWheelEvent::DOM_DELTA_*
455 // Following members are for internal use only, not for DOM event.
457 // If the delta values are computed from prefs, this value is true.
458 // Otherwise, i.e., they are computed from native events, false.
459 bool customizedByUserPrefs
;
461 // true if the event is caused by momentum.
464 // If device event handlers don't know when they should set lineOrPageDeltaX
465 // and lineOrPageDeltaY, this is true. Otherwise, false.
466 // If isPixelOnlyDevice is true, ESM will generate NS_MOUSE_SCROLL events
467 // when accumulated pixel delta values reach a line height.
468 bool isPixelOnlyDevice
;
470 // If widget sets lineOrPageDelta, EventStateManager will dispatch
471 // NS_MOUSE_SCROLL event for compatibility. Note that the delta value means
472 // pages if the deltaMode is DOM_DELTA_PAGE, otherwise, lines.
473 int32_t lineOrPageDeltaX
;
474 int32_t lineOrPageDeltaY
;
476 // When the default action for an wheel event is moving history or zooming,
477 // need to chose a delta value for doing it.
478 int32_t GetPreferredIntDelta()
480 if (!lineOrPageDeltaX
&& !lineOrPageDeltaY
) {
483 if (lineOrPageDeltaY
&& !lineOrPageDeltaX
) {
484 return lineOrPageDeltaY
;
486 if (lineOrPageDeltaX
&& !lineOrPageDeltaY
) {
487 return lineOrPageDeltaX
;
489 if ((lineOrPageDeltaX
< 0 && lineOrPageDeltaY
> 0) ||
490 (lineOrPageDeltaX
> 0 && lineOrPageDeltaY
< 0)) {
491 return 0; // We cannot guess the answer in this case.
493 return (Abs(lineOrPageDeltaX
) > Abs(lineOrPageDeltaY
)) ?
494 lineOrPageDeltaX
: lineOrPageDeltaY
;
498 // The default value is SCROLL_DEFAULT, which means EventStateManager will
499 // select preferred scroll type automatically.
503 SCROLL_SYNCHRONOUSLY
,
504 SCROLL_ASYNCHRONOUSELY
,
507 ScrollType scrollType
;
509 // overflowed delta values for scroll, these values are set by
510 // nsEventStateManger. If the default action of the wheel event isn't scroll,
511 // these values always zero. Otherwise, remaning delta values which are
512 // not used by scroll are set.
513 // NOTE: deltaX, deltaY and deltaZ may be modified by EventStateManager.
514 // However, overflowDeltaX and overflowDeltaY indicate unused original
515 // delta values which are not applied the delta_multiplier prefs.
516 // So, if widget wanted to know the actual direction to be scrolled,
517 // it would need to check the deltaX and deltaY.
518 double overflowDeltaX
;
519 double overflowDeltaY
;
521 // Whether or not the parent of the currently overscrolled frame is the
522 // ViewPort. This is false in situations when an element on the page is being
523 // overscrolled (such as a text field), but true when the 'page' is being
525 bool mViewPortIsOverscrolled
;
527 void AssignWheelEventData(const WidgetWheelEvent
& aEvent
, bool aCopyTargets
)
529 AssignMouseEventBaseData(aEvent
, aCopyTargets
);
531 deltaX
= aEvent
.deltaX
;
532 deltaY
= aEvent
.deltaY
;
533 deltaZ
= aEvent
.deltaZ
;
534 deltaMode
= aEvent
.deltaMode
;
535 customizedByUserPrefs
= aEvent
.customizedByUserPrefs
;
536 isMomentum
= aEvent
.isMomentum
;
537 isPixelOnlyDevice
= aEvent
.isPixelOnlyDevice
;
538 lineOrPageDeltaX
= aEvent
.lineOrPageDeltaX
;
539 lineOrPageDeltaY
= aEvent
.lineOrPageDeltaY
;
540 scrollType
= aEvent
.scrollType
;
541 overflowDeltaX
= aEvent
.overflowDeltaX
;
542 overflowDeltaY
= aEvent
.overflowDeltaY
;
543 mViewPortIsOverscrolled
= aEvent
.mViewPortIsOverscrolled
;
547 /******************************************************************************
548 * mozilla::WidgetPointerEvent
549 ******************************************************************************/
551 class WidgetPointerEvent
: public WidgetMouseEvent
553 friend class mozilla::dom::PBrowserParent
;
554 friend class mozilla::dom::PBrowserChild
;
561 virtual WidgetPointerEvent
* AsPointerEvent() MOZ_OVERRIDE
{ return this; }
563 WidgetPointerEvent(bool aIsTrusted
, uint32_t aMsg
, nsIWidget
* w
)
564 : WidgetMouseEvent(aIsTrusted
, aMsg
, w
, NS_POINTER_EVENT
, eReal
)
572 WidgetPointerEvent(const WidgetMouseEvent
& aEvent
)
573 : WidgetMouseEvent(aEvent
)
578 eventStructType
= NS_POINTER_EVENT
;
585 case NS_POINTER_ENTER
:
586 case NS_POINTER_LEAVE
:
587 mFlags
.mBubbles
= false;
588 mFlags
.mCancelable
= false;
590 case NS_POINTER_CANCEL
:
591 case NS_POINTER_GOT_CAPTURE
:
592 case NS_POINTER_LOST_CAPTURE
:
593 mFlags
.mCancelable
= false;
600 virtual WidgetEvent
* Duplicate() const MOZ_OVERRIDE
602 MOZ_ASSERT(eventStructType
== NS_POINTER_EVENT
,
603 "Duplicate() must be overridden by sub class");
604 // Not copying widget, it is a weak reference.
605 WidgetPointerEvent
* result
=
606 new WidgetPointerEvent(false, message
, nullptr);
607 result
->AssignPointerEventData(*this, true);
608 result
->mFlags
= mFlags
;
616 // XXX Not tested by test_assign_event_data.html
617 void AssignPointerEventData(const WidgetPointerEvent
& aEvent
,
620 AssignMouseEventData(aEvent
, aCopyTargets
);
622 width
= aEvent
.width
;
623 height
= aEvent
.height
;
624 isPrimary
= aEvent
.isPrimary
;
628 } // namespace mozilla
630 #endif // mozilla_MouseEvents_h__