Bug 1275604 - Make the touch-action pref live. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 01 Jun 2016 13:13:14 -0400
changeset 338980 ece66ce5876bcdb00e7d5309fcc4b848390c9739
parent 338979 b5cb31afe51c2e53860a0675e97e52d80fc1908f
child 338981 fb962918980932c9a48d03c50fe0c10bd4aec955
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1275604
milestone49.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
Bug 1275604 - Make the touch-action pref live. r=botond As part of making the pref live, we need to ensure that if the pref is flipped while an input block is in the input queue, the behaviour that results is reasonable. In particular, if a touch block is created while touch-action is disabled, but the pref is enabled while that block is in the queue, it may suddenly go from IsReadyForHandling() returning true to IsReadyForHandling() returning false. This can result in the block getting stuck in the queue and preventing future touch blocks from being processed at all. To handle this case, we explicitly set the mAllowedTouchBehaviorSet flag to true if the block is created with touch-action disabled. This prevents IsReadyForHandling() from flipping to false in these cases. MozReview-Commit-ID: CJq9NtMF1Bq
gfx/layers/apz/src/InputBlockState.cpp
gfx/thebes/gfxPrefs.h
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -734,16 +734,19 @@ TouchBlockState::TouchBlockState(const R
   : CancelableBlockState(aTargetApzc, aTargetConfirmed)
   , mAllowedTouchBehaviorSet(false)
   , mDuringFastFling(false)
   , mSingleTapOccurred(false)
   , mInSlop(false)
   , mTouchCounter(aCounter)
 {
   TBS_LOG("Creating %p\n", this);
+  if (!gfxPrefs::TouchActionEnabled()) {
+    mAllowedTouchBehaviorSet = true;
+  }
 }
 
 bool
 TouchBlockState::SetAllowedTouchBehaviors(const nsTArray<TouchBehaviorFlags>& aBehaviors)
 {
   if (mAllowedTouchBehaviorSet) {
     return false;
   }
@@ -773,27 +776,34 @@ TouchBlockState::CopyPropertiesFrom(cons
   }
   mTransformToApzc = aOther.mTransformToApzc;
 }
 
 bool
 TouchBlockState::HasReceivedAllContentNotifications() const
 {
   return CancelableBlockState::HasReceivedAllContentNotifications()
+      // See comment in TouchBlockState::IsReadyforHandling()
       && (!gfxPrefs::TouchActionEnabled() || mAllowedTouchBehaviorSet);
 }
 
 bool
 TouchBlockState::IsReadyForHandling() const
 {
   if (!CancelableBlockState::IsReadyForHandling()) {
     return false;
   }
 
   if (!gfxPrefs::TouchActionEnabled()) {
+    // If TouchActionEnabled() was false when this block was created, then
+    // mAllowedTouchBehaviorSet is guaranteed to the true. However, the pref
+    // may have been flipped to false after the block was created. In that case,
+    // we should eventually get the touch-behaviour notification, or expire the
+    // content response timeout, but we don't really need to wait for those,
+    // since we don't care about the touch-behaviour values any more.
     return true;
   }
 
   return mAllowedTouchBehaviorSet || IsContentResponseTimerExpired();
 }
 
 void
 TouchBlockState::SetDuringFastFling()
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -396,17 +396,17 @@ private:
   DECL_GFX_PREF(Live, "layers.single-tile.enabled",            LayersSingleTileEnabled, bool, true);
 
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled",    ScrollBehaviorEnabled, bool, false);
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.spring-constant", ScrollBehaviorSpringConstant, float, 250.0f);
   DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-max-velocity", ScrollSnapPredictionMaxVelocity, int32_t, 2000);
   DECL_GFX_PREF(Live, "layout.css.scroll-snap.prediction-sensitivity", ScrollSnapPredictionSensitivity, float, 0.750f);
   DECL_GFX_PREF(Live, "layout.css.scroll-snap.proximity-threshold", ScrollSnapProximityThreshold, int32_t, 200);
-  DECL_GFX_PREF(Once, "layout.css.touch_action.enabled",       TouchActionEnabled, bool, false);
+  DECL_GFX_PREF(Live, "layout.css.touch_action.enabled",       TouchActionEnabled, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.dump",              LayoutDumpDisplayList, bool, false);
   DECL_GFX_PREF(Live, "layout.display-list.dump-content",      LayoutDumpDisplayListContent, bool, false);
   DECL_GFX_PREF(Live, "layout.event-regions.enabled",          LayoutEventRegionsEnabledDoNotUseDirectly, bool, false);
   DECL_GFX_PREF(Once, "layout.frame_rate",                     LayoutFrameRate, int32_t, -1);
   DECL_GFX_PREF(Once, "layout.paint_rects_separately",         LayoutPaintRectsSeparately, bool, true);
 
   // This and code dependent on it should be removed once containerless scrolling looks stable.
   DECL_GFX_PREF(Once, "layout.scroll.root-frame-containers",   LayoutUseContainersForRootFrames, bool, true);