| author | myfreeweb <greg@unrelenting.technology> |
| Thu, 20 Jun 2019 16:18:45 -0400 | |
| changeset 479710 | d9f7c87aa3b474e99c789b91708b35a288366f26 |
| parent 479709 | 46fbd76b43e262194f58cbb015d022eee6104b7b |
| child 479711 | 51a70ac721c07aa77846d5320500960f15ee6fdb |
| push id | 113484 |
| push user | bballo@mozilla.com |
| push date | Fri, 21 Jun 2019 00:25:37 +0000 |
| treeherder | mozilla-inbound@d9f7c87aa3b4 [default view] [failures only] |
| perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
| reviewers | botond |
| bugs | 1213601 |
| milestone | 69.0a1 |
| first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
| last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -1817,18 +1817,18 @@ nsEventStatus AsyncPanZoomController::On } } } } return nsEventStatus_eConsumeNoDefault; } nsEventStatus AsyncPanZoomController::HandleEndOfPan() { - MOZ_ASSERT(GetCurrentTouchBlock()); - GetCurrentTouchBlock()->GetOverscrollHandoffChain()->FlushRepaints(); + MOZ_ASSERT(GetCurrentTouchBlock() || GetCurrentPanGestureBlock()); + GetCurrentInputBlock()->GetOverscrollHandoffChain()->FlushRepaints(); ParentLayerPoint flingVelocity = GetVelocityVector(); // Clear our velocities; if DispatchFling() gives the fling to us, // the fling velocity gets *added* to our existing velocity in // AcceptFling(). mX.SetVelocity(0); mY.SetVelocity(0); // Clear our state so that we don't stay in the PANNING state @@ -1840,29 +1840,29 @@ nsEventStatus AsyncPanZoomController::Ha APZC_LOG("%p starting a fling animation if %f >= %f\n", this, flingVelocity.Length().value, StaticPrefs::APZFlingMinVelocityThreshold()); if (flingVelocity.Length() < StaticPrefs::APZFlingMinVelocityThreshold()) { // Relieve overscroll now if needed, since we will not transition to a fling // animation and then an overscroll animation, and relieve it then. - GetCurrentTouchBlock() + GetCurrentInputBlock() ->GetOverscrollHandoffChain() ->SnapBackOverscrolledApzc(this); return nsEventStatus_eConsumeNoDefault; } // Make a local copy of the tree manager pointer and check that it's not // null before calling DispatchFling(). This is necessary because Destroy(), // which nulls out mTreeManager, could be called concurrently. if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) { const FlingHandoffState handoffState{ - flingVelocity, GetCurrentTouchBlock()->GetOverscrollHandoffChain(), - false /* not handoff */, GetCurrentTouchBlock()->GetScrolledApzc()}; + flingVelocity, GetCurrentInputBlock()->GetOverscrollHandoffChain(), + false /* not handoff */, GetCurrentInputBlock()->GetScrolledApzc()}; treeManagerLocal->DispatchFling(this, handoffState); } return nsEventStatus_eConsumeNoDefault; } bool AsyncPanZoomController::ConvertToGecko(const ScreenIntPoint& aPoint, LayoutDevicePoint* aOut) { if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) { @@ -2551,16 +2551,45 @@ nsEventStatus AsyncPanZoomController::On // Note that there is a multiplier that applies onto the "physical" pan // displacement (how much the user's fingers moved) that produces the // "logical" pan displacement (how much the page should move). For some of the // code below it makes more sense to use the physical displacement rather than // the logical displacement, and vice-versa. ScreenPoint physicalPanDisplacement = aEvent.mPanDisplacement; ParentLayerPoint logicalPanDisplacement = aEvent.UserMultipliedLocalPanDisplacement(); + if (aEvent.mDeltaType == PanGestureInput::PANDELTA_PAGE) { + // Pan events with page units are used by Gtk, so this replicates Gtk: + // https://gitlab.gnome.org/GNOME/gtk/blob/c734c7e9188b56f56c3a504abee05fa40c5475ac/gtk/gtkrange.c#L3065-3073 + CSSSize pageScrollSize; + CSSToParentLayerScale2D zoom; + { + // Grab the lock to access the frame metrics. + RecursiveMutexAutoLock lock(mRecursiveMutex); + pageScrollSize = mScrollMetadata.GetPageScrollAmount() / + Metrics().GetDevPixelsPerCSSPixel(); + zoom = Metrics().GetZoom(); + } + // scrollUnit* is in units of "ParentLayer pixels per page proportion"... + auto scrollUnitWidth = std::min(std::pow(pageScrollSize.width, 2.0 / 3.0), + pageScrollSize.width / 2.0) * + zoom.xScale; + auto scrollUnitHeight = std::min(std::pow(pageScrollSize.height, 2.0 / 3.0), + pageScrollSize.height / 2.0) * + zoom.yScale; + // ... and pan displacements are in units of "page proportion count" + // here, so the products of them and scrollUnit* are in ParentLayer pixels + ParentLayerPoint physicalPanDisplacementPL( + physicalPanDisplacement.x * scrollUnitWidth, + physicalPanDisplacement.y * scrollUnitHeight); + physicalPanDisplacement = ToScreenCoordinates(physicalPanDisplacementPL, + aEvent.mLocalPanStartPoint); + logicalPanDisplacement.x *= scrollUnitWidth; + logicalPanDisplacement.y *= scrollUnitHeight; + } MOZ_ASSERT(GetCurrentPanGestureBlock()); AdjustDeltaForAllowedScrollDirections( logicalPanDisplacement, GetCurrentPanGestureBlock()->GetAllowedScrollDirections()); // We need to update the axis velocity in order to get a useful display port // size and position. We need to do so even if this is a momentum pan (i.e. @@ -2604,16 +2633,22 @@ nsEventStatus AsyncPanZoomController::On APZC_LOG("%p got a pan-end in state %d\n", this, mState); // Call into OnPan in order to process any delta included in this event. OnPan(aEvent, true); mX.EndTouch(aEvent.mTime); mY.EndTouch(aEvent.mTime); + // Use HandleEndOfPan for fling on platforms that don't + // emit momentum events (Gtk). + if (aEvent.mSimulateMomentum) { + return HandleEndOfPan(); + } + // Drop any velocity on axes where we don't have room to scroll anyways // (in this APZC, or an APZC further in the handoff chain). // This ensures that we don't enlarge the display port unnecessarily. MOZ_ASSERT(GetCurrentPanGestureBlock()); RefPtr<const OverscrollHandoffChain> overscrollHandoffChain = GetCurrentPanGestureBlock()->GetOverscrollHandoffChain(); if (!overscrollHandoffChain->CanScrollInDirection( this, ScrollDirection::eHorizontal)) {
--- a/gfx/layers/ipc/LayersMessageUtils.h +++ b/gfx/layers/ipc/LayersMessageUtils.h @@ -162,35 +162,16 @@ struct ParamTraits<mozilla::layers::Comp WriteParam(msg, param.mHandle); } static bool Read(const Message* msg, PickleIterator* iter, paramType* result) { return ReadParam(msg, iter, &result->mHandle); } }; -// Helper class for reading bitfields. -// If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>. -template <typename ParamType> -struct BitfieldHelper { - // We need this helper because we can't get the address of a bitfield to - // pass directly to ReadParam. So instead we read it into a temporary bool - // and set the bitfield using a setter function - static bool ReadBoolForBitfield(const Message* aMsg, PickleIterator* aIter, - ParamType* aResult, - void (ParamType::*aSetter)(bool)) { - bool value; - if (ReadParam(aMsg, aIter, &value)) { - (aResult->*aSetter)(value); - return true; - } - return false; - } -}; - template <> struct ParamTraits<mozilla::layers::FrameMetrics> : BitfieldHelper<mozilla::layers::FrameMetrics> { typedef mozilla::layers::FrameMetrics paramType; static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, aParam.mScrollId); WriteParam(aMsg, aParam.mPresShellResolution);
--- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -1083,11 +1083,30 @@ struct CrossOriginPolicyValidator { } }; template <> struct ParamTraits<nsILoadInfo::CrossOriginPolicy> : EnumSerializer<nsILoadInfo::CrossOriginPolicy, CrossOriginPolicyValidator> {}; +// Helper class for reading bitfields. +// If T has bitfields members, derive ParamTraits<T> from BitfieldHelper<T>. +template <typename ParamType> +struct BitfieldHelper { + // We need this helper because we can't get the address of a bitfield to + // pass directly to ReadParam. So instead we read it into a temporary bool + // and set the bitfield using a setter function + static bool ReadBoolForBitfield(const Message* aMsg, PickleIterator* aIter, + ParamType* aResult, + void (ParamType::*aSetter)(bool)) { + bool value; + if (ReadParam(aMsg, aIter, &value)) { + (aResult->*aSetter)(value); + return true; + } + return false; + } +}; + } /* namespace IPC */ #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
--- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -401,16 +401,25 @@ VARCACHE_PREF( VARCACHE_PREF( Live, "apz.frame_delay.enabled", APZFrameDelayEnabled, RelaxedAtomicBool, false ) +#ifdef MOZ_WIDGET_GTK +VARCACHE_PREF( + Live, + "apz.gtk.kinetic_scroll.enabled", + APZGTKKineticScrollEnabled, + RelaxedAtomicBool, false +) +#endif + #if !defined(MOZ_WIDGET_ANDROID) # define PREF_VALUE true #else # define PREF_VALUE false #endif VARCACHE_PREF( Once, "apz.keyboard.enabled",
--- a/widget/InputData.cpp +++ b/widget/InputData.cpp @@ -432,17 +432,18 @@ PanGestureInput::PanGestureInput() mType(PANGESTURE_MAYSTART), mLineOrPageDeltaX(0), mLineOrPageDeltaY(0), mUserDeltaMultiplierX(1.0), mUserDeltaMultiplierY(1.0), mHandledByAPZ(false), mFollowedByMomentum(false), mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false), - mOverscrollBehaviorAllowsSwipe(false) {} + mOverscrollBehaviorAllowsSwipe(false), + mSimulateMomentum(false) {} PanGestureInput::PanGestureInput(PanGestureType aType, uint32_t aTime, TimeStamp aTimeStamp, const ScreenPoint& aPanStartPoint, const ScreenPoint& aPanDisplacement, Modifiers aModifiers) : InputData(PANGESTURE_INPUT, aTime, aTimeStamp, aModifiers), mType(aType), @@ -450,17 +451,18 @@ PanGestureInput::PanGestureInput(PanGest mPanDisplacement(aPanDisplacement), mLineOrPageDeltaX(0), mLineOrPageDeltaY(0), mUserDeltaMultiplierX(1.0), mUserDeltaMultiplierY(1.0), mHandledByAPZ(false), mFollowedByMomentum(false), mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(false), - mOverscrollBehaviorAllowsSwipe(false) {} + mOverscrollBehaviorAllowsSwipe(false), + mSimulateMomentum(false) {} bool PanGestureInput::IsMomentum() const { switch (mType) { case PanGestureInput::PANGESTURE_MOMENTUMSTART: case PanGestureInput::PANGESTURE_MOMENTUMPAN: case PanGestureInput::PANGESTURE_MOMENTUMEND: return true; default: @@ -472,37 +474,54 @@ WidgetWheelEvent PanGestureInput::ToWidg WidgetWheelEvent wheelEvent(true, eWheel, aWidget); wheelEvent.mModifiers = this->modifiers; wheelEvent.mTime = mTime; wheelEvent.mTimeStamp = mTimeStamp; wheelEvent.mRefPoint = RoundedToInt(ViewAs<LayoutDevicePixel>( mPanStartPoint, PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent)); wheelEvent.mButtons = 0; - wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL; wheelEvent.mMayHaveMomentum = true; // pan inputs may have momentum wheelEvent.mIsMomentum = IsMomentum(); wheelEvent.mLineOrPageDeltaX = mLineOrPageDeltaX; wheelEvent.mLineOrPageDeltaY = mLineOrPageDeltaY; wheelEvent.mDeltaX = mPanDisplacement.x; wheelEvent.mDeltaY = mPanDisplacement.y; wheelEvent.mFlags.mHandledByAPZ = mHandledByAPZ; wheelEvent.mFocusSequenceNumber = mFocusSequenceNumber; + if (mDeltaType == PanGestureInput::PANDELTA_PAGE) { + // Emulate legacy widget/gtk behavior + wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_LINE; + wheelEvent.mIsNoLineOrPageDelta = true; + wheelEvent.mScrollType = WidgetWheelEvent::SCROLL_ASYNCHRONOUSELY; + wheelEvent.mDeltaX *= 3; + wheelEvent.mDeltaY *= 3; + } else { + wheelEvent.mDeltaMode = WheelEvent_Binding::DOM_DELTA_PIXEL; + } return wheelEvent; } bool PanGestureInput::TransformToLocal( const ScreenToParentLayerMatrix4x4& aTransform) { Maybe<ParentLayerPoint> panStartPoint = UntransformBy(aTransform, mPanStartPoint); if (!panStartPoint) { return false; } mLocalPanStartPoint = *panStartPoint; + if (mDeltaType == PanGestureInput::PANDELTA_PAGE) { + // Skip transforming the pan displacement because we want + // raw page proportion counts. + mLocalPanDisplacement.x = mPanDisplacement.x; + mLocalPanDisplacement.y = mPanDisplacement.y; + return true; + } + Maybe<ParentLayerPoint> panDisplacement = UntransformVector(aTransform, mPanDisplacement, mPanStartPoint); if (!panDisplacement) { return false; } mLocalPanDisplacement = *panDisplacement; return true; }
--- a/widget/InputData.h +++ b/widget/InputData.h @@ -327,16 +327,27 @@ class PanGestureInput : public InputData // MomentumPan: The actual momentum motion by mPanDisplacement. PANGESTURE_MOMENTUMPAN, // MomentumEnd: The momentum animation has ended, for example because the // momentum velocity has gone below the stopping threshold, or because the // user has stopped the animation by putting their fingers on a touchpad. PANGESTURE_MOMENTUMEND )); + + MOZ_DEFINE_ENUM_AT_CLASS_SCOPE( + PanDeltaType, ( + // There are three kinds of scroll delta modes in Gecko: "page", "line" + // and "pixel". Touchpad pan gestures only support "page" and "pixel". + // + // NOTE: PANDELTA_PAGE currently replicates Gtk behavior + // (see AsyncPanZoomController::OnPan). + PANDELTA_PAGE, + PANDELTA_PIXEL + )); // clang-format on PanGestureInput(PanGestureType aType, uint32_t aTime, TimeStamp aTimeStamp, const ScreenPoint& aPanStartPoint, const ScreenPoint& aPanDisplacement, Modifiers aModifiers); bool IsMomentum() const; @@ -363,37 +374,49 @@ class PanGestureInput : public InputData // See lineOrPageDeltaX/Y on WidgetWheelEvent. int32_t mLineOrPageDeltaX; int32_t mLineOrPageDeltaY; // User-set delta multipliers. double mUserDeltaMultiplierX; double mUserDeltaMultiplierY; - bool mHandledByAPZ; + PanDeltaType mDeltaType = PANDELTA_PIXEL; + + bool mHandledByAPZ: 1; // true if this is a PANGESTURE_END event that will be followed by a // PANGESTURE_MOMENTUMSTART event. - bool mFollowedByMomentum; + bool mFollowedByMomentum: 1; // If this is true, and this event started a new input block that couldn't // find a scrollable target which is scrollable in the horizontal component // of the scroll start direction, then this input block needs to be put on // hold until a content response has arrived, even if the block has a // confirmed target. // This is used by events that can result in a swipe instead of a scroll. - bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection; + bool mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection: 1; // This is used by APZ to communicate to the macOS widget code whether // the overscroll-behavior of the scroll frame handling this swipe allows // non-local overscroll behaviors in the horizontal direction (such as // swipe navigation). - bool mOverscrollBehaviorAllowsSwipe; + bool mOverscrollBehaviorAllowsSwipe: 1; + + // true if APZ should do a fling animation after this pan ends, like + // it would with touchscreens. (For platforms that don't emit momentum events.) + bool mSimulateMomentum: 1; - // XXX: If adding any more bools, switch to using bitfields instead. + void SetHandledByAPZ(bool aHandled) { mHandledByAPZ = aHandled; } + void SetFollowedByMomentum(bool aFollowed) { mFollowedByMomentum = aFollowed; } + void SetRequiresContentResponseIfCannotScrollHorizontallyInStartDirection(bool aRequires) { + mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection = aRequires; + } + void SetOverscrollBehaviorAllowsSwipe(bool aAllows) { mOverscrollBehaviorAllowsSwipe = aAllows; } + void SetSimulateMomentum(bool aSimulate) { mSimulateMomentum = aSimulate; } }; /** * Encapsulation class for pinch events. In general, these will be generated by * a gesture listener by looking at SingleTouchData/MultiTouchInput instances * and determining whether or not the user was trying to do a gesture. */ class PinchGestureInput : public InputData {
--- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -114,16 +114,19 @@ using namespace mozilla::widget; #include "GLContextProvider.h" #include "mozilla/gfx/2D.h" #include "mozilla/gfx/HelpersCairo.h" #include "mozilla/gfx/GPUProcessManager.h" #include "mozilla/layers/CompositorBridgeParent.h" #include "mozilla/layers/CompositorThread.h" #include "mozilla/layers/KnowsCompositor.h" +#include "mozilla/layers/APZInputBridge.h" +#include "mozilla/layers/IAPZCTreeManager.h" + #ifdef MOZ_X11 # include "GLContextGLX.h" // for GLContextGLX::FindVisual() # include "GtkCompositorWidget.h" # include "gfxXlibSurface.h" # include "WindowSurfaceX11Image.h" # include "WindowSurfaceX11SHM.h" # include "WindowSurfaceXRender.h" #endif // MOZ_X11 @@ -3029,40 +3032,78 @@ gboolean nsWindow::OnKeyReleaseEvent(Gdk } void nsWindow::OnScrollEvent(GdkEventScroll* aEvent) { // check to see if we should rollup if (CheckForRollup(aEvent->x_root, aEvent->y_root, true, false)) return; #if GTK_CHECK_VERSION(3, 4, 0) // check for duplicate legacy scroll event, see GNOME bug 726878 if (aEvent->direction != GDK_SCROLL_SMOOTH && - mLastScrollEventTime == aEvent->time) + mLastScrollEventTime == aEvent->time) { + LOG(("[%d] duplicate legacy scroll event %d\n", aEvent->time, + aEvent->direction)); return; + } #endif WidgetWheelEvent wheelEvent(true, eWheel, this); wheelEvent.mDeltaMode = dom::WheelEvent_Binding::DOM_DELTA_LINE; switch (aEvent->direction) { #if GTK_CHECK_VERSION(3, 4, 0) case GDK_SCROLL_SMOOTH: { // As of GTK 3.4, all directional scroll events are provided by - // the GDK_SCROLL_SMOOTH direction on XInput2 devices. + // the GDK_SCROLL_SMOOTH direction on XInput2 and Wayland devices. mLastScrollEventTime = aEvent->time; + + // Special handling for touchpads to support flings + // (also known as kinetic/inertial/momentum scrolling) + GdkDevice* device = gdk_event_get_source_device((GdkEvent*)aEvent); + GdkInputSource source = gdk_device_get_source(device); + if (source == GDK_SOURCE_TOUCHSCREEN || source == GDK_SOURCE_TOUCHPAD) { + if (StaticPrefs::APZGTKKineticScrollEnabled() && + gtk_check_version(3, 20, 0) == nullptr) { + static auto sGdkEventIsScrollStopEvent = + (gboolean(*)(const GdkEvent*))dlsym( + RTLD_DEFAULT, "gdk_event_is_scroll_stop_event"); + + LOG(("[%d] pan smooth event dx=%f dy=%f inprogress=%d\n", + aEvent->time, aEvent->delta_x, aEvent->delta_y, mPanInProgress)); + PanGestureInput::PanGestureType eventType = + PanGestureInput::PANGESTURE_PAN; + if (sGdkEventIsScrollStopEvent((GdkEvent*)aEvent)) { + eventType = PanGestureInput::PANGESTURE_END; + mPanInProgress = false; + } else if (!mPanInProgress) { + eventType = PanGestureInput::PANGESTURE_START; + mPanInProgress = true; + } + + LayoutDeviceIntPoint touchPoint = GetRefPoint(this, aEvent); + PanGestureInput panEvent( + eventType, aEvent->time, GetEventTimeStamp(aEvent->time), + ScreenPoint(touchPoint.x, touchPoint.y), + ScreenPoint(aEvent->delta_x, aEvent->delta_y), + KeymapWrapper::ComputeKeyModifiers(aEvent->state)); + panEvent.mDeltaType = PanGestureInput::PANDELTA_PAGE; + panEvent.mSimulateMomentum = true; + + DispatchPanGestureInput(panEvent); + + return; + } + + // Older GTK doesn't support stop events, so we can't support fling + wheelEvent.mScrollType = WidgetWheelEvent::SCROLL_ASYNCHRONOUSELY; + } + // TODO - use a more appropriate scrolling unit than lines. // Multiply event deltas by 3 to emulate legacy behaviour. wheelEvent.mDeltaX = aEvent->delta_x * 3; wheelEvent.mDeltaY = aEvent->delta_y * 3; wheelEvent.mIsNoLineOrPageDelta = true; - // This next step manually unsets smooth scrolling for touch devices - // that trigger GDK_SCROLL_SMOOTH. We use the slave device, which - // represents the actual input. - GdkDevice* device = gdk_event_get_source_device((GdkEvent*)aEvent); - GdkInputSource source = gdk_device_get_source(device); - if (source == GDK_SOURCE_TOUCHSCREEN || source == GDK_SOURCE_TOUCHPAD) { - wheelEvent.mScrollType = WidgetWheelEvent::SCROLL_ASYNCHRONOUSELY; - } + break; } #endif case GDK_SCROLL_UP: wheelEvent.mDeltaY = wheelEvent.mLineOrPageDeltaY = -3; break; case GDK_SCROLL_DOWN: wheelEvent.mDeltaY = wheelEvent.mLineOrPageDeltaY = 3;
--- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -487,16 +487,18 @@ class nsWindow final : public nsBaseWidg nsSizeMode mSizeState; nsIntPoint mClientOffset; #if GTK_CHECK_VERSION(3, 4, 0) // This field omits duplicate scroll events caused by GNOME bug 726878. guint32 mLastScrollEventTime; + bool mPanInProgress = false; + // for touch event handling nsRefPtrHashtable<nsPtrHashKey<GdkEventSequence>, mozilla::dom::Touch> mTouches; #endif #ifdef MOZ_X11 Display* mXDisplay; Window mXWindow;
--- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -1127,16 +1127,39 @@ void nsBaseWidget::DispatchTouchInput(Mu } else { WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this); nsEventStatus status; DispatchEvent(&event, status); } } +void nsBaseWidget::DispatchPanGestureInput(PanGestureInput& aInput) { + MOZ_ASSERT(NS_IsMainThread()); + if (mAPZC) { + MOZ_ASSERT(APZThreadUtils::IsControllerThread()); + uint64_t inputBlockId = 0; + ScrollableLayerGuid guid; + + nsEventStatus result = + mAPZC->InputBridge()->ReceiveInputEvent(aInput, &guid, &inputBlockId); + if (result == nsEventStatus_eConsumeNoDefault) { + return; + } + + WidgetWheelEvent event = aInput.ToWidgetWheelEvent(this); + ProcessUntransformedAPZEvent(&event, guid, inputBlockId, result); + } else { + WidgetWheelEvent event = aInput.ToWidgetWheelEvent(this); + + nsEventStatus status; + DispatchEvent(&event, status); + } +} + nsEventStatus nsBaseWidget::DispatchInputEvent(WidgetInputEvent* aEvent) { MOZ_ASSERT(NS_IsMainThread()); if (mAPZC) { if (APZThreadUtils::IsControllerThread()) { uint64_t inputBlockId = 0; ScrollableLayerGuid guid; nsEventStatus result = mAPZC->InputBridge()->ReceiveInputEvent(
--- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -614,16 +614,24 @@ class nsBaseWidget : public nsIWidget, p /** * Dispatch the given MultiTouchInput through APZ to Gecko (if APZ is enabled) * or directly to gecko (if APZ is not enabled). This function must only * be called from the main thread, and if APZ is enabled, that must also be * the APZ controller thread. */ void DispatchTouchInput(mozilla::MultiTouchInput& aInput); + /** + * Dispatch the given PanGestureInput through APZ to Gecko (if APZ is enabled) + * or directly to gecko (if APZ is not enabled). This function must only + * be called from the main thread, and if APZ is enabled, that must also be + * the APZ controller thread. + */ + void DispatchPanGestureInput(mozilla::PanGestureInput& aInput); + #if defined(XP_WIN) void UpdateScrollCapture() override; /** * To be overridden by derived classes to return a snapshot that can be used * during scrolling. Returning null means we won't update the container. * @return an already AddRefed SourceSurface containing the snapshot */
--- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -1206,58 +1206,74 @@ struct ParamTraits<mozilla::MouseInput> template <> struct ParamTraits<mozilla::PanGestureInput::PanGestureType> : public ContiguousEnumSerializerInclusive< mozilla::PanGestureInput::PanGestureType, mozilla::PanGestureInput::PanGestureType::PANGESTURE_MAYSTART, mozilla::PanGestureInput::sHighestPanGestureType> {}; template <> -struct ParamTraits<mozilla::PanGestureInput> { +struct ParamTraits<mozilla::PanGestureInput::PanDeltaType> + : public ContiguousEnumSerializerInclusive< + mozilla::PanGestureInput::PanDeltaType, + mozilla::PanGestureInput::PanDeltaType::PANDELTA_PAGE, + mozilla::PanGestureInput::sHighestPanDeltaType> {}; + +template <> +struct ParamTraits<mozilla::PanGestureInput> + : BitfieldHelper<mozilla::PanGestureInput> { typedef mozilla::PanGestureInput paramType; static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, static_cast<const mozilla::InputData&>(aParam)); WriteParam(aMsg, aParam.mType); WriteParam(aMsg, aParam.mPanStartPoint); WriteParam(aMsg, aParam.mPanDisplacement); WriteParam(aMsg, aParam.mLocalPanStartPoint); WriteParam(aMsg, aParam.mLocalPanDisplacement); WriteParam(aMsg, aParam.mLineOrPageDeltaX); WriteParam(aMsg, aParam.mLineOrPageDeltaY); WriteParam(aMsg, aParam.mUserDeltaMultiplierX); WriteParam(aMsg, aParam.mUserDeltaMultiplierY); + WriteParam(aMsg, aParam.mDeltaType); WriteParam(aMsg, aParam.mHandledByAPZ); WriteParam(aMsg, aParam.mFollowedByMomentum); WriteParam( aMsg, aParam .mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection); WriteParam(aMsg, aParam.mOverscrollBehaviorAllowsSwipe); + WriteParam(aMsg, aParam.mSimulateMomentum); } static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) { return ReadParam(aMsg, aIter, static_cast<mozilla::InputData*>(aResult)) && ReadParam(aMsg, aIter, &aResult->mType) && ReadParam(aMsg, aIter, &aResult->mPanStartPoint) && ReadParam(aMsg, aIter, &aResult->mPanDisplacement) && ReadParam(aMsg, aIter, &aResult->mLocalPanStartPoint) && ReadParam(aMsg, aIter, &aResult->mLocalPanDisplacement) && ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaX) && ReadParam(aMsg, aIter, &aResult->mLineOrPageDeltaY) && ReadParam(aMsg, aIter, &aResult->mUserDeltaMultiplierX) && ReadParam(aMsg, aIter, &aResult->mUserDeltaMultiplierY) && - ReadParam(aMsg, aIter, &aResult->mHandledByAPZ) && - ReadParam(aMsg, aIter, &aResult->mFollowedByMomentum) && - ReadParam( - aMsg, aIter, - &aResult - ->mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection) && - ReadParam(aMsg, aIter, &aResult->mOverscrollBehaviorAllowsSwipe); + ReadParam(aMsg, aIter, &aResult->mDeltaType) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetHandledByAPZ) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetFollowedByMomentum) && + ReadBoolForBitfield( + aMsg, aIter, aResult, + ¶mType:: + SetRequiresContentResponseIfCannotScrollHorizontallyInStartDirection) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetOverscrollBehaviorAllowsSwipe) && + ReadBoolForBitfield(aMsg, aIter, aResult, + ¶mType::SetSimulateMomentum); } }; template <> struct ParamTraits<mozilla::PinchGestureInput::PinchGestureType> : public ContiguousEnumSerializerInclusive< mozilla::PinchGestureInput::PinchGestureType, mozilla::PinchGestureInput::PinchGestureType::PINCHGESTURE_START,