Bug 1348786 - Move SwipeTracker class as reusable for other platforms. r=tnikkel

Differential Revision: https://phabricator.services.mozilla.com/D134361
This commit is contained in:
Hiroyuki Ikezoe 2022-01-05 09:08:05 +00:00
parent a5acf54206
commit 0f2ffcf2af
9 changed files with 59 additions and 35 deletions

View File

@ -13,11 +13,12 @@
#include "mozilla/TouchEvents.h"
#include "mozilla/dom/SimpleGestureEventBinding.h"
#include "nsAlgorithm.h"
#include "nsChildView.h"
#include "nsIWidget.h"
#include "nsRefreshDriver.h"
#include "UnitTransforms.h"
// These values were tweaked to make the physics feel similar to the native swipe.
// These values were tweaked to make the physics feel similar to the native
// swipe.
static const double kSpringForce = 250.0;
static const double kVelocityTwitchTolerance = 0.0000001;
static const double kWholePagePixelSize = 550.0;
@ -29,14 +30,19 @@ namespace mozilla {
static already_AddRefed<nsRefreshDriver> GetRefreshDriver(nsIWidget& aWidget) {
nsIWidgetListener* widgetListener = aWidget.GetWidgetListener();
PresShell* presShell = widgetListener ? widgetListener->GetPresShell() : nullptr;
nsPresContext* presContext = presShell ? presShell->GetPresContext() : nullptr;
RefPtr<nsRefreshDriver> refreshDriver = presContext ? presContext->RefreshDriver() : nullptr;
PresShell* presShell =
widgetListener ? widgetListener->GetPresShell() : nullptr;
nsPresContext* presContext =
presShell ? presShell->GetPresContext() : nullptr;
RefPtr<nsRefreshDriver> refreshDriver =
presContext ? presContext->RefreshDriver() : nullptr;
return refreshDriver.forget();
}
SwipeTracker::SwipeTracker(nsChildView& aWidget, const PanGestureInput& aSwipeStartEvent,
uint32_t aAllowedDirections, uint32_t aSwipeDirection)
SwipeTracker::SwipeTracker(nsIWidget& aWidget,
const PanGestureInput& aSwipeStartEvent,
uint32_t aAllowedDirections,
uint32_t aSwipeDirection)
: mWidget(aWidget),
mRefreshDriver(GetRefreshDriver(mWidget)),
mAxis(0.0, 0.0, 0.0, kSpringForce, 1.0),
@ -58,18 +64,27 @@ SwipeTracker::SwipeTracker(nsChildView& aWidget, const PanGestureInput& aSwipeSt
void SwipeTracker::Destroy() { UnregisterFromRefreshDriver(); }
SwipeTracker::~SwipeTracker() {
MOZ_ASSERT(!mRegisteredWithRefreshDriver, "Destroy needs to be called before deallocating");
MOZ_ASSERT(!mRegisteredWithRefreshDriver,
"Destroy needs to be called before deallocating");
}
double SwipeTracker::SwipeSuccessTargetValue() const {
return (mSwipeDirection == dom::SimpleGestureEvent_Binding::DIRECTION_RIGHT) ? -1.0 : 1.0;
return (mSwipeDirection == dom::SimpleGestureEvent_Binding::DIRECTION_RIGHT)
? -1.0
: 1.0;
}
double SwipeTracker::ClampToAllowedRange(double aGestureAmount) const {
// gestureAmount needs to stay between -1 and 0 when swiping right and
// between 0 and 1 when swiping left.
double min = (mSwipeDirection == dom::SimpleGestureEvent_Binding::DIRECTION_RIGHT) ? -1.0 : 0.0;
double max = (mSwipeDirection == dom::SimpleGestureEvent_Binding::DIRECTION_LEFT) ? 1.0 : 0.0;
double min =
(mSwipeDirection == dom::SimpleGestureEvent_Binding::DIRECTION_RIGHT)
? -1.0
: 0.0;
double max =
(mSwipeDirection == dom::SimpleGestureEvent_Binding::DIRECTION_LEFT)
? 1.0
: 0.0;
return clamped(aGestureAmount, min, max);
}
@ -97,15 +112,18 @@ nsEventStatus SwipeTracker::ProcessEvent(const PanGestureInput& aEvent) {
aEvent.mType == PanGestureInput::PANGESTURE_START) {
mEventsHaveStartedNewGesture = true;
}
return mEventsHaveStartedNewGesture ? nsEventStatus_eIgnore : nsEventStatus_eConsumeNoDefault;
return mEventsHaveStartedNewGesture ? nsEventStatus_eIgnore
: nsEventStatus_eConsumeNoDefault;
}
double delta = -aEvent.mPanDisplacement.x / mWidget.GetDefaultScaleInternal() / kWholePagePixelSize;
double delta = -aEvent.mPanDisplacement.x /
mWidget.GetDefaultScaleInternal() / kWholePagePixelSize;
mGestureAmount = ClampToAllowedRange(mGestureAmount + delta);
SendSwipeEvent(eSwipeGestureUpdate, 0, mGestureAmount, aEvent.mTimeStamp);
if (aEvent.mType != PanGestureInput::PANGESTURE_END) {
double elapsedSeconds = std::max(0.008, (aEvent.mTimeStamp - mLastEventTimeStamp).ToSeconds());
double elapsedSeconds =
std::max(0.008, (aEvent.mTimeStamp - mLastEventTimeStamp).ToSeconds());
mCurrentVelocity = delta / elapsedSeconds;
mLastEventTimeStamp = aEvent.mTimeStamp;
} else {
@ -135,7 +153,8 @@ void SwipeTracker::StartAnimating(double aTargetValue) {
// unregister ourselves.
MOZ_ASSERT(!mRegisteredWithRefreshDriver);
if (mRefreshDriver) {
mRefreshDriver->AddRefreshObserver(this, FlushType::Style, "Swipe animation");
mRefreshDriver->AddRefreshObserver(this, FlushType::Style,
"Swipe animation");
mRegisteredWithRefreshDriver = true;
}
}
@ -173,8 +192,8 @@ void SwipeTracker::UnregisterFromRefreshDriver() {
}
/* static */ WidgetSimpleGestureEvent SwipeTracker::CreateSwipeGestureEvent(
EventMessage aMsg, nsIWidget* aWidget, const LayoutDeviceIntPoint& aPosition,
const TimeStamp& aTimeStamp) {
EventMessage aMsg, nsIWidget* aWidget,
const LayoutDeviceIntPoint& aPosition, const TimeStamp& aTimeStamp) {
// XXX Why isn't this initialized with nsCocoaUtils::InitInputEvent()?
WidgetSimpleGestureEvent geckoEvent(true, aMsg, aWidget);
geckoEvent.mModifiers = 0;
@ -185,8 +204,8 @@ void SwipeTracker::UnregisterFromRefreshDriver() {
return geckoEvent;
}
bool SwipeTracker::SendSwipeEvent(EventMessage aMsg, uint32_t aDirection, double aDelta,
const TimeStamp& aTimeStamp) {
bool SwipeTracker::SendSwipeEvent(EventMessage aMsg, uint32_t aDirection,
double aDelta, const TimeStamp& aTimeStamp) {
WidgetSimpleGestureEvent geckoEvent =
CreateSwipeGestureEvent(aMsg, &mWidget, mEventPosition, aTimeStamp);
geckoEvent.mDirection = aDirection;

View File

@ -14,7 +14,6 @@
#include "nsRefreshObservers.h"
#include "Units.h"
class nsChildView;
class nsIWidget;
class nsRefreshDriver;
@ -50,7 +49,7 @@ class SwipeTracker final : public nsARefreshObserver {
public:
NS_INLINE_DECL_REFCOUNTING(SwipeTracker, override)
SwipeTracker(nsChildView& aWidget, const PanGestureInput& aSwipeStartEvent,
SwipeTracker(nsIWidget& aWidget, const PanGestureInput& aSwipeStartEvent,
uint32_t aAllowedDirections, uint32_t aSwipeDirection);
void Destroy();
@ -80,7 +79,7 @@ class SwipeTracker final : public nsARefreshObserver {
bool SendSwipeEvent(EventMessage aMsg, uint32_t aDirection, double aDelta,
const TimeStamp& aTimeStamp);
nsChildView& mWidget;
nsIWidget& mWidget;
RefPtr<nsRefreshDriver> mRefreshDriver;
layers::AxisPhysicsMSDModel mAxis;
const LayoutDeviceIntPoint mEventPosition;

View File

@ -80,7 +80,6 @@ UNIFIED_SOURCES += [
"nsWindowMap.mm",
"OSXNotificationCenter.mm",
"ScreenHelperCocoa.mm",
"SwipeTracker.mm",
"TextInputHandler.mm",
"VibrancyManager.mm",
"ViewRegion.mm",

View File

@ -46,7 +46,6 @@ class GLPresenter;
namespace mozilla {
class InputData;
class PanGestureInput;
class SwipeTracker;
struct SwipeEventQueue;
class VibrancyManager;
namespace layers {
@ -485,8 +484,6 @@ class nsChildView final : public nsBaseWidget {
LayoutDeviceIntPoint aScreenPosition,
mozilla::Modifiers aModifiers);
void SwipeFinished();
// Called when the main thread enters a phase during which visual changes
// are imminent and any layer updates on the compositor thread would interfere
// with visual atomicity.
@ -583,7 +580,6 @@ class nsChildView final : public nsBaseWidget {
LayoutDeviceIntRegion mContentLayerInvalidRegion;
mozilla::UniquePtr<mozilla::VibrancyManager> mVibrancyManager;
RefPtr<mozilla::SwipeTracker> mSwipeTracker;
mozilla::UniquePtr<mozilla::SwipeEventQueue> mSwipeEventQueue;
RefPtr<mozilla::CancelableRunnable> mUnsuspendAsyncCATransactionsRunnable;

View File

@ -18,6 +18,7 @@
#include "mozilla/MiscEvents.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/PresShell.h"
#include "mozilla/SwipeTracker.h"
#include "mozilla/TextEventDispatcher.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
@ -105,7 +106,6 @@
#include "mozilla/layers/ChromeProcessController.h"
#include "nsLayoutUtils.h"
#include "InputData.h"
#include "SwipeTracker.h"
#include "VibrancyManager.h"
#include "nsNativeThemeCocoa.h"
#include "nsIDOMWindowUtils.h"
@ -239,11 +239,6 @@ nsChildView::nsChildView()
mCurrentPanGestureBelongsToSwipe{false} {}
nsChildView::~nsChildView() {
if (mSwipeTracker) {
mSwipeTracker->Destroy();
mSwipeTracker = nullptr;
}
// Notify the children that we're gone. childView->ResetParent() can change
// our list of children while it's being iterated, so the way we iterate the
// list must allow for this.
@ -1866,8 +1861,6 @@ void nsChildView::TrackScrollEventAsSwipe(const mozilla::PanGestureInput& aSwipe
}
}
void nsChildView::SwipeFinished() { mSwipeTracker = nullptr; }
void nsChildView::UpdateBoundsFromView() {
auto oldSize = mBounds.Size();
mBounds = CocoaPointsToDevPixels([mView frame]);

View File

@ -152,6 +152,7 @@ EXPORTS.mozilla += [
"LookAndFeel.h",
"MiscEvents.h",
"MouseEvents.h",
"SwipeTracker.h",
"TextEventDispatcher.h",
"TextEventDispatcherListener.h",
"TextEvents.h",
@ -219,6 +220,7 @@ UNIFIED_SOURCES += [
"ScrollbarDrawingWin.cpp",
"ScrollbarDrawingWin11.cpp",
"SharedWidgetUtils.cpp",
"SwipeTracker.cpp",
"TextEventDispatcher.cpp",
"ThemeColors.cpp",
"ThemeDrawing.cpp",

View File

@ -12,6 +12,7 @@
#include "GLConsts.h"
#include "InputData.h"
#include "LiveResizeListener.h"
#include "SwipeTracker.h"
#include "TouchEvents.h"
#include "WritingModes.h"
#include "X11UndefineNone.h"
@ -414,6 +415,11 @@ void nsBaseWidget::FreeLocalesChangedObserver() {
//-------------------------------------------------------------------------
nsBaseWidget::~nsBaseWidget() {
if (mSwipeTracker) {
mSwipeTracker->Destroy();
mSwipeTracker = nullptr;
}
IMEStateManager::WidgetDestroyed(this);
FreeLocalesChangedObserver();
@ -2040,6 +2046,8 @@ nsresult nsBaseWidget::AsyncEnableDragDrop(bool aEnable) {
kAsyncDragDropTimeout, EventQueuePriority::Idle);
}
void nsBaseWidget::SwipeFinished() { mSwipeTracker = nullptr; }
const IMENotificationRequests& nsIWidget::IMENotificationRequestsRef() {
TextEventDispatcher* dispatcher = GetTextEventDispatcher();
return dispatcher->IMENotificationRequestsRef();

View File

@ -38,6 +38,7 @@ namespace mozilla {
class CompositorVsyncDispatcher;
class LiveResizeListener;
class FallbackRenderer;
class SwipeTracker;
#ifdef ACCESSIBILITY
namespace a11y {
@ -324,6 +325,8 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
bool AsyncPanZoomEnabled() const override;
void SwipeFinished() override;
void NotifyWindowDestroyed();
void NotifySizeMoveDone();
void NotifyWindowMoved(int32_t aX, int32_t aY);
@ -680,6 +683,7 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
RefPtr<WidgetShutdownObserver> mShutdownObserver;
RefPtr<LocalesChangedObserver> mLocalesChangedObserver;
RefPtr<TextEventDispatcher> mTextEventDispatcher;
RefPtr<mozilla::SwipeTracker> mSwipeTracker;
Cursor mCursor;
nsBorderStyle mBorderStyle;
LayoutDeviceIntRect mBounds;

View File

@ -1366,6 +1366,10 @@ class nsIWidget : public nsISupports {
*/
virtual bool AsyncPanZoomEnabled() const = 0;
/**
*/
virtual void SwipeFinished() = 0;
/**
* Enables the dropping of files to a widget.
*/