forked from mirrors/gecko-dev
		
	Bug 892684 - Implement axis locking in AsyncPanZoomController [r=kats,botond]
This commit is contained in:
		
							parent
							
								
									f58ece2dd9
								
							
						
					
					
						commit
						1403178461
					
				
					 6 changed files with 177 additions and 16 deletions
				
			
		|  | @ -42,6 +42,9 @@ pref("gfx.azpc.fling_repaint_interval", "50"); // prefer 20 fps | ||||||
| pref("gfx.axis.fling_friction", "0.002"); | pref("gfx.axis.fling_friction", "0.002"); | ||||||
| pref("gfx.axis.fling_stopped_threshold", "0.2"); | pref("gfx.axis.fling_stopped_threshold", "0.2"); | ||||||
| 
 | 
 | ||||||
|  | // 0 = free, 1 = standard, 2 = sticky
 | ||||||
|  | pref("apzc.axis_lock_mode", 1); | ||||||
|  | 
 | ||||||
| // Enable Microsoft TSF support by default for imes.
 | // Enable Microsoft TSF support by default for imes.
 | ||||||
| pref("intl.enable_tsf_support", true); | pref("intl.enable_tsf_support", true); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #include "gfxTypes.h"                   // for gfxFloat
 | #include "gfxTypes.h"                   // for gfxFloat
 | ||||||
| #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 | #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 | ||||||
| #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
 | #include "mozilla/ClearOnShutdown.h"    // for ClearOnShutdown
 | ||||||
|  | #include "mozilla/Constants.h"          // for M_PI
 | ||||||
| #include "mozilla/EventForwards.h"      // for nsEventStatus_*
 | #include "mozilla/EventForwards.h"      // for nsEventStatus_*
 | ||||||
| #include "mozilla/Preferences.h"        // for Preferences
 | #include "mozilla/Preferences.h"        // for Preferences
 | ||||||
| #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitorAutoEnter, etc
 | #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitorAutoEnter, etc
 | ||||||
