Bug 870917 - Fix overlay scrollbars in XUL trees to fade and disappear correctly instead of pulsating continuously. r=roc, a=lsblakk
authorStephen Pohl <spohl.mozilla.bugs@gmail.com>
Fri, 12 Jul 2013 23:19:37 -0400
changeset 143091 49c72ba550e6e5d59b9fcc50d5911ede2bbd9460
parent 143090 3b4a649104aa9aed861ce42623e173e0cb687428
child 143092 2cc1ab17c0dea12ca0f547d53ba8df3c559d1ee8
push id2645
push userryanvm@gmail.com
push dateWed, 17 Jul 2013 17:10:02 +0000
treeherdermozilla-beta@98604d9f3c1f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, lsblakk
bugs870917
milestone23.0
Bug 870917 - Fix overlay scrollbars in XUL trees to fade and disappear correctly instead of pulsating continuously. r=roc, a=lsblakk
layout/xul/tree/nsTreeBodyFrame.cpp
layout/xul/tree/nsTreeBodyFrame.h
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -110,16 +110,17 @@ NS_QUERYFRAME_TAIL_INHERITING(nsLeafBoxF
 
 // Constructor
 nsTreeBodyFrame::nsTreeBodyFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 :nsLeafBoxFrame(aPresShell, aContext),
  mSlots(nullptr),
  mTopRowIndex(0),
  mPageLength(0),
  mHorzPosition(0),
+ mOriginalHorzWidth(-1),
  mHorzWidth(0),
  mAdjustWidth(0),
  mRowHeight(0),
  mIndentation(0),
  mStringWidth(-1),
  mUpdateBatchNest(0),
  mRowCount(0),
  mMouseOverRow(-1),
@@ -381,25 +382,38 @@ nsTreeBodyFrame::EnsureView()
         // view current.
         box->RemoveProperty(NS_LITERAL_STRING("topRow").get());
       }
     }
   }
 }
 
 void
+nsTreeBodyFrame::ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth)
+{
+  if (!mReflowCallbackPosted &&
+      (!aRect.IsEqualEdges(mRect) || mHorzWidth != aHorzWidth)) {
+    PresContext()->PresShell()->PostReflowCallback(this);
+    mReflowCallbackPosted = true;
+    mOriginalHorzWidth = mHorzWidth;
+  }
+  else if (mReflowCallbackPosted &&
+           mHorzWidth != aHorzWidth && mOriginalHorzWidth == aHorzWidth) {
+    PresContext()->PresShell()->CancelReflowCallback(this);
+    mReflowCallbackPosted = false;
+    mOriginalHorzWidth = -1;
+  }
+}
+
+void
 nsTreeBodyFrame::SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
                            bool aRemoveOverflowArea)
 {
   nscoord horzWidth = CalcHorzWidth(GetScrollParts());
-  if ((!aRect.IsEqualEdges(mRect) || mHorzWidth != horzWidth) && !mReflowCallbackPosted) {
-    mReflowCallbackPosted = true;
-    PresContext()->PresShell()->PostReflowCallback(this);
-  }
-
+  ManageReflowCallback(aRect, horzWidth);
   mHorzWidth = horzWidth;
 
   nsLeafBoxFrame::SetBounds(aBoxLayoutState, aRect, aRemoveOverflowArea);
 }
 
 
 bool
 nsTreeBodyFrame::ReflowFinished()
--- a/layout/xul/tree/nsTreeBodyFrame.h
+++ b/layout/xul/tree/nsTreeBodyFrame.h
@@ -115,16 +115,18 @@ public:
                                 int32_t *aX, int32_t *aY,
                                 int32_t *aWidth, int32_t *aHeight);
   nsresult IsCellCropped(int32_t aRow, nsITreeColumn *aCol, bool *aResult);
   nsresult RowCountChanged(int32_t aIndex, int32_t aCount);
   nsresult BeginUpdateBatch();
   nsresult EndUpdateBatch();
   nsresult ClearStyleAndImageCaches();
 
+  void ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth);
+
   virtual nsSize GetMinSize(nsBoxLayoutState& aBoxLayoutState);
   virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
                          bool aRemoveOverflowArea = false);
 
   // nsIReflowCallback
   virtual bool ReflowFinished() MOZ_OVERRIDE;
   virtual void ReflowCallbackCanceled() MOZ_OVERRIDE;
 
@@ -571,16 +573,23 @@ protected: // Data Members
   // The index of the first visible row and the # of rows visible onscreen.  
   // The tree only examines onscreen rows, starting from
   // this index and going up to index+pageLength.
   int32_t mTopRowIndex;
   int32_t mPageLength;
 
   // The horizontal scroll position
   nscoord mHorzPosition;
+
+  // The original desired horizontal width before changing it and posting a
+  // reflow callback. In some cases, the desired horizontal width can first be
+  // different from the current desired horizontal width, only to return to
+  // the same value later during the same reflow. In this case, we can cancel
+  // the posted reflow callback and prevent an unnecessary reflow.
+  nscoord mOriginalHorzWidth;
   // Our desired horizontal width (the width for which we actually have tree
   // columns).
   nscoord mHorzWidth;
   // The amount by which to adjust the width of the last cell.
   // This depends on whether or not the columnpicker and scrollbars are present.
   nscoord mAdjustWidth;
 
   // Cached heights and indent info.