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 147922 92ddaae926c7b9f1f8520a33454f0c0cb4b3ebcb
parent 147921 f2b49f275dff97a3b82ef011af4ab0ac0c1aac09
child 147923 69cef757d7aa91a9a9ff67f1a891c0f664a012c3
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, lsblakk
bugs870917
milestone24.0a2
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) MOZ_OVERRIDE;
   virtual void SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
                          bool aRemoveOverflowArea = false) MOZ_OVERRIDE;
 
   // 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.