Files
palemoon27/widget/InputData.cpp
T
roytam1 c975675694 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1198459 - Update telemetry data based on the use of the forced enable pref. r=felipe (f33f0efc9a)
- Bug 1234210 - Restrict updates for accessibility.lastLoadDate to shutdown. r=trevor (5e484eb7ba)
- Bug 1231517 - part 3, Add ZoomToRect function to nsIWidget classes r=kats (57496a18cd)
- Bug 1229393 - Ensure that all the touch points from the original touch go to APZCCallbackHelper::SendSetTargetAPZCNotification. r=botond (45ce1737ac)
- Bug 1174323 part 1 - Add nsDOMWindowUtils::SendNativeMouseMove and EventUtils.sendNativeMouseMove. r=smaug (527439f71b)
- Bug 1180351 - Enable pointerlock tests on Windows and Linux. r=smaug (833fac9ba9)
- Bug 1180351 - Followup: Disable pointerlock tests on Windows for frequently failing tests. r=turning off tests (02525d24f4)
- Bug 1174323 part 2 - Use native mouse move to improve robustness of screenClientXYConst subtest. r=smaug (7e3fb884d3)
- Bug 1231517 - part 4, Add ZoomToFocusedInput function to nsDOMWindowUtils r=kats (a1f3e3b4fd)
- Bug 1153156 part.1 Move nsBaseWidget::OverrideSystemMouseScrollSpeed() to WidgetWheelEvent r=smaug, sr=smaug (8a95d65d55)
- bug 726265 don't activate ELAN swipe hack unless ScanCode is zero r=heycam (477a5ce06a)
- Bug 1235686 part.1 MouseScrollHandler should refresh the cache of system settings at handling wheel messages if the pref doesn't allow to cache system settings r=jimm (6cae8d2b07)
- Bug 1235686 part.2 Don't refresh the cache of system settings at handling wheel messages if the scroll amout values are initialized with prefs r=jimm (ead872b6bf)
- Bug 1235686 part.3 Don't trust system settings cache if SynTP of Synaptics is installed r=jimm (d56a034a42)
- Bug 1235686 part.4 Don't trust system settings cache if Apoint of Alps is installed r=jimm (85cb23e185)
- Bug 1153156 part.2 Make WidgetWheelEvent store if overriding system scroll speed is allowed and it shouldn't be allowed if scroll speed isn't system default settings on Windows r=smaug+jimm (3d5fc255db)
- Bug 1153156 part.3 Don't allow to override system scroll speed if the wheel event causes too fast scroll r=smaug+jimm (21e10640ac)
- Bug 1236750 - Rename ViewTransform to AsyncTransform. r=kats (1ccd8af262)
- Bug 1226826 - Record if painted displayport updates were due to repaints from the relevant layer tree or not. r=botond (e28315ec88)
- Bug 1228641. Add a initializer_list constructor to nsTArray. r=froydnj (448f69f610)
- Bug 962243 - Gtest for being able to pan after lifting a finger from a pinch. r=botond (a1687f190c)
- Bug 1031443 - Allow panning in the pinching state even if zooming is disabled;r=botond (aacb1a28bd)
- Bug 1231504 - Move some prefs from b2g.js to all.js. r=botond (c9801602ba)
- Bug 1092128 - Ensure the tests for touch action disabled actually disable touch action. r=botond (ec3fae4568)
- Bug 1014691 - Get TestAsyncPanZoomController to compile in its new location. r=kats (9dd104c6fd)
- Bug 1240244 - Split APZ gtests into several files. r=kats (0ce8bd4f80)
- Bug 1235994 - Add a flag to wheel events to track if they may have momentum following them. r=mstange (d5b2099244)
- Bug 1153156 part.4 Make APZC system scroll speed overriding aware r=mstange (f9d49eb79c)
- Bug 1233118 - implement IAccessible2_3::selectionRanges, r=yzen (d85fe6cf64)
- bug 1235965 - null check mDoc in AccessibleWrap::Shutdown() r=davidb (cb775e5c00)
- Bug 1130096 - Convert embedding/components/find/ to Gecko style. r=mccr8 (83d043e841)
- Bug 1164473 - Resolve issue when touches stop working after pen was activated. r=jimm (16ce68b032)
- Bug 1171712 - Implement separated InkColletor and InkCollectorEvent classes. r=smaug, r=jimm (8000e742b8)
- bug 1198656 interpret null ConvolverNode mBuffer as a buffer of zerosr=padenot (339e1f9904)
- bug 930257 finish Oscillator on processing last non-null block r=padenot (2719eee12b)
- Bug 1240411: P1. Clean up webaudio headers. r=cpearce (f169dc2789)
- Bug 1219711 - Don't rely on timer interval in fake audio track. r=jesup (f140fd848a)
- Bug 1223655 - Only check for track end if track exists in MediaEngineDefaultAudioSource. r=jesup (3055b4529f)
- Bug 1223655 - Also don't check time of data end if track has ended. r=jesup (bbdf7c5be5)
- Bug 1223655 - Fix opt build bustage on a CLOSED TREE. r=bustage (d546f4ba0b)
- Bug 1164463 followup: Add missing 'override' keyword to MediaEngineDefault::Shutdown(). rs=ehsan (33bf959d84)
- Bug 1240411: P2. Clean up webrtc headers. r=jesup (73c2bdf22d)
- Bug 1240411: P4. Clean up readers headers. r=cpearce (748d2bf9e8)
- Bug 1232527 - Remove GMPVideoDecoderTrialCreator and friends. r=jwwang (e0decf270f)
- Bug 1240411: P5. Clean up GMP headers. r=cpearce (0336b7fd9c)
- Bug 1240252: Add missing "mozilla::" namespace prefix before usage of type LayoutDeviceIntRegion, to fix local build bustage. r=njn (54d5a4a553)
- Bug 1245241 - part 1 - Close Shmem file handles after mapping them when possible to reduce exhaustion issues. r=billm (631c2b6da5)
2023-08-16 17:20:15 +08:00

