Bug 1260905 - Set a minimum bound on the velocity required for a fling to actually happen. r?rbarker
MozReview-Commit-ID: 11PFN06ZOz4
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -235,16 +235,22 @@ typedef GenericFlingAnimation FlingAnima
* \li\b apz.fling_friction
* Amount of friction applied during flings. This is used in the following
* formula: v(t1) = v(t0) * (1 - f)^(t1 - t0), where v(t1) is the velocity
* for a new sample, v(t0) is the velocity at the previous sample, f is the
* value of this pref, and (t1 - t0) is the amount of time, in milliseconds,
* that has elapsed between the two samples.\n
* NOTE: Not currently used in Android fling calculations.
*
+ * \li\b apz.fling_min_velocity_threshold
+ * Minimum velocity for a fling to actually kick off. If the user pans and lifts
+ * their finger such that the velocity is smaller than this amount, no fling
+ * is initiated.\n
+ * Units: screen pixels per millisecond
+ *
* \li\b apz.fling_stop_on_tap_threshold
* When flinging, if the velocity is above this number, then a tap on the
* screen will stop the fling without dispatching a tap to content. If the
* velocity is below this threshold a tap will also be dispatched.
* Note: when modifying this pref be sure to run the APZC gtests as some of
* them depend on the value of this pref.\n
* Units: screen pixels per millisecond
*
@@ -1235,17 +1241,24 @@ nsEventStatus AsyncPanZoomController::On
mX.SetVelocity(0);
mY.SetVelocity(0);
// Clear our state so that we don't stay in the PANNING state
// if DispatchFling() gives the fling to somone else. However,
// don't send the state change notification until we've determined
// what our final state is to avoid notification churn.
StateChangeNotificationBlocker blocker(this);
SetState(NOTHING);
- APZC_LOG("%p starting a fling animation\n", this);
+
+ APZC_LOG("%p starting a fling animation if %f > %f\n", this,
+ flingVelocity.Length(), gfxPrefs::APZFlingMinVelocityThreshold());
+
+ if (flingVelocity.Length() <= gfxPrefs::APZFlingMinVelocityThreshold()) {
+ 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()) {
FlingHandoffState handoffState{flingVelocity,
CurrentTouchBlock()->GetOverscrollHandoffChain(),
false /* not handoff */,
CurrentTouchBlock()->GetScrolledApzc()};
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -151,16 +151,17 @@ private:
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
DECL_GFX_PREF(Live, "apz.fling_accel_supplemental_mult", APZFlingAccelSupplementalMultiplier, float, 1.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_x1", APZCurveFunctionX1, float, 0.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_x2", APZCurveFunctionX2, float, 1.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_y1", APZCurveFunctionY1, float, 0.0f);
DECL_GFX_PREF(Once, "apz.fling_curve_function_y2", APZCurveFunctionY2, float, 1.0f);
DECL_GFX_PREF(Live, "apz.fling_curve_threshold_inches_per_ms", APZCurveThreshold, float, -1.0f);
DECL_GFX_PREF(Live, "apz.fling_friction", APZFlingFriction, float, 0.002f);
+ DECL_GFX_PREF(Live, "apz.fling_min_velocity_threshold", APZFlingMinVelocityThreshold, float, 0.5f);
DECL_GFX_PREF(Live, "apz.fling_stop_on_tap_threshold", APZFlingStopOnTapThreshold, float, 0.05f);
DECL_GFX_PREF(Live, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f);
DECL_GFX_PREF(Live, "apz.highlight_checkerboarded_areas", APZHighlightCheckerboardedAreas, bool, false);
DECL_GFX_PREF(Live, "apz.max_velocity_inches_per_ms", APZMaxVelocity, float, -1.0f);
DECL_GFX_PREF(Once, "apz.max_velocity_queue_size", APZMaxVelocityQueueSize, uint32_t, 5);
DECL_GFX_PREF(Live, "apz.min_skate_speed", APZMinSkateSpeed, float, 1.0f);
DECL_GFX_PREF(Live, "apz.minimap.enabled", APZMinimap, bool, false);
DECL_GFX_PREF(Live, "apz.minimap.visibility.enabled", APZMinimapVisibilityEnabled, bool, false);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -607,16 +607,17 @@ pref("apz.fling_accel_base_mult", "1.0")
pref("apz.fling_accel_interval_ms", 500);
pref("apz.fling_accel_supplemental_mult", "1.0");
pref("apz.fling_curve_function_x1", "0.0");
pref("apz.fling_curve_function_y1", "0.0");
pref("apz.fling_curve_function_x2", "1.0");
pref("apz.fling_curve_function_y2", "1.0");
pref("apz.fling_curve_threshold_inches_per_ms", "-1.0");
pref("apz.fling_friction", "0.002");
+pref("apz.fling_min_velocity_threshold", "0.5");
pref("apz.fling_stop_on_tap_threshold", "0.05");
pref("apz.fling_stopped_threshold", "0.01");
pref("apz.highlight_checkerboarded_areas", false);
pref("apz.max_velocity_inches_per_ms", "-1.0");
pref("apz.max_velocity_queue_size", 5);
pref("apz.min_skate_speed", "1.0");
pref("apz.minimap.enabled", false);
pref("apz.minimap.visibility.enabled", false);