Bug 343430. Reduce the area we scroll on Windows to reduce flicker by excluding areas that shouldn't be moving. On Linux, since we can't control the area we scroll, just disable accelerated scrolling in that case and repaint everything. r+sr=dbaron
authorroc+@cs.cmu.edu
Sun, 27 May 2007 20:17:20 -0700
changeset 1913 d0d81a7305a719bd74eebb839438706dd24781c6
parent 1912 5ee3a8fd54ab4aa7e12eec5c8c30c92144ce1683
child 1914 d9d6743ea3f35449b29571fb9bf73f7a4990c7fa
push idunknown
push userunknown
push dateunknown
bugs343430
milestone1.9a5pre
Bug 343430. Reduce the area we scroll on Windows to reduce flicker by excluding areas that shouldn't be moving. On Linux, since we can't control the area we scroll, just disable accelerated scrolling in that case and repaint everything. r+sr=dbaron
view/src/nsScrollPortView.cpp
view/src/nsViewManager.cpp
widget/src/windows/nsWindow.cpp
--- a/view/src/nsScrollPortView.cpp
+++ b/view/src/nsScrollPortView.cpp
@@ -573,19 +573,43 @@ void nsScrollPortView::Scroll(nsView *aS
       nsRect bounds(GetBounds());
       nsPoint topLeft(bounds.x, bounds.y);
       AdjustChildWidgets(aScrolledView,
                          GetPosition() - topLeft, aP2A, PR_FALSE);
       // We should call this after fixing up the widget positions to be
       // consistent with the view hierarchy.
       mViewManager->UpdateView(this, 0);
     } else { // if we can blit and have a scrollwidget then scroll.
+      nsRect* toScrollPtr = nsnull;
+
+#ifdef XP_WIN
+      nsRect toScroll;
+      if (!updateRegion.IsEmpty()) {
+        nsRegion regionToScroll;
+        regionToScroll.Sub(nsRect(nsPoint(0,0), GetBounds().Size()),
+                           updateRegion);
+        nsRegionRectIterator iter(regionToScroll);
+        nsRect biggestRect(0,0,0,0);
+        const nsRect* r;
+        for (r = iter.Next(); r; r = iter.Next()) {
+          if (r->width*r->height > biggestRect.width*biggestRect.height) {
+            biggestRect = *r;
+          }
+        }
+        regionToScroll.Sub(regionToScroll, biggestRect);
+        updateRegion.Or(updateRegion, regionToScroll);
+        toScrollPtr = &toScroll;
+        toScroll = biggestRect;
+        toScroll.ScaleRoundOut(1.0/aP2A);
+      }
+#endif
+
       // Scroll the contents of the widget by the specified amount, and scroll
       // the child widgets
-      scrollWidget->Scroll(aPixDelta.x, aPixDelta.y, nsnull);
+      scrollWidget->Scroll(aPixDelta.x, aPixDelta.y, toScrollPtr);
       mViewManager->UpdateViewAfterScroll(this, updateRegion);
     }
   }
 }
 
 NS_IMETHODIMP nsScrollPortView::ScrollToImpl(nscoord aX, nscoord aY, PRUint32 aUpdateFlags)
 {
   PRInt32           dxPx = 0, dyPx = 0;
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -1623,18 +1623,22 @@ PRBool nsViewManager::CanScrollWithBitBl
   toScroll.IntersectRect(parentBounds + aDelta, parentBounds);
   nsresult rv =
     mObserver->ComputeRepaintRegionForCopy(displayRoot, aView, -aDelta, toScroll,
                                            aUpdateRegion);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
 
   aUpdateRegion->MoveBy(-displayOffset);
 
+#ifdef MOZ_WIDGET_GTK2
+  return aUpdateRegion->IsEmpty();
+#else
   return PR_TRUE;
-}                                            
+#endif
+}
 
 NS_IMETHODIMP nsViewManager::SetViewCheckChildEvents(nsIView *aView, PRBool aEnable)
 {
   nsView* view = NS_STATIC_CAST(nsView*, aView);
 
   NS_ASSERTION(!(nsnull == view), "no view");
 
   if (aEnable) {
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -3273,17 +3273,17 @@ NS_METHOD nsWindow::Scroll(PRInt32 aDx, 
   if (nsnull != aClipRect)
   {
     trect.left = aClipRect->x;
     trect.top = aClipRect->y;
     trect.right = aClipRect->XMost();
     trect.bottom = aClipRect->YMost();
   }
 
-  ::ScrollWindowEx(mWnd, aDx, aDy, (nsnull != aClipRect) ? &trect : NULL, NULL,
+  ::ScrollWindowEx(mWnd, aDx, aDy, NULL, (nsnull != aClipRect) ? &trect : NULL,
                    NULL, NULL, SW_INVALIDATE | SW_SCROLLCHILDREN);
   ::UpdateWindow(mWnd);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsWindow::ScrollWidgets(PRInt32 aDx, PRInt32 aDy)
 {
   // Scroll the entire contents of the window + change the offset of any child windows