mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Add APZ handling for desktop scroll wheel events. (bug 1086162 part 1, r=kats)
This commit is contained in:
parent
440327dce2
commit
028b163679
@ -394,10 +394,10 @@ struct ParamTraits<nsIntPoint>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::gfx::IntSize>
|
||||
template<typename T>
|
||||
struct ParamTraits<mozilla::gfx::IntSizeTyped<T> >
|
||||
{
|
||||
typedef mozilla::gfx::IntSize paramType;
|
||||
typedef mozilla::gfx::IntSizeTyped<T> paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
@ -756,6 +756,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
WriteParam(aMsg, aParam.mBackgroundColor);
|
||||
WriteParam(aMsg, aParam.mDoSmoothScroll);
|
||||
WriteParam(aMsg, aParam.mSmoothScrollOffset);
|
||||
WriteParam(aMsg, aParam.GetLineScrollAmount());
|
||||
WriteParam(aMsg, aParam.GetContentDescription());
|
||||
}
|
||||
|
||||
@ -797,6 +798,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
ReadParam(aMsg, aIter, &aResult->mBackgroundColor) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDoSmoothScroll) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mSmoothScrollOffset) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mLineScrollAmount) &&
|
||||
ReadContentDescription(aMsg, aIter, aResult));
|
||||
}
|
||||
};
|
||||
|
@ -65,6 +65,7 @@ public:
|
||||
, mViewport(0, 0, 0, 0)
|
||||
, mExtraResolution(1)
|
||||
, mBackgroundColor(0, 0, 0, 0)
|
||||
, mLineScrollAmount(0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -95,7 +96,8 @@ public:
|
||||
mUpdateScrollOffset == aOther.mUpdateScrollOffset &&
|
||||
mExtraResolution == aOther.mExtraResolution &&
|
||||
mBackgroundColor == aOther.mBackgroundColor &&
|
||||
mDoSmoothScroll == aOther.mDoSmoothScroll;
|
||||
mDoSmoothScroll == aOther.mDoSmoothScroll &&
|
||||
mLineScrollAmount == aOther.mLineScrollAmount;
|
||||
}
|
||||
bool operator!=(const FrameMetrics& aOther) const
|
||||
{
|
||||
@ -514,6 +516,16 @@ public:
|
||||
mMayHaveTouchListeners = aMayHaveTouchListeners;
|
||||
}
|
||||
|
||||
const LayoutDeviceIntSize& GetLineScrollAmount() const
|
||||
{
|
||||
return mLineScrollAmount;
|
||||
}
|
||||
|
||||
void SetLineScrollAmount(const LayoutDeviceIntSize& size)
|
||||
{
|
||||
mLineScrollAmount = size;
|
||||
}
|
||||
|
||||
private:
|
||||
// New fields from now on should be made private and old fields should
|
||||
// be refactored to be private.
|
||||
@ -605,6 +617,9 @@ private:
|
||||
// This is empty unless this is a scrollable layer and the
|
||||
// apz.printtree pref is turned on.
|
||||
nsCString mContentDescription;
|
||||
|
||||
// The value of GetLineScrollAmount(), for scroll frames.
|
||||
LayoutDeviceIntSize mLineScrollAmount;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -611,6 +611,29 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
|
||||
MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
|
||||
result = ProcessTouchInput(touchInput, aOutTargetGuid, aOutInputBlockId);
|
||||
break;
|
||||
} case SCROLLWHEEL_INPUT: {
|
||||
ScrollWheelInput& wheelInput = aEvent.AsScrollWheelInput();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(wheelInput.mOrigin,
|
||||
&hitResult);
|
||||
if (apzc) {
|
||||
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
|
||||
|
||||
transformToApzc = GetScreenToApzcTransform(apzc);
|
||||
wheelInput.mLocalOrigin =
|
||||
TransformTo<ParentLayerPixel>(transformToApzc, wheelInput.mOrigin);
|
||||
|
||||
result = mInputQueue->ReceiveInputEvent(
|
||||
apzc,
|
||||
/* aTargetConfirmed = */ hitResult,
|
||||
wheelInput, aOutInputBlockId);
|
||||
|
||||
// Update the out-parameters so they are what the caller expects.
|
||||
apzc->GetGuid(aOutTargetGuid);
|
||||
Matrix4x4 transformToGecko = transformToApzc * GetApzcToGeckoTransform(apzc);
|
||||
wheelInput.mOrigin =
|
||||
TransformTo<ScreenPixel>(transformToGecko, wheelInput.mLocalOrigin);
|
||||
}
|
||||
break;
|
||||
} case PANGESTURE_INPUT: {
|
||||
PanGestureInput& panInput = aEvent.AsPanGestureInput();
|
||||
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(panInput.mPanStartPoint,
|
||||
|
@ -1070,6 +1070,11 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCROLLWHEEL_INPUT: {
|
||||
const ScrollWheelInput& scrollInput = aEvent.AsScrollWheelInput();
|
||||
rv = OnScrollWheel(scrollInput);
|
||||
break;
|
||||
}
|
||||
default: return HandleGestureEvent(aEvent);
|
||||
}
|
||||
|
||||
@ -1453,6 +1458,72 @@ AsyncPanZoomController::ConvertToGecko(const ParentLayerPoint& aPoint, CSSPoint*
|
||||
return false;
|
||||
}
|
||||
|
||||
nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEvent)
|
||||
{
|
||||
double deltaX = aEvent.mDeltaX;
|
||||
double deltaY = aEvent.mDeltaY;
|
||||
switch (aEvent.mDeltaType) {
|
||||
case ScrollWheelInput::SCROLLDELTA_LINE: {
|
||||
LayoutDeviceIntSize scrollAmount = mFrameMetrics.GetLineScrollAmount();
|
||||
deltaX *= scrollAmount.width;
|
||||
deltaY *= scrollAmount.height;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected scroll delta type");
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
switch (aEvent.mScrollMode) {
|
||||
case ScrollWheelInput::SCROLLMODE_INSTANT: {
|
||||
// Decompose into pan events for simplicity.
|
||||
PanGestureInput start(PanGestureInput::PANGESTURE_START, aEvent.mTime, aEvent.mTimeStamp,
|
||||
aEvent.mOrigin, ScreenPoint(0, 0), aEvent.modifiers);
|
||||
start.mLocalPanStartPoint = aEvent.mLocalOrigin;
|
||||
OnPanBegin(start);
|
||||
|
||||
// Pan gestures use natural directions which are inverted from scroll
|
||||
// wheel and touchpad scroll gestures, so we invert x/y here. Since the
|
||||
// zoom includes any device : css pixel zoom, we convert to CSS pixels
|
||||
// before applying the zoom.
|
||||
LayoutDevicePoint devicePixelDelta(-deltaX, -deltaY);
|
||||
ParentLayerPoint delta = (devicePixelDelta / mFrameMetrics.mDevPixelsPerCSSPixel) *
|
||||
mFrameMetrics.GetZoom();
|
||||
|
||||
PanGestureInput move(PanGestureInput::PANGESTURE_PAN, aEvent.mTime, aEvent.mTimeStamp,
|
||||
aEvent.mOrigin,
|
||||
ToScreenCoordinates(delta, aEvent.mLocalOrigin),
|
||||
aEvent.modifiers);
|
||||
move.mLocalPanStartPoint = aEvent.mLocalOrigin;
|
||||
move.mLocalPanDisplacement = delta;
|
||||
OnPan(move, false);
|
||||
|
||||
PanGestureInput end(PanGestureInput::PANGESTURE_END, aEvent.mTime, aEvent.mTimeStamp,
|
||||
aEvent.mOrigin, ScreenPoint(0, 0), aEvent.modifiers);
|
||||
end.mLocalPanStartPoint = aEvent.mLocalOrigin;
|
||||
OnPanEnd(start);
|
||||
break;
|
||||
}
|
||||
|
||||
case ScrollWheelInput::SCROLLMODE_SMOOTH: {
|
||||
CSSPoint delta = LayoutDevicePoint(deltaX, deltaY) / mFrameMetrics.mDevPixelsPerCSSPixel;
|
||||
|
||||
// If we're already in a smooth scroll animation, don't cancel it. This
|
||||
// lets us preserve the existing scrolling velocity.
|
||||
if (mState != SMOOTH_SCROLL) {
|
||||
CancelAnimation();
|
||||
mFrameMetrics.SetSmoothScrollOffset(mFrameMetrics.GetScrollOffset() + delta);
|
||||
} else {
|
||||
mFrameMetrics.SetSmoothScrollOffset(mFrameMetrics.GetSmoothScrollOffset() + delta);
|
||||
}
|
||||
StartSmoothScroll();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
nsEventStatus AsyncPanZoomController::OnPanMayBegin(const PanGestureInput& aEvent) {
|
||||
APZC_LOG("%p got a pan-maybegin in state %d\n", this, mState);
|
||||
|
||||
|
@ -414,6 +414,11 @@ protected:
|
||||
nsEventStatus OnPanMomentumStart(const PanGestureInput& aEvent);
|
||||
nsEventStatus OnPanMomentumEnd(const PanGestureInput& aEvent);
|
||||
|
||||
/**
|
||||
* Helper methods for handling scroll wheel events.
|
||||
*/
|
||||
nsEventStatus OnScrollWheel(const ScrollWheelInput& aEvent);
|
||||
|
||||
/**
|
||||
* Helper methods for long press gestures.
|
||||
*/
|
||||
|
@ -236,6 +236,12 @@ struct LayoutDevicePixel {
|
||||
return FromUntyped(aRect.ToNearestPixels(aAppUnitsPerDevPixel));
|
||||
}
|
||||
|
||||
static LayoutDeviceIntSize FromAppUnitsRounded(const nsSize& aSize, nscoord aAppUnitsPerDevPixel) {
|
||||
return LayoutDeviceIntSize(
|
||||
NSAppUnitsToIntPixels(aSize.width, aAppUnitsPerDevPixel),
|
||||
NSAppUnitsToIntPixels(aSize.height, aAppUnitsPerDevPixel));
|
||||
}
|
||||
|
||||
static nsSize ToAppUnits(const LayoutDeviceIntSize& aSize, nscoord aAppUnitsPerDevPixel) {
|
||||
return nsSize(aSize.width * aAppUnitsPerDevPixel,
|
||||
aSize.height * aAppUnitsPerDevPixel);
|
||||
|
@ -723,6 +723,11 @@ nsDisplayScrollLayer::ComputeFrameMetrics(nsIFrame* aForFrame,
|
||||
if (lastSmoothScrollOrigin) {
|
||||
metrics.SetSmoothScrollOffsetUpdated(scrollableFrame->CurrentScrollGeneration());
|
||||
}
|
||||
|
||||
nsSize lineScrollAmount = scrollableFrame->GetLineScrollAmount();
|
||||
LayoutDeviceIntSize lineScrollAmountInDevPixels =
|
||||
LayoutDeviceIntSize::FromAppUnitsRounded(lineScrollAmount, presContext->AppUnitsPerDevPixel());
|
||||
metrics.SetLineScrollAmount(lineScrollAmountInDevPixels);
|
||||
}
|
||||
|
||||
metrics.SetScrollId(scrollId);
|
||||
|
@ -27,13 +27,15 @@ enum InputType
|
||||
MULTITOUCH_INPUT,
|
||||
PANGESTURE_INPUT,
|
||||
PINCHGESTURE_INPUT,
|
||||
TAPGESTURE_INPUT
|
||||
TAPGESTURE_INPUT,
|
||||
SCROLLWHEEL_INPUT
|
||||
};
|
||||
|
||||
class MultiTouchInput;
|
||||
class PanGestureInput;
|
||||
class PinchGestureInput;
|
||||
class TapGestureInput;
|
||||
class ScrollWheelInput;
|
||||
|
||||
// This looks unnecessary now, but as we add more and more classes that derive
|
||||
// from InputType (eventually probably almost as many as *Events.h has), it
|
||||
@ -72,6 +74,7 @@ public:
|
||||
INPUTDATA_AS_CHILD_TYPE(PanGestureInput, PANGESTURE_INPUT)
|
||||
INPUTDATA_AS_CHILD_TYPE(PinchGestureInput, PINCHGESTURE_INPUT)
|
||||
INPUTDATA_AS_CHILD_TYPE(TapGestureInput, TAPGESTURE_INPUT)
|
||||
INPUTDATA_AS_CHILD_TYPE(ScrollWheelInput, SCROLLWHEEL_INPUT)
|
||||
|
||||
InputData()
|
||||
{
|
||||
@ -431,6 +434,60 @@ public:
|
||||
ParentLayerPoint mLocalPoint;
|
||||
};
|
||||
|
||||
// Encapsulation class for scroll-wheel events. These are generated by mice
|
||||
// with physical scroll wheels, and on Windows by most touchpads when using
|
||||
// scroll gestures.
|
||||
class ScrollWheelInput : public InputData
|
||||
{
|
||||
public:
|
||||
enum ScrollDeltaType
|
||||
{
|
||||
// There are three kinds of scroll delta modes in Gecko: "page", "line" and
|
||||
// "pixel". For apz, we currently only support "line" mode.
|
||||
SCROLLDELTA_LINE
|
||||
};
|
||||
|
||||
enum ScrollMode
|
||||
{
|
||||
SCROLLMODE_INSTANT,
|
||||
SCROLLMODE_SMOOTH
|
||||
};
|
||||
|
||||
ScrollWheelInput(uint32_t aTime,
|
||||
TimeStamp aTimeStamp,
|
||||
Modifiers aModifiers,
|
||||
ScrollMode aScrollMode,
|
||||
ScrollDeltaType aDeltaType,
|
||||
const ScreenPoint& aOrigin,
|
||||
double aDeltaX,
|
||||
double aDeltaY)
|
||||
: InputData(SCROLLWHEEL_INPUT, aTime, aTimeStamp, aModifiers),
|
||||
mDeltaType(aDeltaType),
|
||||
mScrollMode(aScrollMode),
|
||||
mOrigin(aOrigin),
|
||||
mDeltaX(aDeltaX),
|
||||
mDeltaY(aDeltaY)
|
||||
{}
|
||||
|
||||
ScrollDeltaType mDeltaType;
|
||||
ScrollMode mScrollMode;
|
||||
ScreenPoint mOrigin;
|
||||
|
||||
// Deltas are in units corresponding to the delta type. For line deltas, they
|
||||
// are the number of line units to scroll. The number of device pixels for a
|
||||
// horizontal and vertical line unit are in FrameMetrics::mLineScrollAmount.
|
||||
//
|
||||
// The horizontal (X) delta is > 0 for scrolling right and < 0 for scrolling
|
||||
// left. The vertical (Y) delta is < 0 for scrolling up and > 0 for
|
||||
// scrolling down.
|
||||
double mDeltaX;
|
||||
double mDeltaY;
|
||||
|
||||
// The location of the scroll in local coordinates. This is set and used by
|
||||
// APZ.
|
||||
ParentLayerPoint mLocalOrigin;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // InputData_h__
|
||||
|
Loading…
Reference in New Issue
Block a user