Files
palemoon27/widget/InputData.cpp
T
roytam1 d88cb9e205 import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1193062 - Add PanGestureBlockState. r=kats (a8da88a934)
- Bug 1193062 - Make PanGestureInput transform processing work like ScrollWheelInput processing. r=kats (fb17c120e8)
- Bug 1180780 - Enable handling of pixel-scrolling wheel events with APZ on Windows and Linux. r=mstange (41d8fd5ed2)
- missing part of Bug 1013412 (4fa14a56d9)
- Make sure that confirmed APZ wheel targets are always scrollable. (bug 1154132, r=kats) (c35e3a34ca)
- breakage fixes (96a1e3c36a)
- Bug 1153711 - Do not discard a component of a fling if an APZC further in the handoff chain has room to scroll in that direction. r=kats (4f35dfd913)
- Bug 1193062 - Set correct axis velocities when using PanGestureInput events. r=kats (7036040c68)
- Clamp APZ wheel animations to their scrollable range. (bug 1152011 part 2, r=botond) (45c4925fee)
- Bug 1193062 - CanScrollWithWheel needs to use ParentLayerCoords for the scroll delta. r=kats (20a3c4ac6b)
- Bug 1193062 - Make OverscrollHandoffChain::FindFirstScrollable and AsyncPanZoomController::CanScroll able to deal with PanGestureInput events. r=kats (d87ec270db)
- Bug 1193062 - Add mHandledByAPZ on PanGestureInput and ScrollWheelInput, and sync the information to the WidgetWheelEvent. r=kats (6e72f5885f)
- Bug 1016035 - Delay the processing of a PanGestureInput block until we know whether it's a swipe. r=kats (77d1dceb04)
- Bug 1145084 - Ensure that the 300ms content timeout in the APZ code also applies to the touch-action allowed behaviours. r=botond (45f58fe247)
- Bug 1193062 - Make AllowScrollHandoff work for both ScrollWheelInput and PanGestureInput blocks. r=kats (d335008b0a)
- Bug 1193062 - Remove mPanGestureState. r=kats (774bb3dedf)
- Bug 1193062 - Use ScrollSource::Wheel for pan gesture events. r=kats (e9328b0bc4)
- Bug 1193062 - Don't use PanGestureInput events for instant wheel scrolling. r=kats (7d89c5dc2e)
- Bug 1175564 - don't lock y-axis if pan displacement is 0. r=kats (372d76c914)
- Bug 1193062 - Process pan gesture deltas in begin+end events. r=kats (f29072bf8f)
- Bug 1193062 - Fix UntransformVector w coordinate checks. r=kip (73b459e459)
- Bug 1016035 - Replay the queue to the swipe tracker once the swipe start confirmation arrives. r=kats (9891444d4f)
- Bug 1016035 - Don't wait for content to say that we need to swipe if APZ has enough information. r=kats (2b94c25bd3)
- Bug 1016035 - Swallow the rest of the scroll gesture after swiping without APZ. r=kats (f9250388f9)
- Fix crashes when a wheel transaction has a null confirmed apzc. (bug 1147249, r=kats) (ef898a9f3a)
- Bug 1176001 - Turn unconditional log into a manually-enabled log. r=botond (1d866b1ffa)
- Don't have a default repaint interval of "never" for APZ animations. (bug 1152138, r=botond) (7e276ba862)
- Bug 1152051 - Ensure that destroying an overscroll animation always clears the state Axis tracks about it. r=Cwiiis (1273aac828)
- Request content repaints during APZ wheel animations. (bug 1152138, r=botond) (ba3e24011b)
- Bug 1164557 - Use COORDINATE_EPSILON in IsZero(). r=kats (c07e506607)
- Bug 1164557 - Weed out spurious calls to Axis::OverscrollBy() caused by rounding error r=kats (15f8d18a7e)
- Bug 1186164 - When clearing the overscroll animation state, make sure# etOverscroll() continues to reflect the correct direction of overscroll. r=Cwiiis (282c63383c)
- Bug 1198900 - Don't call OnTouchCancel when the current block is not a touch block. r=botond (b724d8d3ef)
- Bug 788873 - Only rebind a GLXPixmap if the texture has changed. r=karlt (e1f72858ee)
- Bug 1169270 - Minor style fixes. r=dvander (494449170d)
- Bug 1145702 - Make the assertion in Axis::GetOverscroll() more informative. r=Cwiiis (dff257bbbd)
- Bug 1152051 - During an overscroll animation, detect a peak even if a sample has a velocity of exaclty zero. r=Cwiiis (a5aad5349f)
- Bug 1201101 - Enable axis-locking over multiple APZCs. r=botond (21574b80ec)
- test of Bug 1143522 - Convert Layer::mClipRect to ParentLayerIntRect. r=botond (8f729ca8b0)
- Bug 1159398 - Set the controller thread when running APZ gtests. r=dvander (4349b6722b)
- Bug 1148350 - Add a test. r=botond (72e3c0716d)
- Bug 1152051 - Gtest. r=Cwiiis,kats (bf337c0d6d)
- missing of Bug 1158122 - Remove most occurences of nsIntRect in gfx/tests. r=nical (a328773d9d)
- missing test of Bug 1160566 - Make FrameMetrics.mCompositionBounds private (091db42632)
- Bug 1163845 - Unify handling of time in APZ gtests. r=kats (2366690fe7)
- Fix APZ scroll wheel animations often prematurely ending on the first frame. (bug 1157409, r=kats) (78cc0e2292)
- Bug 1169689 - Make sure we don't end up with a spurious velocity if we're not going to be panning. r=botond (8911802134)
- Bug 1203744 - Fix the SCREEN blend mode with CompositorOGL when the source data is unpremultiplied. r=dvander (e256f83a14)
2022-02-04 11:50:49 +08:00