440 lines
13 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "InputData.h"
#include "mozilla/dom/Touch.h"
#include "nsDebug.h"
#include "nsThreadUtils.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/TouchEvents.h"
#include "UnitTransforms.h"
namespace mozilla {
using namespace dom;
already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only create dom::Touch instances on main thread");
RefPtr<Touch> touch = new Touch(mIdentifier,
LayoutDeviceIntPoint(mScreenPoint.x, mScreenPoint.y),
LayoutDeviceIntPoint(mRadius.width, mRadius.height),
mRotationAngle,
mForce);
return touch.forget();
}
MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent)
: InputData(MOUSE_INPUT, aMouseEvent.time, aMouseEvent.timeStamp,
aMouseEvent.modifiers)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetTouchEvent on main thread");
mButtonType = NONE;
switch (aMouseEvent.button) {
case WidgetMouseEventBase::eLeftButton:
mButtonType = MouseInput::LEFT_BUTTON;
break;
case WidgetMouseEventBase::eMiddleButton:
mButtonType = MouseInput::MIDDLE_BUTTON;
break;
case WidgetMouseEventBase::eRightButton:
mButtonType = MouseInput::RIGHT_BUTTON;
break;
}
switch (aMouseEvent.mMessage) {
case eMouseMove:
mType = MOUSE_MOVE;
break;
case eMouseUp:
mType = MOUSE_UP;
break;
case eMouseDown:
mType = MOUSE_DOWN;
break;
case eDragStart:
mType = MOUSE_DRAG_START;
break;
case eDragEnd:
mType = MOUSE_DRAG_END;
break;
default:
MOZ_ASSERT_UNREACHABLE("Mouse event type not supported");
break;
}
}
bool
MouseInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
if (!point) {
return false;
}
mLocalOrigin = *point;
return true;
}
MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
: InputData(MULTITOUCH_INPUT, aTouchEvent.time, aTouchEvent.timeStamp,
aTouchEvent.modifiers)
, mHandledByAPZ(aTouchEvent.mFlags.mHandledByAPZ)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetTouchEvent on main thread");
switch (aTouchEvent.mMessage) {
case eTouchStart:
mType = MULTITOUCH_START;
break;
case eTouchMove:
mType = MULTITOUCH_MOVE;
break;
case eTouchEnd:
mType = MULTITOUCH_END;
break;
case eTouchCancel:
mType = MULTITOUCH_CANCEL;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to a MultiTouchInput");
break;
}
for (size_t i = 0; i < aTouchEvent.touches.Length(); i++) {
const Touch* domTouch = aTouchEvent.touches[i];
// Extract data from weird interfaces.
int32_t identifier = domTouch->Identifier();
int32_t radiusX = domTouch->RadiusX();
int32_t radiusY = domTouch->RadiusY();
float rotationAngle = domTouch->RotationAngle();
float force = domTouch->Force();
SingleTouchData data(identifier,
ViewAs<ScreenPixel>(domTouch->mRefPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
ScreenSize(radiusX, radiusY),
rotationAngle,
force);
mTouches.AppendElement(data);
}
}
WidgetTouchEvent
MultiTouchInput::ToWidgetTouchEvent(nsIWidget* aWidget) const
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only convert To WidgetTouchEvent on main thread");
EventMessage touchEventMessage = eVoidEvent;
switch (mType) {
case MULTITOUCH_START:
touchEventMessage = eTouchStart;
break;
case MULTITOUCH_MOVE:
touchEventMessage = eTouchMove;
break;
case MULTITOUCH_END:
touchEventMessage = eTouchEnd;
break;
case MULTITOUCH_CANCEL:
touchEventMessage = eTouchCancel;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetTouchEvent in MultiTouchInput");
break;
}
WidgetTouchEvent event(true, touchEventMessage, aWidget);
if (touchEventMessage == eVoidEvent) {
return event;
}
event.modifiers = this->modifiers;
event.time = this->mTime;
event.timeStamp = this->mTimeStamp;
event.mFlags.mHandledByAPZ = mHandledByAPZ;
for (size_t i = 0; i < mTouches.Length(); i++) {
*event.touches.AppendElement() = mTouches[i].ToNewDOMTouch();
}
return event;
}
WidgetMouseEvent
MultiTouchInput::ToWidgetMouseEvent(nsIWidget* aWidget) const
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only convert To WidgetMouseEvent on main thread");
EventMessage mouseEventMessage = eVoidEvent;
switch (mType) {
case MultiTouchInput::MULTITOUCH_START:
mouseEventMessage = eMouseDown;
break;
case MultiTouchInput::MULTITOUCH_MOVE:
mouseEventMessage = eMouseMove;
break;
case MultiTouchInput::MULTITOUCH_CANCEL:
case MultiTouchInput::MULTITOUCH_END:
mouseEventMessage = eMouseUp;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetMouseEvent");
break;
}
WidgetMouseEvent event(true, mouseEventMessage, aWidget,
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
const SingleTouchData& firstTouch = mTouches[0];
event.refPoint.x = firstTouch.mScreenPoint.x;
event.refPoint.y = firstTouch.mScreenPoint.y;
event.time = mTime;
event.button = WidgetMouseEvent::eLeftButton;
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
event.modifiers = modifiers;
event.mFlags.mHandledByAPZ = mHandledByAPZ;
if (mouseEventMessage != eMouseMove) {
event.clickCount = 1;
}
return event;
}
int32_t
MultiTouchInput::IndexOfTouch(int32_t aTouchIdentifier)
{
for (size_t i = 0; i < mTouches.Length(); i++) {
if (mTouches[i].mIdentifier == aTouchIdentifier) {
return (int32_t)i;
}
}
return -1;
}
// This conversion from WidgetMouseEvent to MultiTouchInput is needed because on
// the B2G emulator we can only receive mouse events, but we need to be able
// to pan correctly. To do this, we convert the events into a format that the
// panning code can handle. This code is very limited and only supports
// SingleTouchData. It also sends garbage for the identifier, radius, force
// and rotation angle.
MultiTouchInput::MultiTouchInput(const WidgetMouseEvent& aMouseEvent)
: InputData(MULTITOUCH_INPUT, aMouseEvent.time, aMouseEvent.timeStamp,
aMouseEvent.modifiers)
, mHandledByAPZ(aMouseEvent.mFlags.mHandledByAPZ)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetMouseEvent on main thread");
switch (aMouseEvent.mMessage) {
case eMouseDown:
mType = MULTITOUCH_START;
break;
case eMouseMove:
mType = MULTITOUCH_MOVE;
break;
case eMouseUp:
mType = MULTITOUCH_END;
break;
// The mouse pointer has been interrupted in an implementation-specific
// manner, such as a synchronous event or action cancelling the touch, or a
// touch point leaving the document window and going into a non-document
// area capable of handling user interactions.
case eMouseExitFromWidget:
mType = MULTITOUCH_CANCEL;
break;
default:
NS_WARNING("Did not assign a type to a MultiTouchInput");
break;
}
mTouches.AppendElement(SingleTouchData(0,
ViewAs<ScreenPixel>(aMouseEvent.refPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent),
ScreenSize(1, 1),
180.0f,
1.0f));
}
bool
MultiTouchInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
for (size_t i = 0; i < mTouches.Length(); i++) {
Maybe<ParentLayerIntPoint> point = UntransformBy(aTransform, mTouches[i].mScreenPoint);
if (!point) {
return false;
}
mTouches[i].mLocalScreenPoint = *point;
}
return true;
}
bool
PanGestureInput::IsMomentum() const
{
switch (mType) {
case PanGestureInput::PANGESTURE_MOMENTUMSTART:
case PanGestureInput::PANGESTURE_MOMENTUMPAN:
case PanGestureInput::PANGESTURE_MOMENTUMEND:
return true;
default:
return false;
}
}
WidgetWheelEvent
PanGestureInput::ToWidgetWheelEvent(nsIWidget* aWidget) const
{
WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
wheelEvent.modifiers = this->modifiers;
wheelEvent.time = mTime;
wheelEvent.timeStamp = mTimeStamp;
wheelEvent.refPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mPanStartPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
wheelEvent.buttons = 0;
wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_PIXEL;
wheelEvent.mayHaveMomentum = true; // pan inputs may have momentum
wheelEvent.isMomentum = IsMomentum();
wheelEvent.lineOrPageDeltaX = mLineOrPageDeltaX;
wheelEvent.lineOrPageDeltaY = mLineOrPageDeltaY;
wheelEvent.deltaX = mPanDisplacement.x;
wheelEvent.deltaY = mPanDisplacement.y;
wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
return wheelEvent;
}
bool
PanGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
Maybe<ParentLayerPoint> panStartPoint = UntransformBy(aTransform, mPanStartPoint);
if (!panStartPoint) {
return false;
}
mLocalPanStartPoint = *panStartPoint;
Maybe<ParentLayerPoint> panDisplacement = UntransformVector(aTransform, mPanDisplacement, mPanStartPoint);
if (!panDisplacement) {
return false;
}
mLocalPanDisplacement = *panDisplacement;
return true;
}
bool
PinchGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mFocusPoint);
if (!point) {
return false;
}
mLocalFocusPoint = *point;
return true;
}
bool
TapGestureInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
Maybe<ParentLayerIntPoint> point = UntransformBy(aTransform, mPoint);
if (!point) {
return false;
}
mLocalPoint = *point;
return true;
}
static uint32_t
DeltaModeForDeltaType(ScrollWheelInput::ScrollDeltaType aDeltaType)
{
switch (aDeltaType) {
case ScrollWheelInput::SCROLLDELTA_LINE:
return nsIDOMWheelEvent::DOM_DELTA_LINE;
case ScrollWheelInput::SCROLLDELTA_PAGE:
return nsIDOMWheelEvent::DOM_DELTA_PAGE;
case ScrollWheelInput::SCROLLDELTA_PIXEL:
default:
return nsIDOMWheelEvent::DOM_DELTA_PIXEL;
}
}
ScrollWheelInput::ScrollWheelInput(const WidgetWheelEvent& aWheelEvent)
: InputData(SCROLLWHEEL_INPUT,
aWheelEvent.time,
aWheelEvent.timeStamp,
aWheelEvent.modifiers)
, mDeltaType(DeltaTypeForDeltaMode(aWheelEvent.deltaMode))
, mScrollMode(SCROLLMODE_INSTANT)
, mHandledByAPZ(aWheelEvent.mFlags.mHandledByAPZ)
, mDeltaX(aWheelEvent.deltaX)
, mDeltaY(aWheelEvent.deltaY)
, mLineOrPageDeltaX(aWheelEvent.lineOrPageDeltaX)
, mLineOrPageDeltaY(aWheelEvent.lineOrPageDeltaY)
, mUserDeltaMultiplierX(1.0)
, mUserDeltaMultiplierY(1.0)
, mMayHaveMomentum(aWheelEvent.mayHaveMomentum)
, mIsMomentum(aWheelEvent.isMomentum)
, mAllowToOverrideSystemScrollSpeed(
aWheelEvent.mAllowToOverrideSystemScrollSpeed)
{
mOrigin =
ScreenPoint(ViewAs<ScreenPixel>(aWheelEvent.refPoint,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
}
WidgetWheelEvent
ScrollWheelInput::ToWidgetWheelEvent(nsIWidget* aWidget) const
{
WidgetWheelEvent wheelEvent(true, eWheel, aWidget);
wheelEvent.modifiers = this->modifiers;
wheelEvent.time = mTime;
wheelEvent.timeStamp = mTimeStamp;
wheelEvent.refPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent));
wheelEvent.buttons = 0;
wheelEvent.deltaMode = DeltaModeForDeltaType(mDeltaType);
wheelEvent.mayHaveMomentum = mMayHaveMomentum;
wheelEvent.isMomentum = mIsMomentum;
wheelEvent.deltaX = mDeltaX;
wheelEvent.deltaY = mDeltaY;
wheelEvent.lineOrPageDeltaX = mLineOrPageDeltaX;
wheelEvent.lineOrPageDeltaY = mLineOrPageDeltaY;
wheelEvent.mAllowToOverrideSystemScrollSpeed =
mAllowToOverrideSystemScrollSpeed;
wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
return wheelEvent;
}
bool
ScrollWheelInput::TransformToLocal(const ScreenToParentLayerMatrix4x4& aTransform)
{
Maybe<ParentLayerPoint> point = UntransformBy(aTransform, mOrigin);
if (!point) {
return false;
}
mLocalOrigin = *point;
return true;
}
bool
ScrollWheelInput::IsCustomizedByUserPrefs() const
{
return mUserDeltaMultiplierX != 1.0 ||
mUserDeltaMultiplierY != 1.0;
}
} // namespace mozilla