diff --git a/gfx/layers/apz/test/mochitest/test_group_scroll_snap.html b/gfx/layers/apz/test/mochitest/test_group_scroll_snap.html index ea288ebf7e47..9a1341c503ef 100644 --- a/gfx/layers/apz/test/mochitest/test_group_scroll_snap.html +++ b/gfx/layers/apz/test/mochitest/test_group_scroll_snap.html @@ -44,6 +44,8 @@ const subtests = [ "prefs": [["layout.css.scroll-behavior.spring-constant", 1000], // Avoid fling at the end of pan. ["apz.fling_min_velocity_threshold", "10000"], + // This test needs mSimilateMomentum flag on headless mode. + ["apz.test.headless.simulate_momentum", true], ["apz.gtk.kinetic_scroll.enabled", true], // Use the pixel mode to make the test predictable easily. ["apz.gtk.kinetic_scroll.delta_mode", 2], diff --git a/widget/headless/HeadlessWidget.cpp b/widget/headless/HeadlessWidget.cpp index c1fbcccc93d9..340cb723bd4d 100644 --- a/widget/headless/HeadlessWidget.cpp +++ b/widget/headless/HeadlessWidget.cpp @@ -12,6 +12,7 @@ #include "mozilla/ClearOnShutdown.h" #include "mozilla/Maybe.h" #include "mozilla/NativeKeyBindingsType.h" +#include "mozilla/Preferences.h" #include "mozilla/TextEventDispatcher.h" #include "mozilla/TextEvents.h" #include "mozilla/WritingModes.h" @@ -545,13 +546,14 @@ nsresult HeadlessWidget::SynthesizeNativeTouchPadPinch( return NS_ERROR_INVALID_ARG; } - LayoutDeviceIntPoint touchpadPoint = aPoint - WidgetToScreenOffset(); + ScreenPoint touchpadPoint = ViewAs( + aPoint - WidgetToScreenOffset(), + PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent); // The headless widget does not support modifiers. // Do not pass `aModifierFlags` because it contains native modifier values. PinchGestureInput inputToDispatch( pinchGestureType, PinchGestureInput::TRACKPAD, PR_IntervalNow(), - TimeStamp::Now(), ExternalPoint(0, 0), - ScreenPoint(touchpadPoint.x, touchpadPoint.y), + TimeStamp::Now(), ExternalPoint(0, 0), touchpadPoint, 100.0 * ((aEventPhase == PHASE_END) ? ScreenCoord(1.f) : CurrentSpan), 100.0 * ((aEventPhase == PHASE_END) ? ScreenCoord(1.f) : PreviousSpan), 0); @@ -564,5 +566,47 @@ nsresult HeadlessWidget::SynthesizeNativeTouchPadPinch( DispatchPinchGestureInput(inputToDispatch); return NS_OK; } + +nsresult HeadlessWidget::SynthesizeNativeTouchpadPan( + TouchpadGesturePhase aEventPhase, LayoutDeviceIntPoint aPoint, + double aDeltaX, double aDeltaY, int32_t aModifierFlags, + nsIObserver* aObserver) { + AutoObserverNotifier notifier(aObserver, "touchpadpanevent"); + + MOZ_ASSERT(NS_IsMainThread()); + + PanGestureInput::PanGestureType eventType = PanGestureInput::PANGESTURE_PAN; + switch (aEventPhase) { + case PHASE_BEGIN: + eventType = PanGestureInput::PANGESTURE_START; + break; + case PHASE_UPDATE: + eventType = PanGestureInput::PANGESTURE_PAN; + break; + case PHASE_END: + eventType = PanGestureInput::PANGESTURE_END; + break; + default: + return NS_ERROR_INVALID_ARG; + } + + ScreenPoint touchpadPoint = ViewAs( + aPoint - WidgetToScreenOffset(), + PixelCastJustification::LayoutDeviceIsScreenForUntransformedEvent); + PanGestureInput input(eventType, PR_IntervalNow(), TimeStamp::Now(), + touchpadPoint, + ScreenPoint(float(aDeltaX), float(aDeltaY)), + // Same as SynthesizeNativeTouchPadPinch case we ignore + // aModifierFlags. + 0); + + input.mSimulateMomentum = + Preferences::GetBool("apz.test.headless.simulate_momentum"); + + DispatchPanGestureInput(input); + + return NS_OK; +} + } // namespace widget } // namespace mozilla diff --git a/widget/headless/HeadlessWidget.h b/widget/headless/HeadlessWidget.h index 2b80eea70e58..b77ec632a90f 100644 --- a/widget/headless/HeadlessWidget.h +++ b/widget/headless/HeadlessWidget.h @@ -135,6 +135,12 @@ class HeadlessWidget : public nsBaseWidget { TouchpadGesturePhase aEventPhase, float aScale, LayoutDeviceIntPoint aPoint, int32_t aModifierFlags) override; + virtual nsresult SynthesizeNativeTouchpadPan(TouchpadGesturePhase aEventPhase, + LayoutDeviceIntPoint aPoint, + double aDeltaX, double aDeltaY, + int32_t aModifierFlags, + nsIObserver* aObserver) override; + private: ~HeadlessWidget(); bool mEnabled;