346 lines
10 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");
nsRefPtr<Touch> touch = new Touch(mIdentifier,
LayoutDeviceIntPoint(mScreenPoint.x, mScreenPoint.y),
nsIntPoint(mRadius.width, mRadius.height),
mRotationAngle,
mForce);
return touch.forget();
}
MultiTouchInput::MultiTouchInput(const WidgetTouchEvent& aTouchEvent)
: InputData(MULTITOUCH_INPUT, aTouchEvent.time, aTouchEvent.timeStamp,
aTouchEvent.modifiers)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetTouchEvent on main thread");
switch (aTouchEvent.mMessage) {
case NS_TOUCH_START:
mType = MULTITOUCH_START;
break;
case NS_TOUCH_MOVE:
mType = MULTITOUCH_MOVE;
break;
case NS_TOUCH_END:
mType = MULTITOUCH_END;
break;
case NS_TOUCH_CANCEL:
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,
ScreenIntPoint::FromUnknownPoint(
gfx::IntPoint(domTouch->mRefPoint.x,
domTouch->mRefPoint.y)),
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 = NS_EVENT_NULL;
switch (mType) {
case MULTITOUCH_START:
touchEventMessage = NS_TOUCH_START;
break;
case MULTITOUCH_MOVE:
touchEventMessage = NS_TOUCH_MOVE;
break;
case MULTITOUCH_END:
touchEventMessage = NS_TOUCH_END;
break;
case MULTITOUCH_CANCEL:
touchEventMessage = NS_TOUCH_CANCEL;
break;
default:
MOZ_ASSERT_UNREACHABLE("Did not assign a type to WidgetTouchEvent in MultiTouchInput");
break;
}
WidgetTouchEvent event(true, touchEventMessage, aWidget);
if (touchEventMessage == NS_EVENT_NULL) {
return event;
}
event.modifiers = this->modifiers;
event.time = this->mTime;
event.timeStamp = this->mTimeStamp;
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 = NS_EVENT_NULL;
switch (mType) {
case MultiTouchInput::MULTITOUCH_START:
mouseEventMessage = NS_MOUSE_BUTTON_DOWN;
break;
case MultiTouchInput::MULTITOUCH_MOVE:
mouseEventMessage = NS_MOUSE_MOVE;
break;
case MultiTouchInput::MULTITOUCH_CANCEL:
case MultiTouchInput::MULTITOUCH_END:
mouseEventMessage = NS_MOUSE_BUTTON_UP;
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;
if (mouseEventMessage != NS_MOUSE_MOVE) {
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)
{
MOZ_ASSERT(NS_IsMainThread(),
"Can only copy from WidgetMouseEvent on main thread");
switch (aMouseEvent.mMessage) {
case NS_MOUSE_BUTTON_DOWN:
mType = MULTITOUCH_START;
break;
case NS_MOUSE_MOVE:
mType = MULTITOUCH_MOVE;
break;
case NS_MOUSE_BUTTON_UP:
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 NS_MOUSE_EXIT_WIDGET:
mType = MULTITOUCH_CANCEL;
break;
default:
NS_WARNING("Did not assign a type to a MultiTouchInput");
break;
}
mTouches.AppendElement(SingleTouchData(0,
ScreenIntPoint::FromUnknownPoint(
gfx::IntPoint(aMouseEvent.refPoint.x,
aMouseEvent.refPoint.y)),
ScreenSize(1, 1),
180.0f,
1.0f));
}
bool
MultiTouchInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
{
for (size_t i = 0; i < mTouches.Length(); i++) {
Maybe<ParentLayerIntPoint> point = UntransformTo<ParentLayerPixel>(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, NS_WHEEL_WHEEL, aWidget);
wheelEvent.modifiers = this->modifiers;
wheelEvent.time = mTime;
wheelEvent.timeStamp = mTimeStamp;
wheelEvent.refPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mPanStartPoint,
PixelCastJustification::LayoutDeviceToScreenForUntransformedEvent));
wheelEvent.buttons = 0;
wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_PIXEL;
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 gfx::Matrix4x4& aTransform)
{
Maybe<ParentLayerPoint> panStartPoint = UntransformTo<ParentLayerPixel>(aTransform, mPanStartPoint);
if (!panStartPoint) {
return false;
}
mLocalPanStartPoint = *panStartPoint;
Maybe<ParentLayerPoint> panDisplacement = UntransformVector<ParentLayerPixel>(aTransform, mPanDisplacement, mPanStartPoint);
if (!panDisplacement) {
return false;
}
mLocalPanDisplacement = *panDisplacement;
return true;
}
bool
PinchGestureInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
{
Maybe<ParentLayerPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mFocusPoint);
if (!point) {
return false;
}
mLocalFocusPoint = *point;
return true;
}
bool
TapGestureInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
{
Maybe<ParentLayerIntPoint> point = UntransformTo<ParentLayerPixel>(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_PIXEL:
default:
return nsIDOMWheelEvent::DOM_DELTA_PIXEL;
}
}
WidgetWheelEvent
ScrollWheelInput::ToWidgetWheelEvent(nsIWidget* aWidget) const
{
WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, aWidget);
wheelEvent.modifiers = this->modifiers;
wheelEvent.time = mTime;
wheelEvent.timeStamp = mTimeStamp;
wheelEvent.refPoint =
RoundedToInt(ViewAs<LayoutDevicePixel>(mOrigin,
PixelCastJustification::LayoutDeviceToScreenForUntransformedEvent));
wheelEvent.buttons = 0;
wheelEvent.deltaMode = DeltaModeForDeltaType(mDeltaType);
wheelEvent.isMomentum = mIsMomentum;
wheelEvent.deltaX = mDeltaX;
wheelEvent.deltaY = mDeltaY;
wheelEvent.lineOrPageDeltaX = mLineOrPageDeltaX;
wheelEvent.lineOrPageDeltaY = mLineOrPageDeltaY;
wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ;
return wheelEvent;
}
bool
ScrollWheelInput::TransformToLocal(const gfx::Matrix4x4& aTransform)
{
Maybe<ParentLayerPoint> point = UntransformTo<ParentLayerPixel>(aTransform, mOrigin);
if (!point) {
return false;
}
mLocalOrigin = *point;
return true;
}
} // namespace mozilla