Bug 1180295 - Ensure we don't scroll past the end of the page. r=rbarker
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 18 Aug 2015 14:27:20 -0400
changeset 258275 8573249b176e7039c2bb85040e6a9f7f8f180bee
parent 258274 893b1381755ab40c5b7dd22fd8f129e60cdb1d71
child 258276 f2a739dbce5f4b1377382715b814b14307e17087
push id29249
push userryanvm@gmail.com
push dateWed, 19 Aug 2015 11:17:27 +0000
treeherdermozilla-central@706b23a03d1c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrbarker
bugs1180295
milestone43.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 1180295 - Ensure we don't scroll past the end of the page. r=rbarker
mobile/android/base/gfx/Axis.java
mobile/android/base/gfx/DynamicToolbarAnimator.java
mobile/android/base/gfx/GeckoLayerClient.java
mobile/android/base/gfx/JavaPanZoomController.java
mobile/android/base/gfx/PanZoomTarget.java
--- a/mobile/android/base/gfx/Axis.java
+++ b/mobile/android/base/gfx/Axis.java
@@ -201,16 +201,17 @@ abstract class Axis {
     private float mLastFlingVelocity;
 
     private FlingStates mFlingState = FlingStates.STOPPED; /* The fling state we're in on this axis. */
 
     protected abstract float getOrigin();
     protected abstract float getViewportLength();
     protected abstract float getPageStart();
     protected abstract float getPageLength();
+    protected abstract float getVisibleEndOfLayerView();
 
     Axis(SubdocumentScrollHelper subscroller) {
         mSubscroller = subscroller;
         mOverscrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS;
         mRecentVelocities = new float[FLING_VELOCITY_POINTS];
     }
 
     // Implementors can override these to show effects when the axis overscrolls
@@ -494,18 +495,18 @@ abstract class Axis {
         // to remove any excess. Using getExcess alone isn't enough here since it relies on
         // getOverscroll which doesn't take into account any new displacment being applied.
         // If we using a subscroller, we don't want to alter the scrolling being done
         if (getOverScrollMode() == View.OVER_SCROLL_NEVER && !mSubscroller.scrolling()) {
             float originalDisplacement = mDisplacement;
 
             if (mDisplacement + getOrigin() < getPageStart()) {
                 mDisplacement = getPageStart() - getOrigin();
-            } else if (mDisplacement + getViewportEnd() > getPageEnd()) {
-                mDisplacement = getPageEnd() - getViewportEnd();
+            } else if (mDisplacement + getOrigin() + getVisibleEndOfLayerView() > getPageEnd()) {
+                mDisplacement = getPageEnd() - getOrigin() - getVisibleEndOfLayerView();
             }
 
             // Return the amount of overscroll so that the overscroll controller can draw it for us
             if (originalDisplacement != mDisplacement) {
                 if (mFlingState == FlingStates.FLINGING) {
                     overscrollFling(mVelocity / MS_PER_FRAME * 1000);
                     stopFling();
                 } else if (mFlingState == FlingStates.PANNING) {
--- a/mobile/android/base/gfx/DynamicToolbarAnimator.java
+++ b/mobile/android/base/gfx/DynamicToolbarAnimator.java
@@ -326,16 +326,21 @@ public class DynamicToolbarAnimator {
             return false;
         }
 
         fireListeners();
         mTarget.getView().requestRender();
         return true;
     }
 
+    public PointF getVisibleEndOfLayerView() {
+        return new PointF(mTarget.getView().getWidth(),
+            mTarget.getView().getHeight() - mMaxTranslation + mLayerViewTranslation);
+    }
+
     private float bottomOfCssViewport(ImmutableViewportMetrics aMetrics) {
         return aMetrics.getHeight() + mMaxTranslation - mLayerViewTranslation;
     }
 
     void populateFixedPositionMargins(ViewTransform aTransform, ImmutableViewportMetrics aMetrics) {
         Log.v(LOGTAG, "Populating top fixed margin using " + mLayerViewTranslation + " - " + mToolbarTranslation);
         aTransform.fixedLayerMarginTop = mLayerViewTranslation - mToolbarTranslation;
         float bottomOfScreen = mTarget.getView().getHeight();
--- a/mobile/android/base/gfx/GeckoLayerClient.java
+++ b/mobile/android/base/gfx/GeckoLayerClient.java
@@ -743,16 +743,22 @@ class GeckoLayerClient implements LayerV
     /** Implementation of PanZoomTarget */
     @Override
     public FullScreenState getFullScreenState() {
         return mView.getFullScreenState();
     }
 
     /** Implementation of PanZoomTarget */
     @Override
+    public PointF getVisibleEndOfLayerView() {
+        return mToolbarAnimator.getVisibleEndOfLayerView();
+    }
+
+    /** Implementation of PanZoomTarget */
+    @Override
     public void setAnimationTarget(ImmutableViewportMetrics metrics) {
         if (mGeckoIsReady) {
             // We know what the final viewport of the animation is going to be, so
             // immediately request a draw of that area by setting the display port
             // accordingly. This way we should have the content pre-rendered by the
             // time the animation is done.
             DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null);
             adjustViewport(displayPort);
--- a/mobile/android/base/gfx/JavaPanZoomController.java
+++ b/mobile/android/base/gfx/JavaPanZoomController.java
@@ -1098,16 +1098,20 @@ class JavaPanZoomController
         public float getOrigin() { return getMetrics().viewportRectLeft; }
         @Override
         protected float getViewportLength() { return getMetrics().getWidth(); }
         @Override
         protected float getPageStart() { return getMetrics().pageRectLeft; }
         @Override
         protected float getPageLength() { return getMetrics().getPageWidthWithMargins(); }
         @Override
+        protected float getVisibleEndOfLayerView() {
+            return mTarget.getVisibleEndOfLayerView().x;
+        }
+        @Override
         protected void overscrollFling(final float velocity) {
             if (mOverscroll != null) {
                 mOverscroll.setVelocity(velocity, Overscroll.Axis.X);
             }
         }
         @Override
         protected void overscrollPan(final float distance) {
             if (mOverscroll != null) {
@@ -1122,16 +1126,20 @@ class JavaPanZoomController
         public float getOrigin() { return getMetrics().viewportRectTop; }
         @Override
         protected float getViewportLength() { return getMetrics().getHeight(); }
         @Override
         protected float getPageStart() { return getMetrics().pageRectTop; }
         @Override
         protected float getPageLength() { return getMetrics().getPageHeightWithMargins(); }
         @Override
+        protected float getVisibleEndOfLayerView() {
+            return mTarget.getVisibleEndOfLayerView().y;
+        }
+        @Override
         protected void overscrollFling(final float velocity) {
             if (mOverscroll != null) {
                 mOverscroll.setVelocity(velocity, Overscroll.Axis.Y);
             }
         }
         @Override
         protected void overscrollPan(final float distance) {
             if (mOverscroll != null) {
--- a/mobile/android/base/gfx/PanZoomTarget.java
+++ b/mobile/android/base/gfx/PanZoomTarget.java
@@ -9,16 +9,17 @@ import org.mozilla.gecko.ZoomConstraints
 
 import android.graphics.PointF;
 import android.graphics.RectF;
 
 public interface PanZoomTarget {
     public ImmutableViewportMetrics getViewportMetrics();
     public ZoomConstraints getZoomConstraints();
     public FullScreenState getFullScreenState();
+    public PointF getVisibleEndOfLayerView();
 
     public void setAnimationTarget(ImmutableViewportMetrics viewport);
     public void setViewportMetrics(ImmutableViewportMetrics viewport);
     public void scrollBy(float dx, float dy);
     public void panZoomStopped();
     /** This triggers an (asynchronous) viewport update/redraw. */
     public void forceRedraw(DisplayPortMetrics displayPort);