Bug 402843. Don't persistently store scroll positions in device pixels, it just gets out of sync and causes bugs during full zoom. r+sr=bzbarsky
authorroc+@cs.cmu.edu
Thu, 15 Nov 2007 17:45:21 -0800
changeset 8082 317c01d10b837b58a6c28a83d239d56adee27a15
parent 8081 1a966f689d12f0c076b8a8b58b4c11e54ac84a2b
child 8083 0aa640408412d5fdcd6f84aec53e335f591d95da
push idunknown
push userunknown
push dateunknown
bugs402843
milestone1.9b2pre
Bug 402843. Don't persistently store scroll positions in device pixels, it just gets out of sync and causes bugs during full zoom. r+sr=bzbarsky
view/src/nsScrollPortView.cpp
view/src/nsScrollPortView.h
--- a/view/src/nsScrollPortView.cpp
+++ b/view/src/nsScrollPortView.cpp
@@ -76,17 +76,16 @@ public:
   nscoord mDestinationX;
   nscoord mDestinationY;
 };
 
 nsScrollPortView::nsScrollPortView(nsViewManager* aViewManager)
   : nsView(aViewManager)
 {
   mOffsetX = mOffsetY = 0;
-  mOffsetXpx = mOffsetYpx = 0;
   nsCOMPtr<nsIDeviceContext> dev;
   mViewManager->GetDeviceContext(*getter_AddRefs(dev));
   mLineHeight = dev->AppUnitsPerInch() / 6; // 12 pt
 
   mListeners = nsnull;
   mSmoothScroll = nsnull;
 }
 
@@ -612,33 +611,32 @@ NS_IMETHODIMP nsScrollPortView::ScrollTo
   PRInt32 p2a = dev->AppUnitsPerDevPixel();
 
   // Update the scrolled view's position
   nsresult rv = ClampScrollValues(aX, aY, this);
   if (NS_FAILED(rv)) {
     return rv;
   }
   
-  // convert aX and aY in pixels
-  nscoord aXpx = NSAppUnitsToIntPixels(aX, p2a);
-  nscoord aYpx = NSAppUnitsToIntPixels(aY, p2a);
+  PRInt32 xPixels = NSAppUnitsToIntPixels(aX, p2a);
+  PRInt32 yPixels = NSAppUnitsToIntPixels(aY, p2a);
   
-  aX = NSIntPixelsToAppUnits(aXpx, p2a);
-  aY = NSIntPixelsToAppUnits(aYpx, p2a);
+  aX = NSIntPixelsToAppUnits(xPixels, p2a);
+  aY = NSIntPixelsToAppUnits(yPixels, p2a);
   
   // do nothing if the we aren't scrolling.
   // this needs to be rechecked because of the clamping and
   // rounding
   if (aX == mOffsetX && aY == mOffsetY) {
     return NS_OK;
   }
 
   // figure out the diff by comparing old pos to new
-  dxPx = mOffsetXpx - aXpx;
-  dyPx = mOffsetYpx - aYpx;
+  dxPx = NSAppUnitsToIntPixels(mOffsetX, p2a) - xPixels;
+  dyPx = NSAppUnitsToIntPixels(mOffsetY, p2a) - yPixels;
 
   // notify the listeners.
   PRUint32 listenerCount;
   const nsIID& kScrollPositionListenerIID = NS_GET_IID(nsIScrollPositionListener);
   nsIScrollPositionListener* listener;
   if (nsnull != mListeners) {
     if (NS_SUCCEEDED(mListeners->Count(&listenerCount))) {
       for (PRUint32 i = 0; i < listenerCount; i++) {
@@ -653,21 +651,16 @@ NS_IMETHODIMP nsScrollPortView::ScrollTo
   nsView* scrolledView = GetScrolledView();
   if (!scrolledView) return NS_ERROR_FAILURE;
 
   // move the scrolled view to the new location
   // Note that child widgets may be scrolled by the native widget scrolling,
   // so don't update their positions
   scrolledView->SetPositionIgnoringChildWidgets(-aX, -aY);
       
-  // store old position in pixels. We need to do this to make sure there is no
-  // round off errors. This could cause weird scrolling.
-  mOffsetXpx = aXpx;
-  mOffsetYpx = aYpx;
-      
   nsPoint twipsDelta(aX - mOffsetX, aY - mOffsetY);
 
   // store the new position
   mOffsetX = aX;
   mOffsetY = aY;
 
   Scroll(scrolledView, twipsDelta, nsPoint(dxPx, dyPx), p2a);
 
--- a/view/src/nsScrollPortView.h
+++ b/view/src/nsScrollPortView.h
@@ -101,15 +101,14 @@ private:
 protected:
   virtual ~nsScrollPortView();
 
   //private
   void Scroll(nsView *aScrolledView, nsPoint aTwipsDelta, nsPoint aPixDelta, PRInt32 p2a);
   PRBool CannotBitBlt(nsView* aScrolledView);
 
   nscoord             mOffsetX, mOffsetY;
-  nscoord             mOffsetXpx, mOffsetYpx;
   PRUint32            mScrollProperties;
   nscoord             mLineHeight;
   nsISupportsArray   *mListeners;
 };
 
 #endif