Bug 1652470 [wpt PR 24579] - Update mozrunner to 8.0.0, a=testonly
[gecko.git] / widget / InputData.cpp
blob3a9c533f2dcba3d219422495c775de0940cc97ad
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 #include "InputData.h"
8 #include "mozilla/dom/MouseEventBinding.h"
9 #include "mozilla/dom/Touch.h"
10 #include "mozilla/dom/WheelEventBinding.h"
11 #include "mozilla/TextEvents.h"
12 #include "nsContentUtils.h"
13 #include "nsDebug.h"
14 #include "nsThreadUtils.h"
15 #include "mozilla/MouseEvents.h"
16 #include "mozilla/TouchEvents.h"
17 #include "UnitTransforms.h"
19 namespace mozilla {
21 using namespace dom;
23 InputData::~InputData() = default;
25 InputData::InputData(InputType aInputType)
26 : mInputType(aInputType),
27 mTime(0),
28 mFocusSequenceNumber(0),
29 mLayersId{0},
30 modifiers(0) {}
32 InputData::InputData(InputType aInputType, uint32_t aTime, TimeStamp aTimeStamp,
33 Modifiers aModifiers)
34 : mInputType(aInputType),
35 mTime(aTime),
36 mTimeStamp(aTimeStamp),
37 mFocusSequenceNumber(0),
38 mLayersId{0},
39 modifiers(aModifiers) {}
41 SingleTouchData::SingleTouchData(int32_t aIdentifier,
42 ScreenIntPoint aScreenPoint,
43 ScreenSize aRadius, float aRotationAngle,
44 float aForce)
45 : mIdentifier(aIdentifier),
46 mScreenPoint(aScreenPoint),
47 mRadius(aRadius),
48 mRotationAngle(aRotationAngle),
49 mForce(aForce) {}
51 SingleTouchData::SingleTouchData(int32_t aIdentifier,
52 ParentLayerPoint aLocalScreenPoint,
53 ScreenSize aRadius, float aRotationAngle,
54 float aForce)
55 : mIdentifier(aIdentifier),
56 mLocalScreenPoint(aLocalScreenPoint),
57 mRadius(aRadius),
58 mRotationAngle(aRotationAngle),
59 mForce(aForce) {}
61 SingleTouchData::SingleTouchData()
62 : mIdentifier(0), mRotationAngle(0.0), mForce(0.0) {}
64 already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const {
65 MOZ_ASSERT(NS_IsMainThread(),
66 "Can only create dom::Touch instances on main thread");
67 RefPtr<Touch> touch =
68 new Touch(mIdentifier,
69 LayoutDeviceIntPoint::Truncate(mScreenPoint.x, mScreenPoint.y),
70 LayoutDeviceIntPoint::Truncate(mRadius.width, mRadius.height),
71 mRotationAngle, mForce);
72 return touch.forget();
75 MultiTouchInput::MultiTouchInput(MultiTouchType aType, uint32_t aTime,
76 TimeStamp aTimeStamp, Modifiers aModifiers)
77 : InputData(MULTITOUCH_INPUT, aTime, aTimeStamp, aModifiers),
78 mType(aType),
79 mHandledByAPZ(false) {}
81 MultiTouchInput::MultiTouchInput()
82 : InputData(MULTITOUCH_INPUT),
83 mType(MULTITOUCH_START),
84 mHandledByAPZ(false) {}
86 MultiTouchInput::MultiTouchInput(const MultiTouchInput& aOther)
87 : InputData(MULTITOUCH_INPUT, aOther.mTime, aOther.mTimeStamp,
88 aOther.modifiers),
89 mType(aOther.mType),
90 mScreenOffset(aOther.mScreenOffset),
91 mHandledByAPZ(aOther.mHandledByAPZ) {
92 mTouches.AppendElements(aOther.mTouches);
95 MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
96 : InputData(MULTITOUCH_INPUT, aTouchEvent.mTime, aTouchEvent.mTimeStamp,
97 aTouchEvent.mModifiers),
98 mHandledByAPZ(aTouchEvent.mFlags.mHandledByAPZ) {
99 MOZ_ASSERT(NS_IsMainThread(),
100 "Can only copy from WidgetTouchEvent on main thread");
102 switch (aTouchEvent.mMessage) {
103 case eTouchStart:
104 mType = MULTITOUCH_START;
105 break;
106 case eTouchMove:
107 mType = MULTITOUCH_MOVE;
108 break;
109 case eTouchEnd:
110 mType = MULTITOUCH_END;
111 break;
112 case eTouchCancel:
113 mType = MULTITOUCH_CANCEL;
114 break;
115 default:
116 MOZ_ASSERT_UNREACHABLE("Did not assign a type to a MultiTouchInput");
117 break;
120 mScreenOffset = ViewAs<ExternalPixel>(
121 aTouchEvent.mWidget->WidgetToScreenOffset(),
122 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent);
124 for (size_t i = 0; i < aTouchEvent.mTouches.Length(); i++) {
125 const Touch* domTouch = aTouchEvent.mTouches[i];
127 // Extract data from weird interfaces.
128 int32_t identifier = domTouch->Identifier();
129 int32_t radiusX = domTouch->RadiusX(CallerType::System);
130 int32_t radiusY = domTouch->RadiusY(CallerType::System);
131 float rotationAngle = domTouch->RotationAngle(CallerType::System);
132 float force = domTouch->Force(CallerType::System);
134 SingleTouchData data(
135 identifier,
136 ViewAs<ScreenPixel>(
137 domTouch->mRefPoint,
138 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
139 ScreenSize(radiusX, radiusY), rotationAngle, force);
141 mTouches.AppendElement(data);
145 void MultiTouchInput::Translate(const ScreenPoint& aTranslation) {
146 const int32_t xTranslation = (int32_t)(aTranslation.x + 0.5f);
147 const int32_t yTranslation = (int32_t)(aTranslation.y + 0.5f);
149 for (auto iter = mTouches.begin(); iter != mTouches.end(); iter++) {
150 iter->mScreenPoint.MoveBy(xTranslation, yTranslation);
154 WidgetTouchEvent MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const {
155 MOZ_ASSERT(NS_IsMainThread(),
156 "Can only convert To WidgetTouchEvent on main thread");
158 EventMessage touchEventMessage = eVoidEvent;
159 switch (mType) {
160 case MULTITOUCH_START:
161 touchEventMessage = eTouchStart;
162 break;
163 case MULTITOUCH_MOVE:
164 touchEventMessage = eTouchMove;
165 break;
166 case MULTITOUCH_END:
167 touchEventMessage = eTouchEnd;
168 break;
169 case MULTITOUCH_CANCEL:
170 touchEventMessage = eTouchCancel;
171 break;
172 default:
173 MOZ_ASSERT_UNREACHABLE(
174 "Did not assign a type to WidgetTouchEvent in MultiTouchInput");
175 break;
178 WidgetTouchEvent event(true, touchEventMessage, aWidget);
179 if (touchEventMessage == eVoidEvent) {
180 return event;
183 event.mModifiers = this->modifiers;
184 event.mTime = this->mTime;
185 event.mTimeStamp = this->mTimeStamp;
186 event.mFlags.mHandledByAPZ = mHandledByAPZ;
187 event.mFocusSequenceNumber = mFocusSequenceNumber;
188 event.mLayersId = mLayersId;
190 for (size_t i = 0; i < mTouches.Length(); i++) {
191 *event.mTouches.AppendElement() = mTouches[i].ToNewDOMTouch();
194 return event;
197 int32_t MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier) {
198 for (size_t i = 0; i < mTouches.Length(); i++) {
199 if (mTouches[i].mIdentifier == aTouchIdentifier) {
200 return (int32_t)i;
203 return -1;
206 bool MultiTouchInput::TransformToLocal(
207 const ScreenToParentLayerMatrix4x4& aTransform) {
208 for (size_t i = 0; i < mTouches.Length(); i++) {
209 Maybe<ParentLayerIntPoint> point =
210 UntransformBy(aTransform, mTouches[i].mScreenPoint);
211 if (!point) {
212 return false;
214 mTouches[i].mLocalScreenPoint = *point;
216 return true;
219 MouseInput::MouseInput()
220 : InputData(MOUSE_INPUT),
221 mType(MOUSE_NONE),
222 mButtonType(NONE),
223 mInputSource(0),
224 mButtons(0),
225 mHandledByAPZ(false) {}
227 MouseInput::MouseInput(MouseType aType, ButtonType aButtonType,
228 uint16_t aInputSource, int16_t aButtons,
229 const ScreenPoint& aPoint, uint32_t aTime,
230 TimeStamp aTimeStamp, Modifiers aModifiers)
231 : InputData(MOUSE_INPUT, aTime, aTimeStamp, aModifiers),
232 mType(aType),
233 mButtonType(aButtonType),
234 mInputSource(aInputSource),
235 mButtons(aButtons),
236 mOrigin(aPoint),
237 mHandledByAPZ(false) {}
239 MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent)
240 : InputData(MOUSE_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
241 aMouseEvent.mModifiers),
242 mType(MOUSE_NONE),
243 mButtonType(NONE),
244 mInputSource(aMouseEvent.mInputSource),
245 mButtons(aMouseEvent.mButtons),
246 mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ) {
247 MOZ_ASSERT(NS_IsMainThread(),
248 "Can only copy from WidgetTouchEvent on main thread");
250 mButtonType = NONE;
252 switch (aMouseEvent.mButton) {
253 case MouseButton::ePrimary:
254 mButtonType = MouseInput::PRIMARY_BUTTON;
255 break;
256 case MouseButton::eMiddle:
257 mButtonType = MouseInput::MIDDLE_BUTTON;
258 break;
259 case MouseButton::eSecondary:
260 mButtonType = MouseInput::SECONDARY_BUTTON;
261 break;
264 switch (aMouseEvent.mMessage) {
265 case eMouseMove:
266 mType = MOUSE_MOVE;
267 break;
268 case eMouseUp:
269 mType = MOUSE_UP;
270 break;
271 case eMouseDown:
272 mType = MOUSE_DOWN;
273 break;
274 case eDragStart:
275 mType = MOUSE_DRAG_START;
276 break;
277 case eDragEnd:
278 mType = MOUSE_DRAG_END;
279 break;
280 case eMouseEnterIntoWidget:
281 mType = MOUSE_WIDGET_ENTER;
282 break;
283 case eMouseExitFromWidget:
284 mType = MOUSE_WIDGET_EXIT;
285 break;
286 case eMouseHitTest:
287 mType = MOUSE_HITTEST;
288 break;
289 default:
290 MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
291 break;
294 mOrigin = ScreenPoint(ViewAs<ScreenPixel>(
295 aMouseEvent.mRefPoint,
296 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
299 bool MouseInput::IsLeftButton() const { return mButtonType == PRIMARY_BUTTON; }
301 bool MouseInput::TransformToLocal(
302 const ScreenToParentLayerMatrix4x4& aTransform) {
303 Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
304 if (!point) {
305 return false;
307 mLocalOrigin = *point;
309 return true;
312 WidgetMouseEvent MouseInput::ToWidgetMouseEvent(nsIWidget* aWidget) const {
313 MOZ_ASSERT(NS_IsMainThread(),
314 "Can only convert To WidgetTouchEvent on main thread");
316 EventMessage msg = eVoidEvent;
317 uint32_t clickCount = 0;
318 switch (mType) {
319 case MOUSE_MOVE:
320 msg = eMouseMove;
321 break;
322 case MOUSE_UP:
323 msg = eMouseUp;
324 clickCount = 1;
325 break;
326 case MOUSE_DOWN:
327 msg = eMouseDown;
328 clickCount = 1;
329 break;
330 case MOUSE_DRAG_START:
331 msg = eDragStart;
332 break;
333 case MOUSE_DRAG_END:
334 msg = eDragEnd;
335 break;
336 case MOUSE_WIDGET_ENTER:
337 msg = eMouseEnterIntoWidget;
338 break;
339 case MOUSE_WIDGET_EXIT:
340 msg = eMouseExitFromWidget;
341 break;
342 case MOUSE_HITTEST:
343 msg = eMouseHitTest;
344 break;
345 default:
346 MOZ_ASSERT_UNREACHABLE(
347 "Did not assign a type to WidgetMouseEvent in MouseInput");
348 break;
351 WidgetMouseEvent event(true, msg, aWidget, WidgetMouseEvent::eReal,
352 WidgetMouseEvent::eNormal);
354 if (msg == eVoidEvent) {
355 return event;
358 switch (mButtonType) {
359 case MouseInput::PRIMARY_BUTTON:
360 event.mButton = MouseButton::ePrimary;
361 break;
362 case MouseInput::MIDDLE_BUTTON:
363 event.mButton = MouseButton::eMiddle;
364 break;
365 case MouseInput::SECONDARY_BUTTON:
366 event.mButton = MouseButton::eSecondary;
367 break;
368 case MouseInput::NONE:
369 default:
370 break;
373 event.mButtons = mButtons;
374 event.mModifiers = modifiers;
375 event.mTime = mTime;
376 event.mTimeStamp = mTimeStamp;
377 event.mFlags.mHandledByAPZ = mHandledByAPZ;
378 event.mRefPoint = RoundedToInt(ViewAs<LayoutDevicePixel>(
379 mOrigin,
380 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
381 event.mClickCount = clickCount;
382 event.mInputSource = mInputSource;
383 event.mFocusSequenceNumber = mFocusSequenceNumber;
385 return event;
388 PanGestureInput::PanGestureInput()
389 : InputData(PANGESTURE_INPUT),
390 mType(PANGESTURE_MAYSTART),
391 mLineOrPageDeltaX(0),
392 mLineOrPageDeltaY(0),
393 mUserDeltaMultiplierX(1.0),
394 mUserDeltaMultiplierY(1.0),
395 mHandledByAPZ(false),
396 mFollowedByMomentum(false),
397 mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false),
398 mOverscrollBehaviorAllowsSwipe(false),
399 mSimulateMomentum(false) {}
401 PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime,
402 TimeStamp aTimeStamp,
403 const ScreenPoint& aPanStartPoint,
404 const ScreenPoint& aPanDisplacement,
405 Modifiers aModifiers)
406 : InputData(PANGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
407 mType(aType),
408 mPanStartPoint(aPanStartPoint),
409 mPanDisplacement(aPanDisplacement),
410 mLineOrPageDeltaX(0),
411 mLineOrPageDeltaY(0),
412 mUserDeltaMultiplierX(1.0),
413 mUserDeltaMultiplierY(1.0),
414 mHandledByAPZ(false),
415 mFollowedByMomentum(false),
416 mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false),
417 mOverscrollBehaviorAllowsSwipe(false),
418 mSimulateMomentum(false) {}
420 bool PanGestureInput::IsMomentum() const {
421 switch (mType) {
422 case PanGestureInput::PANGESTURE_MOMENTUMSTART:
423 case PanGestureInput::PANGESTURE_MOMENTUMPAN:
424 case PanGestureInput::PANGESTURE_MOMENTUMEND:
425 return true;
426 default:
427 return false;
431 WidgetWheelEvent PanGestureInput::ToWidgetWheelEvent(nsIWidget* aWidget) const {
432 WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
433 wheelEvent.mModifiers = this->modifiers;
434 wheelEvent.mTime = mTime;
435 wheelEvent.mTimeStamp = mTimeStamp;
436 wheelEvent.mRefPoint = RoundedToInt(ViewAs<LayoutDevicePixel>(
437 mPanStartPoint,
438 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
439 wheelEvent.mButtons = 0;
440 wheelEvent.mMayHaveMomentum = true; // pan inputs may have momentum
441 wheelEvent.mIsMomentum = IsMomentum();
442 wheelEvent.mLineOrPageDeltaX = mLineOrPageDeltaX;
443 wheelEvent.mLineOrPageDeltaY = mLineOrPageDeltaY;
444 wheelEvent.mDeltaX = mPanDisplacement.x;
445 wheelEvent.mDeltaY = mPanDisplacement.y;
446 wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
447 wheelEvent.mFocusSequenceNumber = mFocusSequenceNumber;
448 if (mDeltaType == PanGestureInput::PANDELTA_PAGE) {
449 // Emulate legacy widget/gtk behavior
450 wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_LINE;
451 wheelEvent.mIsNoLineOrPageDelta = true;
452 wheelEvent.mScrollType = WidgetWheelEvent::SCROLL_ASYNCHRONOUSELY;
453 wheelEvent.mDeltaX *= 3;
454 wheelEvent.mDeltaY *= 3;
455 } else {
456 wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL;
458 return wheelEvent;
461 bool PanGestureInput::TransformToLocal(
462 const ScreenToParentLayerMatrix4x4& aTransform) {
463 Maybe<ParentLayerPoint> panStartPoint =
464 UntransformBy(aTransform, mPanStartPoint);
465 if (!panStartPoint) {
466 return false;
468 mLocalPanStartPoint = *panStartPoint;
470 if (mDeltaType == PanGestureInput::PANDELTA_PAGE) {
471 // Skip transforming the pan displacement because we want
472 // raw page proportion counts.
473 mLocalPanDisplacement.x = mPanDisplacement.x;
474 mLocalPanDisplacement.y = mPanDisplacement.y;
475 return true;
478 Maybe<ParentLayerPoint> panDisplacement =
479 UntransformVector(aTransform, mPanDisplacement, mPanStartPoint);
480 if (!panDisplacement) {
481 return false;
483 mLocalPanDisplacement = *panDisplacement;
484 return true;
487 ScreenPoint PanGestureInput::UserMultipliedPanDisplacement() const {
488 return ScreenPoint(mPanDisplacement.x * mUserDeltaMultiplierX,
489 mPanDisplacement.y * mUserDeltaMultiplierY);
492 ParentLayerPoint PanGestureInput::UserMultipliedLocalPanDisplacement() const {
493 return ParentLayerPoint(mLocalPanDisplacement.x * mUserDeltaMultiplierX,
494 mLocalPanDisplacement.y * mUserDeltaMultiplierY);
497 PinchGestureInput::PinchGestureInput()
498 : InputData(PINCHGESTURE_INPUT),
499 mType(PINCHGESTURE_START),
500 mSource(UNKNOWN),
501 mHandledByAPZ(false) {}
503 PinchGestureInput::PinchGestureInput(
504 PinchGestureType aType, PinchGestureSource aSource, uint32_t aTime,
505 TimeStamp aTimeStamp, const ExternalPoint& aScreenOffset,
506 const ScreenPoint& aFocusPoint, ScreenCoord aCurrentSpan,
507 ScreenCoord aPreviousSpan, Modifiers aModifiers)
508 : InputData(PINCHGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
509 mType(aType),
510 mSource(aSource),
511 mFocusPoint(aFocusPoint),
512 mScreenOffset(aScreenOffset),
513 mCurrentSpan(aCurrentSpan),
514 mPreviousSpan(aPreviousSpan),
515 mHandledByAPZ(false) {}
517 bool PinchGestureInput::TransformToLocal(
518 const ScreenToParentLayerMatrix4x4& aTransform) {
519 Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mFocusPoint);
520 if (!point) {
521 return false;
523 mLocalFocusPoint = *point;
524 return true;
527 WidgetWheelEvent PinchGestureInput::ToWidgetWheelEvent(
528 nsIWidget* aWidget) const {
529 WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
530 wheelEvent.mModifiers = this->modifiers | MODIFIER_CONTROL;
531 wheelEvent.mTime = mTime;
532 wheelEvent.mTimeStamp = mTimeStamp;
533 wheelEvent.mRefPoint = RoundedToInt(ViewAs<LayoutDevicePixel>(
534 mFocusPoint,
535 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
536 wheelEvent.mButtons = 0;
537 wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
538 wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL;
540 #if defined(OS_MACOSX)
541 // This converts the pinch gesture value to a fake wheel event that has the
542 // control key pressed so that pages can implement custom pinch gesture
543 // handling. It may seem strange that this doesn't use a wheel event with
544 // the deltaZ property set, but this matches Chrome's behavior as described
545 // at https://code.google.com/p/chromium/issues/detail?id=289887
547 // The intent of the formula below is to produce numbers similar to Chrome's
548 // implementation of this feature. Chrome implements deltaY using the formula
549 // "-100 * log(1 + [event magnification])" which is unfortunately incorrect.
550 // All deltas for a single pinch gesture should sum to 0 if the start and end
551 // of a pinch gesture end up in the same place. This doesn't happen in Chrome
552 // because they followed Apple's misleading documentation, which implies that
553 // "1 + [event magnification]" is the scale factor. The scale factor is
554 // instead "pow(ratio, [event magnification])" so "[event magnification]" is
555 // already in log space.
557 // The multiplication by the backing scale factor below counteracts the
558 // division by the backing scale factor in WheelEvent.
560 // We want to set deltaY to |-100.0 * M * GetDefaultScaleInternal()| where M
561 // is [event magnification] but [event magnification] is only available in the
562 // macOS widget code so we have to reverse engineer from mCurrentSpan and
563 // mPreviousSpan (which are derived from [event magnification]) to get it.
564 // Specifically, we know |mCurrentSpan == 100.0| and |mPreviousSpan == 100.0 *
565 // (1.0 - M)|. We can calculate deltaY by solving the mPreviousSpan equation
566 // for M in terms of mPreviousSpan and plugging that into to the formula for
567 // deltaY.
568 wheelEvent.mDeltaY = (mPreviousSpan - 100.0) *
569 (aWidget ? aWidget->GetDefaultScaleInternal() : 1.f);
570 #else
571 // This calculation is based on what the Windows widget code does.
572 // Specifically, it creates a PinchGestureInput with |mCurrentSpan == 100.0 *
573 // currentScale| and |mPreviousSpan == 100.0 * lastScale| where currentScale
574 // is the scale from the current OS event and lastScale is the scale when the
575 // previous OS event happened. On macOS [event magnification] is a relative
576 // change in scale factor, ie if the scale factor changed from 1 to 1.1 it
577 // will be 0.1, similarly if it changed from 1 to 0.9 it will be -0.1. To
578 // calculate the relative scale change on Windows we would calculate |M =
579 // currentScale - lastScale = (mCurrentSpan-mPreviousSpan)/100| and use the
580 // same formula as the macOS code
581 // (|-100.0 * M * GetDefaultScaleInternal()|).
583 // XXX When we write the code for other platforms to do the same we'll need to
584 // make sure this calculation is reasonable.
586 wheelEvent.mDeltaY = (mPreviousSpan - mCurrentSpan) *
587 (aWidget ? aWidget->GetDefaultScaleInternal() : 1.f);
588 #endif
590 MOZ_ASSERT(mType == PINCHGESTURE_END || wheelEvent.mDeltaY != 0.0);
592 return wheelEvent;
595 TapGestureInput::TapGestureInput()
596 : InputData(TAPGESTURE_INPUT), mType(TAPGESTURE_LONG) {}
598 TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime,
599 TimeStamp aTimeStamp,
600 const ScreenIntPoint& aPoint,
601 Modifiers aModifiers)
602 : InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
603 mType(aType),
604 mPoint(aPoint) {}
606 TapGestureInput::TapGestureInput(TapGestureType aType, uint32_t aTime,
607 TimeStamp aTimeStamp,
608 const ParentLayerPoint& aLocalPoint,
609 Modifiers aModifiers)
610 : InputData(TAPGESTURE_INPUT, aTime, aTimeStamp, aModifiers),
611 mType(aType),
612 mLocalPoint(aLocalPoint) {}
614 bool TapGestureInput::TransformToLocal(
615 const ScreenToParentLayerMatrix4x4& aTransform) {
616 Maybe<ParentLayerIntPoint> point = UntransformBy(aTransform, mPoint);
617 if (!point) {
618 return false;
620 mLocalPoint = *point;
621 return true;
624 ScrollWheelInput::ScrollWheelInput()
625 : InputData(SCROLLWHEEL_INPUT),
626 mDeltaType(SCROLLDELTA_LINE),
627 mScrollMode(SCROLLMODE_INSTANT),
628 mHandledByAPZ(false),
629 mDeltaX(0.0),
630 mDeltaY(0.0),
631 mLineOrPageDeltaX(0),
632 mLineOrPageDeltaY(0),
633 mScrollSeriesNumber(0),
634 mUserDeltaMultiplierX(1.0),
635 mUserDeltaMultiplierY(1.0),
636 mMayHaveMomentum(false),
637 mIsMomentum(false),
638 mAPZAction(APZWheelAction::Scroll) {}
640 ScrollWheelInput::ScrollWheelInput(
641 uint32_t aTime, TimeStamp aTimeStamp, Modifiers aModifiers,
642 ScrollMode aScrollMode, ScrollDeltaType aDeltaType,
643 const ScreenPoint& aOrigin, double aDeltaX, double aDeltaY,
644 bool aAllowToOverrideSystemScrollSpeed,
645 WheelDeltaAdjustmentStrategy aWheelDeltaAdjustmentStrategy)
646 : InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers),
647 mDeltaType(aDeltaType),
648 mScrollMode(aScrollMode),
649 mOrigin(aOrigin),
650 mHandledByAPZ(false),
651 mDeltaX(aDeltaX),
652 mDeltaY(aDeltaY),
653 mLineOrPageDeltaX(0),
654 mLineOrPageDeltaY(0),
655 mScrollSeriesNumber(0),
656 mUserDeltaMultiplierX(1.0),
657 mUserDeltaMultiplierY(1.0),
658 mMayHaveMomentum(false),
659 mIsMomentum(false),
660 mAllowToOverrideSystemScrollSpeed(aAllowToOverrideSystemScrollSpeed),
661 mWheelDeltaAdjustmentStrategy(aWheelDeltaAdjustmentStrategy),
662 mAPZAction(APZWheelAction::Scroll) {}
664 ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent)
665 : InputData(SCROLLWHEEL_INPUT, aWheelEvent.mTime, aWheelEvent.mTimeStamp,
666 aWheelEvent.mModifiers),
667 mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.mDeltaMode)),
668 mScrollMode(SCROLLMODE_INSTANT),
669 mHandledByAPZ(aWheelEvent.mFlags.mHandledByAPZ),
670 mDeltaX(aWheelEvent.mDeltaX),
671 mDeltaY(aWheelEvent.mDeltaY),
672 mLineOrPageDeltaX(aWheelEvent.mLineOrPageDeltaX),
673 mLineOrPageDeltaY(aWheelEvent.mLineOrPageDeltaY),
674 mScrollSeriesNumber(0),
675 mUserDeltaMultiplierX(1.0),
676 mUserDeltaMultiplierY(1.0),
677 mMayHaveMomentum(aWheelEvent.mMayHaveMomentum),
678 mIsMomentum(aWheelEvent.mIsMomentum),
679 mAllowToOverrideSystemScrollSpeed(
680 aWheelEvent.mAllowToOverrideSystemScrollSpeed),
681 mWheelDeltaAdjustmentStrategy(WheelDeltaAdjustmentStrategy::eNone),
682 mAPZAction(APZWheelAction::Scroll) {
683 mOrigin = ScreenPoint(ViewAs<ScreenPixel>(
684 aWheelEvent.mRefPoint,
685 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
688 ScrollWheelInput::ScrollDeltaType ScrollWheelInput::DeltaTypeForDeltaMode(
689 uint32_t aDeltaMode) {
690 switch (aDeltaMode) {
691 case WheelEvent_Binding::DOM_DELTA_LINE:
692 return SCROLLDELTA_LINE;
693 case WheelEvent_Binding::DOM_DELTA_PAGE:
694 return SCROLLDELTA_PAGE;
695 case WheelEvent_Binding::DOM_DELTA_PIXEL:
696 return SCROLLDELTA_PIXEL;
697 default:
698 MOZ_CRASH();
700 return SCROLLDELTA_LINE;
703 uint32_t ScrollWheelInput::DeltaModeForDeltaType(ScrollDeltaType aDeltaType) {
704 switch (aDeltaType) {
705 case ScrollWheelInput::SCROLLDELTA_LINE:
706 return WheelEvent_Binding::DOM_DELTA_LINE;
707 case ScrollWheelInput::SCROLLDELTA_PAGE:
708 return WheelEvent_Binding::DOM_DELTA_PAGE;
709 case ScrollWheelInput::SCROLLDELTA_PIXEL:
710 default:
711 return WheelEvent_Binding::DOM_DELTA_PIXEL;
715 ScrollUnit ScrollWheelInput::ScrollUnitForDeltaType(
716 ScrollDeltaType aDeltaType) {
717 switch (aDeltaType) {
718 case SCROLLDELTA_LINE:
719 return ScrollUnit::LINES;
720 case SCROLLDELTA_PAGE:
721 return ScrollUnit::PAGES;
722 case SCROLLDELTA_PIXEL:
723 return ScrollUnit::DEVICE_PIXELS;
724 default:
725 MOZ_CRASH();
727 return ScrollUnit::LINES;
730 WidgetWheelEvent ScrollWheelInput::ToWidgetWheelEvent(
731 nsIWidget* aWidget) const {
732 WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
733 wheelEvent.mModifiers = this->modifiers;
734 wheelEvent.mTime = mTime;
735 wheelEvent.mTimeStamp = mTimeStamp;
736 wheelEvent.mRefPoint = RoundedToInt(ViewAs<LayoutDevicePixel>(
737 mOrigin,
738 PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
739 wheelEvent.mButtons = 0;
740 wheelEvent.mDeltaMode = DeltaModeForDeltaType(mDeltaType);
741 wheelEvent.mMayHaveMomentum = mMayHaveMomentum;
742 wheelEvent.mIsMomentum = mIsMomentum;
743 wheelEvent.mDeltaX = mDeltaX;
744 wheelEvent.mDeltaY = mDeltaY;
745 wheelEvent.mLineOrPageDeltaX = mLineOrPageDeltaX;
746 wheelEvent.mLineOrPageDeltaY = mLineOrPageDeltaY;
747 wheelEvent.mAllowToOverrideSystemScrollSpeed =
748 mAllowToOverrideSystemScrollSpeed;
749 wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
750 wheelEvent.mFocusSequenceNumber = mFocusSequenceNumber;
751 return wheelEvent;
754 bool ScrollWheelInput::TransformToLocal(
755 const ScreenToParentLayerMatrix4x4& aTransform) {
756 Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
757 if (!point) {
758 return false;
760 mLocalOrigin = *point;
761 return true;
764 bool ScrollWheelInput::IsCustomizedByUserPrefs() const {
765 return mUserDeltaMultiplierX != 1.0 || mUserDeltaMultiplierY != 1.0;
768 KeyboardInput::KeyboardInput(const WidgetKeyboardEvent& aEvent)
769 : InputData(KEYBOARD_INPUT, aEvent.mTime, aEvent.mTimeStamp,
770 aEvent.mModifiers),
771 mKeyCode(aEvent.mKeyCode),
772 mCharCode(aEvent.mCharCode),
773 mHandledByAPZ(false) {
774 switch (aEvent.mMessage) {
775 case eKeyPress: {
776 mType = KeyboardInput::KEY_PRESS;
777 break;
779 case eKeyUp: {
780 mType = KeyboardInput::KEY_UP;
781 break;
783 case eKeyDown: {
784 mType = KeyboardInput::KEY_DOWN;
785 break;
787 default:
788 mType = KeyboardInput::KEY_OTHER;
789 break;
792 aEvent.GetShortcutKeyCandidates(mShortcutCandidates);
795 KeyboardInput::KeyboardInput()
796 : InputData(KEYBOARD_INPUT),
797 mType(KEY_DOWN),
798 mKeyCode(0),
799 mCharCode(0),
800 mHandledByAPZ(false) {}
802 } // namespace mozilla