|  | @ -64,7 +65,27 @@ namespace layers { | ||||||
|  */ |  */ | ||||||
| static float gTouchStartTolerance = 1.0f/16.0f; | static float gTouchStartTolerance = 1.0f/16.0f; | ||||||
| 
 | 
 | ||||||
| static const float EPSILON = 0.0001; | static const float EPSILON = 0.0001f; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Angle from axis within which we stay axis-locked | ||||||
|  |  */ | ||||||
|  | static const double AXIS_LOCK_ANGLE = M_PI / 6.0; // 30 degrees
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * The distance in inches the user must pan before axis lock can be broken | ||||||
|  |  */ | ||||||
|  | static const float AXIS_BREAKOUT_THRESHOLD = 1.0f/32.0f; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * The angle at which axis lock can be broken | ||||||
|  |  */ | ||||||
|  | static const double AXIS_BREAKOUT_ANGLE = M_PI / 8.0; // 22.5 degrees
 | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * The preferred axis locking style. See AxisLockMode for possible values. | ||||||
|  |  */ | ||||||
|  | static int32_t gAxisLockMode = 0; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Maximum amount of time while panning before sending a viewport change. This |  * Maximum amount of time while panning before sending a viewport change. This | ||||||
|  | @ -153,6 +174,23 @@ static int gAsyncScrollTimeout = 300; | ||||||
|  */ |  */ | ||||||
| static bool gAsyncZoomDisabled = false; | static bool gAsyncZoomDisabled = false; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Is aAngle within the given threshold of the horizontal axis? | ||||||
|  |  * @param aAngle an angle in radians in the range [0, pi] | ||||||
|  |  * @param aThreshold an angle in radians in the range [0, pi/2] | ||||||
|  |  */ | ||||||
|  | static bool IsCloseToHorizontal(float aAngle, float aThreshold) | ||||||
|  | { | ||||||
|  |   return (aAngle < aThreshold || aAngle > (M_PI - aThreshold)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // As above, but for the vertical axis.
 | ||||||
|  | static bool IsCloseToVertical(float aAngle, float aThreshold) | ||||||
|  | { | ||||||
|  |   return (fabs(aAngle - (M_PI / 2)) < aThreshold); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| static TimeStamp sFrameTime; | static TimeStamp sFrameTime; | ||||||
| 
 | 
 | ||||||
| static TimeStamp | static TimeStamp | ||||||
|  | @ -191,6 +229,7 @@ AsyncPanZoomController::InitializeGlobalState() | ||||||
|   Preferences::AddIntVarCache(&gAsyncScrollThrottleTime, "apzc.asyncscroll.throttle", gAsyncScrollThrottleTime); |   Preferences::AddIntVarCache(&gAsyncScrollThrottleTime, "apzc.asyncscroll.throttle", gAsyncScrollThrottleTime); | ||||||
|   Preferences::AddIntVarCache(&gAsyncScrollTimeout, "apzc.asyncscroll.timeout", gAsyncScrollTimeout); |   Preferences::AddIntVarCache(&gAsyncScrollTimeout, "apzc.asyncscroll.timeout", gAsyncScrollTimeout); | ||||||
|   Preferences::AddBoolVarCache(&gAsyncZoomDisabled, "apzc.asynczoom.disabled", gAsyncZoomDisabled); |   Preferences::AddBoolVarCache(&gAsyncZoomDisabled, "apzc.asynczoom.disabled", gAsyncZoomDisabled); | ||||||
|  |   Preferences::AddIntVarCache(&gAxisLockMode, "apzc.axis_lock_mode", gAxisLockMode); | ||||||
| 
 | 
 | ||||||
|   gComputedTimingFunction = new ComputedTimingFunction(); |   gComputedTimingFunction = new ComputedTimingFunction(); | ||||||
|   gComputedTimingFunction->Init( |   gComputedTimingFunction->Init( | ||||||
|  | @ -272,6 +311,11 @@ AsyncPanZoomController::GetTouchStartTolerance() | ||||||
|   return gTouchStartTolerance; |   return gTouchStartTolerance; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* static */AsyncPanZoomController::AxisLockMode AsyncPanZoomController::GetAxisLockMode() | ||||||
|  | { | ||||||
|  |   return static_cast<AxisLockMode>(gAxisLockMode); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static CSSPoint | static CSSPoint | ||||||
| WidgetSpaceToCompensatedViewportSpace(const ScreenPoint& aPoint, | WidgetSpaceToCompensatedViewportSpace(const ScreenPoint& aPoint, | ||||||
|                                       const CSSToScreenScale& aCurrentZoom) |                                       const CSSToScreenScale& aCurrentZoom) | ||||||
|  | @ -295,7 +339,7 @@ nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent) | ||||||
|   // responding in a timely fashion, this only introduces a nearly constant few
 |   // responding in a timely fashion, this only introduces a nearly constant few
 | ||||||
|   // hundred ms of lag.
 |   // hundred ms of lag.
 | ||||||
|   if (mFrameMetrics.mMayHaveTouchListeners && aEvent.mInputType == MULTITOUCH_INPUT && |   if (mFrameMetrics.mMayHaveTouchListeners && aEvent.mInputType == MULTITOUCH_INPUT && | ||||||
|       (mState == NOTHING || mState == TOUCHING || mState == PANNING)) { |       (mState == NOTHING || mState == TOUCHING || IsPanningState(mState))) { | ||||||
|     const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput(); |     const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput(); | ||||||
|     if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) { |     if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) { | ||||||
|       SetState(WAITING_LISTENERS); |       SetState(WAITING_LISTENERS); | ||||||
|  | @ -413,6 +457,8 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent | ||||||
|       break; |       break; | ||||||
|     case TOUCHING: |     case TOUCHING: | ||||||
|     case PANNING: |     case PANNING: | ||||||
|  |     case PANNING_LOCKED_X: | ||||||
|  |     case PANNING_LOCKED_Y: | ||||||
|     case PINCHING: |     case PINCHING: | ||||||
|     case WAITING_LISTENERS: |     case WAITING_LISTENERS: | ||||||
|       NS_WARNING("Received impossible touch in OnTouchStart"); |       NS_WARNING("Received impossible touch in OnTouchStart"); | ||||||
|  | @ -452,6 +498,8 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     case PANNING: |     case PANNING: | ||||||
|  |     case PANNING_LOCKED_X: | ||||||
|  |     case PANNING_LOCKED_Y: | ||||||
|       TrackTouch(aEvent); |       TrackTouch(aEvent); | ||||||
|       return nsEventStatus_eConsumeNoDefault; |       return nsEventStatus_eConsumeNoDefault; | ||||||
| 
 | 
 | ||||||
|  | @ -495,6 +543,8 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent) | ||||||
|     return nsEventStatus_eIgnore; |     return nsEventStatus_eIgnore; | ||||||
| 
 | 
 | ||||||
|   case PANNING: |   case PANNING: | ||||||
|  |   case PANNING_LOCKED_X: | ||||||
|  |   case PANNING_LOCKED_Y: | ||||||
|     { |     { | ||||||
|       ReentrantMonitorAutoEnter lock(mMonitor); |       ReentrantMonitorAutoEnter lock(mMonitor); | ||||||
|       ScheduleComposite(); |       ScheduleComposite(); | ||||||
|  | @ -704,13 +754,37 @@ const gfx::Point AsyncPanZoomController::GetAccelerationVector() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) { | void AsyncPanZoomController::StartPanning(const MultiTouchInput& aEvent) { | ||||||
|   float dx = mX.PanDistance(), |   ReentrantMonitorAutoEnter lock(mMonitor); | ||||||
|         dy = mY.PanDistance(); | 
 | ||||||
|  |   ScreenIntPoint point = GetFirstTouchScreenPoint(aEvent); | ||||||
|  |   float dx = mX.PanDistance(point.x); | ||||||
|  |   float dy = mY.PanDistance(point.y); | ||||||
|  | 
 | ||||||
|  |   // When the touch move breaks through the pan threshold, reposition the touch down origin
 | ||||||
|  |   // so the page won't jump when we start panning.
 | ||||||
|  |   mX.StartTouch(point.x); | ||||||
|  |   mY.StartTouch(point.y); | ||||||
|  |   mLastEventTime = aEvent.mTime; | ||||||
|  | 
 | ||||||
|  |   if (GetAxisLockMode() == FREE) { | ||||||
|  |     SetState(PANNING); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   double angle = atan2(dy, dx); // range [-pi, pi]
 |   double angle = atan2(dy, dx); // range [-pi, pi]
 | ||||||
|   angle = fabs(angle); // range [0, pi]
 |   angle = fabs(angle); // range [0, pi]
 | ||||||
| 
 | 
 | ||||||
|  |   if (!mX.Scrollable() || !mY.Scrollable()) { | ||||||
|     SetState(PANNING); |     SetState(PANNING); | ||||||
|  |   } else if (IsCloseToHorizontal(angle, AXIS_LOCK_ANGLE)) { | ||||||
|  |     mY.SetScrollingDisabled(true); | ||||||
|  |     SetState(PANNING_LOCKED_X); | ||||||
|  |   } else if (IsCloseToVertical(angle, AXIS_LOCK_ANGLE)) { | ||||||
|  |     mX.SetScrollingDisabled(true); | ||||||
|  |     SetState(PANNING_LOCKED_Y); | ||||||
|  |   } else { | ||||||
|  |     SetState(PANNING); | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AsyncPanZoomController::UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent) { | void AsyncPanZoomController::UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent) { | ||||||
|  | @ -775,6 +849,32 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) { | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   // If we're axis-locked, check if the user is trying to break the lock
 | ||||||
|  |   if (GetAxisLockMode() == STICKY) { | ||||||
|  |     ScreenIntPoint point = GetFirstTouchScreenPoint(aEvent); | ||||||
|  |     float dx = mX.PanDistance(point.x); | ||||||
|  |     float dy = mY.PanDistance(point.y); | ||||||
|  | 
 | ||||||
|  |     double angle = atan2(dy, dx); // range [-pi, pi]
 | ||||||
|  |     angle = fabs(angle); // range [0, pi]
 | ||||||
|  | 
 | ||||||
|  |     float breakThreshold = AXIS_BREAKOUT_THRESHOLD * APZCTreeManager::GetDPI(); | ||||||
|  | 
 | ||||||
|  |     if (fabs(dx) > breakThreshold || fabs(dy) > breakThreshold) { | ||||||
|  |       if (mState == PANNING_LOCKED_X) { | ||||||
|  |         if (!IsCloseToHorizontal(angle, AXIS_BREAKOUT_ANGLE)) { | ||||||
|  |           mY.SetScrollingDisabled(false); | ||||||
|  |           SetState(PANNING); | ||||||
|  |         } | ||||||
|  |       } else if (mState == PANNING_LOCKED_Y) { | ||||||
|  |         if (!IsCloseToVertical(angle, AXIS_BREAKOUT_ANGLE)) { | ||||||
|  |           mX.SetScrollingDisabled(false); | ||||||
|  |           SetState(PANNING); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   UpdateWithTouchAtDevicePoint(aEvent); |   UpdateWithTouchAtDevicePoint(aEvent); | ||||||
| 
 | 
 | ||||||
|   AttemptScroll(prevTouchPoint, touchPoint); |   AttemptScroll(prevTouchPoint, touchPoint); | ||||||
|  | @ -1361,14 +1461,18 @@ void AsyncPanZoomController::SetState(PanZoomState aNewState) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   if (mGeckoContentController) { |   if (mGeckoContentController) { | ||||||
|     if (oldState == PANNING && aNewState != PANNING) { |     if (IsPanningState(oldState) && !IsPanningState(aNewState)) { | ||||||
|       mGeckoContentController->HandlePanEnd(); |       mGeckoContentController->HandlePanEnd(); | ||||||
|     } else if (oldState != PANNING && aNewState == PANNING) { |     } else if (!IsPanningState(oldState) && IsPanningState(aNewState)) { | ||||||
|       mGeckoContentController->HandlePanBegin(); |       mGeckoContentController->HandlePanBegin(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool AsyncPanZoomController::IsPanningState(PanZoomState aState) { | ||||||
|  |   return (aState == PANNING || aState == PANNING_LOCKED_X || aState == PANNING_LOCKED_Y); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void AsyncPanZoomController::TimeoutTouchListeners() { | void AsyncPanZoomController::TimeoutTouchListeners() { | ||||||
|   mTouchListenerTimeoutTask = nullptr; |   mTouchListenerTimeoutTask = nullptr; | ||||||
|   ContentReceivedTouch(false); |   ContentReceivedTouch(false); | ||||||
|  |  | ||||||
|  | @ -484,7 +484,11 @@ private: | ||||||
|     NOTHING,        /* no touch-start events received */ |     NOTHING,        /* no touch-start events received */ | ||||||
|     FLING,          /* all touches removed, but we're still scrolling page */ |     FLING,          /* all touches removed, but we're still scrolling page */ | ||||||
|     TOUCHING,       /* one touch-start event received */ |     TOUCHING,       /* one touch-start event received */ | ||||||
|  | 
 | ||||||
|     PANNING,           /* panning the frame */ |     PANNING,           /* panning the frame */ | ||||||
|  |     PANNING_LOCKED_X,  /* touch-start followed by move (i.e. panning with axis lock) X axis */ | ||||||
|  |     PANNING_LOCKED_Y,  /* as above for Y axis */ | ||||||
|  | 
 | ||||||
|     PINCHING,       /* nth touch-start, where n > 1. this mode allows pan and zoom */ |     PINCHING,       /* nth touch-start, where n > 1. this mode allows pan and zoom */ | ||||||
|     ANIMATING_ZOOM, /* animated zoom to a new rect */ |     ANIMATING_ZOOM, /* animated zoom to a new rect */ | ||||||
|     WAITING_LISTENERS, /* a state halfway between NOTHING and TOUCHING - the user has
 |     WAITING_LISTENERS, /* a state halfway between NOTHING and TOUCHING - the user has
 | ||||||
|  | @ -492,6 +496,14 @@ private: | ||||||
|                     prevented the default actions yet. we still need to abort animations. */ |                     prevented the default actions yet. we still need to abort animations. */ | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   enum AxisLockMode { | ||||||
|  |     FREE,     /* No locking at all */ | ||||||
|  |     STANDARD, /* Default axis locking mode that remains locked until pan ends*/ | ||||||
|  |     STICKY,   /* Allow lock to be broken, with hysteresis */ | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   static AxisLockMode GetAxisLockMode(); | ||||||
|  | 
 | ||||||
|   /**
 |   /**
 | ||||||
|    * Helper to set the current state. Holds the monitor before actually setting |    * Helper to set the current state. Holds the monitor before actually setting | ||||||
|    * it. If the monitor is already held by the current thread, it is safe to |    * it. If the monitor is already held by the current thread, it is safe to | ||||||
|  | @ -499,6 +511,8 @@ private: | ||||||
|    */ |    */ | ||||||
|   void SetState(PanZoomState aState); |   void SetState(PanZoomState aState); | ||||||
| 
 | 
 | ||||||
|  |   bool IsPanningState(PanZoomState mState); | ||||||
|  | 
 | ||||||
|   uint64_t mLayersId; |   uint64_t mLayersId; | ||||||
|   nsRefPtr<CompositorParent> mCompositorParent; |   nsRefPtr<CompositorParent> mCompositorParent; | ||||||
|   TaskThrottler mPaintThrottler; |   TaskThrottler mPaintThrottler; | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||||||
| /* vim: set sw=4 ts=8 et tw=80 : */ | /* vim: set sw=2 ts=8 et tw=80 : */ | ||||||
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | /* This Source Code Form is subject to the terms of the Mozilla Public
 | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
|  | @ -103,13 +103,14 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController) | ||||||
|   : mPos(0), |   : mPos(0), | ||||||
|     mVelocity(0.0f), |     mVelocity(0.0f), | ||||||
|     mAcceleration(0), |     mAcceleration(0), | ||||||
|  |     mScrollingDisabled(false), | ||||||
|     mAsyncPanZoomController(aAsyncPanZoomController) |     mAsyncPanZoomController(aAsyncPanZoomController) | ||||||
| { | { | ||||||
|   InitAxisPrefs(); |   InitAxisPrefs(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta) { | void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta) { | ||||||
|   float newVelocity = (mPos - aPos) / aTimeDelta.ToMilliseconds(); |   float newVelocity = mScrollingDisabled ? 0 : (mPos - aPos) / aTimeDelta.ToMilliseconds(); | ||||||
| 
 | 
 | ||||||
|   bool curVelocityBelowThreshold = fabsf(newVelocity) < gVelocityThreshold; |   bool curVelocityBelowThreshold = fabsf(newVelocity) < gVelocityThreshold; | ||||||
|   bool directionChange = (mVelocity > 0) != (newVelocity > 0); |   bool directionChange = (mVelocity > 0) != (newVelocity > 0); | ||||||
|  | @ -133,9 +134,15 @@ void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeD | ||||||
| void Axis::StartTouch(int32_t aPos) { | void Axis::StartTouch(int32_t aPos) { | ||||||
|   mStartPos = aPos; |   mStartPos = aPos; | ||||||
|   mPos = aPos; |   mPos = aPos; | ||||||
|  |   mScrollingDisabled = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float Axis::AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut) { | float Axis::AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut) { | ||||||
|  |   if (mScrollingDisabled) { | ||||||
|  |     aOverscrollAmountOut = 0; | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   if (fabsf(mVelocity) < gVelocityThreshold) { |   if (fabsf(mVelocity) < gVelocityThreshold) { | ||||||
|     mAcceleration = 0; |     mAcceleration = 0; | ||||||
|   } |   } | ||||||
|  | @ -159,6 +166,10 @@ float Axis::PanDistance() { | ||||||
|   return fabsf(mPos - mStartPos); |   return fabsf(mPos - mStartPos); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | float Axis::PanDistance(float aPos) { | ||||||
|  |   return fabsf(aPos - mStartPos); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void Axis::EndTouch() { | void Axis::EndTouch() { | ||||||
|   mAcceleration++; |   mAcceleration++; | ||||||
| 
 | 
 | ||||||
|  | @ -182,6 +193,13 @@ void Axis::CancelTouch() { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool Axis::Scrollable() { | ||||||
|  |     if (mScrollingDisabled) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |     return GetCompositionLength() < GetPageLength(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) { | bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) { | ||||||
|   if (fabsf(mVelocity) <= gFlingStoppedThreshold) { |   if (fabsf(mVelocity) <= gFlingStoppedThreshold) { | ||||||
|     // If the velocity is very low, just set it to 0 and stop the fling,
 |     // If the velocity is very low, just set it to 0 and stop the fling,
 | ||||||
|  | @ -284,7 +302,7 @@ float Axis::ScaleWillOverscrollAmount(ScreenToScreenScale aScale, float aFocus) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float Axis::GetVelocity() { | float Axis::GetVelocity() { | ||||||
|   return mVelocity; |   return mScrollingDisabled ? 0 : mVelocity; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float Axis::GetAccelerationFactor() { | float Axis::GetAccelerationFactor() { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | ||||||
| /* vim: set sw=4 ts=8 et tw=80 : */ | /* vim: set sw=2 ts=8 et tw=80 : */ | ||||||
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | /* This Source Code Form is subject to the terms of the Mozilla Public
 | ||||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||||
|  | @ -69,10 +69,11 @@ public: | ||||||
| 
 | 
 | ||||||
|   /**
 |   /**
 | ||||||
|    * Takes a requested displacement to the position of this axis, and adjusts |    * Takes a requested displacement to the position of this axis, and adjusts | ||||||
|    * it to account for acceleration  (which might increase the displacement) |    * it to account for acceleration (which might increase the displacement), | ||||||
|    * and overscroll (which might decrease the displacement; this is to prevent |    * overscroll (which might decrease the displacement; this is to prevent the | ||||||
|    * the viewport from overscrolling the page rect). If overscroll ocurred, |    * viewport from overscrolling the page rect), and axis locking (which might | ||||||
|    * its amount is written to |aOverscrollAmountOut|. |    * prevent any displacement from happening). If overscroll ocurred, its amount | ||||||
|  |    * is written to |aOverscrollAmountOut|. | ||||||
|    * The adjusted displacement is returned. |    * The adjusted displacement is returned. | ||||||
|    */ |    */ | ||||||
|   float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut); |   float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut); | ||||||
|  | @ -84,6 +85,12 @@ public: | ||||||
|    */ |    */ | ||||||
|   float PanDistance(); |   float PanDistance(); | ||||||
| 
 | 
 | ||||||
|  |   /**
 | ||||||
|  |    * Gets the distance between the starting position of the touch supplied in | ||||||
|  |    * startTouch() and the supplied position. | ||||||
|  |    */ | ||||||
|  |   float PanDistance(float aPos); | ||||||
|  | 
 | ||||||
|   /**
 |   /**
 | ||||||
|    * Applies friction during a fling, or cancels the fling if the velocity is |    * Applies friction during a fling, or cancels the fling if the velocity is | ||||||
|    * too low. Returns true if the fling should continue to another frame, or |    * too low. Returns true if the fling should continue to another frame, or | ||||||
|  | @ -92,6 +99,14 @@ public: | ||||||
|    */ |    */ | ||||||
|   bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta); |   bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta); | ||||||
| 
 | 
 | ||||||
|  |   /*
 | ||||||
|  |    * Returns true if the page is zoomed in to some degree along this axis such that scrolling is | ||||||
|  |    * possible and this axis has not been scroll locked while panning. Otherwise, returns false. | ||||||
|  |    */ | ||||||
|  |   bool Scrollable(); | ||||||
|  | 
 | ||||||
|  |   void SetScrollingDisabled(bool aDisabled) { mScrollingDisabled = aDisabled; } | ||||||
|  | 
 | ||||||
|   /**
 |   /**
 | ||||||
|    * Gets the overscroll state of the axis in its current position. |    * Gets the overscroll state of the axis in its current position. | ||||||
|    */ |    */ | ||||||
|  | @ -184,6 +199,7 @@ protected: | ||||||
|   // they are flinging multiple times in a row very quickly, probably trying to
 |   // they are flinging multiple times in a row very quickly, probably trying to
 | ||||||
|   // reach one of the extremes of the page.
 |   // reach one of the extremes of the page.
 | ||||||
|   int32_t mAcceleration; |   int32_t mAcceleration; | ||||||
|  |   bool mScrollingDisabled;     // Whether movement on this axis is locked.
 | ||||||
|   AsyncPanZoomController* mAsyncPanZoomController; |   AsyncPanZoomController* mAsyncPanZoomController; | ||||||
|   nsTArray<float> mVelocityQueue; |   nsTArray<float> mVelocityQueue; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -273,6 +273,12 @@ pref("media.video_stats.enabled", true); | ||||||
| // Whether to enable the audio writing APIs on the audio element
 | // Whether to enable the audio writing APIs on the audio element
 | ||||||
| pref("media.audio_data.enabled", true); | pref("media.audio_data.enabled", true); | ||||||
| 
 | 
 | ||||||
|  | // Whether to lock touch scrolling to one axis at a time
 | ||||||
|  | // 0 = FREE (No locking at all)
 | ||||||
|  | // 1 = STANDARD (Once locked, remain locked until scrolling ends)
 | ||||||
|  | // 2 = STICKY (Allow lock to be broken, with hysteresis)
 | ||||||
|  | pref("apzc.axis_lock_mode", 0); | ||||||
|  | 
 | ||||||
| #ifdef XP_MACOSX | #ifdef XP_MACOSX | ||||||
| // Whether to run in native HiDPI mode on machines with "Retina"/HiDPI display;
 | // Whether to run in native HiDPI mode on machines with "Retina"/HiDPI display;
 | ||||||
| //   <= 0 : hidpi mode disabled, display will just use pixel-based upscaling
 | //   <= 0 : hidpi mode disabled, display will just use pixel-based upscaling
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Matt Brubeck
						Matt Brubeck