Bug 586216 - Don't use one timer per animated widget. r=roc a=b
authorBen Turner <bent.mozilla@gmail.com>
Sat, 13 Nov 2010 09:19:38 +0100
changeset 57445 a0351ac4eb4535310d68c1c49bc57c3e359a90c8
parent 57444 e162ecf5bf4e3fd1572ec2d14123379f05de424d
child 57446 65a5f743eaaba7bff2fa05ac488f70ef79f897ae
push id16929
push userdgottwald@mozilla.com
push dateSat, 13 Nov 2010 08:20:29 +0000
treeherdermozilla-central@a0351ac4eb45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, b
bugs586216
milestone2.0b8pre
first release with
nightly linux32
a0351ac4eb45 / 4.0b8pre / 20101113015938 / files
nightly linux64
a0351ac4eb45 / 4.0b8pre / 20101113030932 / files
nightly mac
a0351ac4eb45 / 4.0b8pre / 20101113030748 / files
nightly win32
a0351ac4eb45 / 4.0b8pre / 20101113042433 / files
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
Bug 586216 - Don't use one timer per animated widget. r=roc a=b
layout/generic/nsIFrame.h
toolkit/content/widgets/button.xml
toolkit/content/widgets/progressmeter.xml
toolkit/content/xul.css
toolkit/themes/pinstripe/global/global.css
widget/src/cocoa/nsNativeThemeCocoa.h
widget/src/cocoa/nsNativeThemeCocoa.mm
widget/src/gtk2/nsNativeThemeGTK.cpp
widget/src/gtk2/nsNativeThemeGTK.h
widget/src/qt/nsNativeThemeQt.cpp
widget/src/qt/nsNativeThemeQt.h
widget/src/windows/nsNativeThemeWin.cpp
widget/src/windows/nsNativeThemeWin.h
widget/src/xpwidgets/nsNativeTheme.cpp
widget/src/xpwidgets/nsNativeTheme.h
widget/src/xpwidgets/nsWidgetAtomList.h
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1972,16 +1972,24 @@ public:
    * We want all callers to *think* about what has changed in the frame and what area might
    * need to be repainted.
    *
    * @param aDamageRect is in the frame's local coordinate space
    */
   void Invalidate(const nsRect& aDamageRect)
   { return InvalidateWithFlags(aDamageRect, 0); }
 
+#ifndef MOZ_ENABLE_LIBXUL
+  /**
+   * Same as InvalidateOverflowRect, just for non-libxul builds.
+   */
+  virtual void InvalidateOverflowRectExternal()
+  { return InvalidateOverflowRect(); }
+#endif
+
   /**
    * As Invalidate above, except that this should be called when the
    * rendering that has changed is performed using layers so we can avoid
    * updating the contents of ThebesLayers.
    * @param aDisplayItemKey must not be zero; indicates the kind of display
    * item that is being invalidated.
    */
   void InvalidateLayer(const nsRect& aDamageRect, PRUint32 aDisplayItemKey);
--- a/toolkit/content/widgets/button.xml
+++ b/toolkit/content/widgets/button.xml
@@ -217,47 +217,16 @@
         <children>
           <xul:image class="button-icon" xbl:inherits="src=image"/>
           <xul:label class="button-text" xbl:inherits="value=label,accesskey,crop"/>
         </children>
       </xul:hbox>
     </content>
   </binding>
 
-  <binding id="button-periodic-redraw"
-           extends="chrome://global/content/bindings/button.xml#button">
-    <implementation>
-      <field name="_alive">true</field>
-      <method name="_init">
-        <body><![CDATA[
-          var step = 0;
-          var self = this;
-          var hbox = document.getAnonymousElementByAttribute(this, "anonid", "button-box");
-          var interval = setInterval(function nextStep() {
-            try {
-              // Only bother redrawing when we're visible
-              if (!hbox.getBoundingClientRect().width) {
-                // Maybe we've been removed from the document.
-                if (!self._alive)
-                  clearInterval(interval);
-                return;
-              }
-              // Trigger redraw by changing the step attribute
-              step = 1 - step;
-              self.setAttribute('step', step);
-            } catch (e) {
-              clearInterval(interval);
-            }
-          }, 100);
-        ]]></body>
-      </method>
-      <constructor>this._init();</constructor>
-    </implementation>
-  </binding>
-
   <binding id="menu" display="xul:menu"
            extends="chrome://global/content/bindings/button.xml#button">
     <content>
       <children includes="observes|template|menupopup|panel|tooltip"/>
       <xul:hbox class="box-inherit button-box" xbl:inherits="align,dir,pack,orient"
                 align="center" pack="center" flex="1">
         <children>
           <xul:hbox class="box-inherit" xbl:inherits="align,dir,pack,orient"
--- a/toolkit/content/widgets/progressmeter.xml
+++ b/toolkit/content/widgets/progressmeter.xml
@@ -116,44 +116,9 @@
           mozRequestAnimationFrame();
         ]]></body>
       </method>
 
       <constructor>this._init();</constructor>
     </implementation>
   </binding>
 
-  <binding id="progressmeter-periodic-redraw"
-           extends="chrome://global/content/bindings/progressmeter.xml#progressmeter">
-    <content>
-      <xul:spacer anonid="visibility-detector" flex="1"/>
-    </content>
-    <implementation>
-      <field name="_alive">true</field>
-      <method name="_init">
-        <body><![CDATA[
-          var step = 0;
-          var self = this;
-          var spacer = document.getAnonymousElementByAttribute(this, "anonid", "visibility-detector");
-          var interval = setInterval(function nextStep() {
-            try {
-              // Only bother redrawing when we're visible
-              var width = spacer.boxObject.width;
-              if (!width) {
-                // Maybe we've been removed from the document.
-                if (!self._alive)
-                  clearInterval(interval);
-                return;
-              }
-              // Trigger redraw by changing the step attribute
-              step = 1 - step;
-              self.setAttribute('step', step);
-            } catch (e) {
-              clearInterval(interval);
-            }
-          }, 1000/30);
-        ]]></body>
-      </method>
-      <constructor>this._init();</constructor>
-    </implementation>
-  </binding>
-
 </bindings>
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -119,22 +119,16 @@ bbox {
 }
 
 /********** button **********/
 
 button {
   -moz-binding: url("chrome://global/content/bindings/button.xml#button");
 }
 
-%ifdef XP_MACOSX
-button[default="true"] {
-  -moz-binding: url("chrome://global/content/bindings/button.xml#button-periodic-redraw");
-}
-%endif
-
 button[type="repeat"] {
   -moz-binding: url("chrome://global/content/bindings/button.xml#button-repeat");
 }
 
 button[type="menu"], button[type="panel"] {
   -moz-binding: url("chrome://global/content/bindings/button.xml#menu");
 }
 
--- a/toolkit/themes/pinstripe/global/global.css
+++ b/toolkit/themes/pinstripe/global/global.css
@@ -48,20 +48,16 @@ menulist > menupopup,
 .menulist-menupopup {
   -moz-binding: url("chrome://global/content/bindings/popup.xml#popup-scrollbars");
 }
 
 .menulist-compact {
   -moz-binding: url("chrome://global/content/bindings/menulist.xml#menulist-compact");
 }
 
-progressmeter {
-  -moz-binding: url("chrome://global/content/bindings/progressmeter.xml#progressmeter-periodic-redraw");
-}
-
 /* ::::: draggable elements ::::: */
 
 toolbar:not([nowindowdrag="true"]) {
   -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
 }
 
 statusbar:not([nowindowdrag="true"]) {
   -moz-binding: url("chrome://global/content/bindings/general.xml#statusbar-drag");
--- a/widget/src/cocoa/nsNativeThemeCocoa.h
+++ b/widget/src/cocoa/nsNativeThemeCocoa.h
@@ -54,17 +54,17 @@
 
 class nsNativeThemeCocoa : private nsNativeTheme,
                            public nsITheme
 {
 public:
   nsNativeThemeCocoa();
   virtual ~nsNativeThemeCocoa();
 
-  NS_DECL_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
 
   // The nsITheme interface.
   NS_IMETHOD DrawWidgetBackground(nsIRenderingContext* aContext,
                                   nsIFrame* aFrame,
                                   PRUint8 aWidgetType,
                                   const nsRect& aRect,
                                   const nsRect& aDirtyRect);
   virtual void RegisterWidgetGeometry(nsIWidget* aWindow,
--- a/widget/src/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/src/cocoa/nsNativeThemeCocoa.mm
@@ -221,17 +221,17 @@ static BOOL FrameIsInActiveWindow(nsIFra
   topLevelWidget->GetWindowType(windowType);
   if (windowType == eWindowType_popup)
     return YES;
   if ([win isSheet])
     return [win isKeyWindow];
   return [win isMainWindow] && ![win attachedSheet];
 }
 
-NS_IMPL_ISUPPORTS1(nsNativeThemeCocoa, nsITheme)
+NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeCocoa, nsNativeTheme, nsITheme)
 
 
 nsNativeThemeCocoa::nsNativeThemeCocoa()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   mPushButtonCell = [[NSButtonCell alloc] initTextCell:nil];
   [mPushButtonCell setButtonType:NSMomentaryPushInButton];
@@ -1673,16 +1673,19 @@ nsNativeThemeCocoa::DrawWidgetBackground
       PRBool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
       DrawCheckboxOrRadio(cgContext, isCheckbox, macRect, GetCheckedOrSelected(aFrame, !isCheckbox),
                           eventState, aFrame);
     }
       break;
 
     case NS_THEME_BUTTON:
       if (IsDefaultButton(aFrame)) {
+        if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 10)) {
+          NS_WARNING("Unable to animate button!");
+        }
         DrawButton(cgContext, kThemePushButton, macRect, true,
                    kThemeButtonOff, kThemeAdornmentNone, eventState, aFrame);
       } else if (IsButtonTypeMenu(aFrame)) {
         DrawDropdown(cgContext, macRect, eventState, aWidgetType, aFrame);
       } else {
         DrawPushButton(cgContext, macRect, eventState, aFrame);
       }
       break;
@@ -1792,16 +1795,19 @@ nsNativeThemeCocoa::DrawWidgetBackground
                 IsDisabled(aFrame, eventState) || IsReadOnly(aFrame), eventState);
       break;
       
     case NS_THEME_SEARCHFIELD:
       DrawSearchField(cgContext, macRect, aFrame, eventState);
       break;
 
     case NS_THEME_PROGRESSBAR:
+      if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 30)) {
+        NS_WARNING("Unable to animate progressbar!");
+      }
       DrawProgress(cgContext, macRect, IsIndeterminateProgress(aFrame),
                    PR_TRUE, GetProgressValue(aFrame),
                    GetProgressMaxValue(aFrame), aFrame);
       break;
 
     case NS_THEME_PROGRESSBAR_VERTICAL:
       DrawProgress(cgContext, macRect, IsIndeterminateProgress(aFrame),
                    PR_FALSE, GetProgressValue(aFrame),
@@ -2375,23 +2381,21 @@ nsNativeThemeCocoa::WidgetStateChanged(n
     case NS_THEME_STATUSBAR_PANEL:
     case NS_THEME_STATUSBAR_RESIZER_PANEL:
     case NS_THEME_TOOLTIP:
     case NS_THEME_TAB_PANELS:
     case NS_THEME_TAB_PANEL:
     case NS_THEME_DIALOG:
     case NS_THEME_MENUPOPUP:
     case NS_THEME_GROUPBOX:
-      *aShouldRepaint = PR_FALSE;
-      return NS_OK;
     case NS_THEME_PROGRESSBAR_CHUNK:
     case NS_THEME_PROGRESSBAR_CHUNK_VERTICAL:
     case NS_THEME_PROGRESSBAR:
     case NS_THEME_PROGRESSBAR_VERTICAL:
-      *aShouldRepaint = (aAttribute == nsWidgetAtoms::step);
+      *aShouldRepaint = PR_FALSE;
       return NS_OK;
   }
 
   // XXXdwh Not sure what can really be done here.  Can at least guess for
   // specific widgets that they're highly unlikely to have certain states.
   // For example, a toolbar doesn't care about any states.
   if (!aAttribute) {
     // Hover/focus/active changed.  Always repaint.
@@ -2402,17 +2406,16 @@ nsNativeThemeCocoa::WidgetStateChanged(n
     *aShouldRepaint = PR_FALSE;
     if (aAttribute == nsWidgetAtoms::disabled ||
         aAttribute == nsWidgetAtoms::checked ||
         aAttribute == nsWidgetAtoms::selected ||
         aAttribute == nsWidgetAtoms::mozmenuactive ||
         aAttribute == nsWidgetAtoms::sortdirection ||
         aAttribute == nsWidgetAtoms::focused ||
         aAttribute == nsWidgetAtoms::_default ||
-        aAttribute == nsWidgetAtoms::step ||
         aAttribute == nsWidgetAtoms::open)
       *aShouldRepaint = PR_TRUE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/widget/src/gtk2/nsNativeThemeGTK.cpp
+++ b/widget/src/gtk2/nsNativeThemeGTK.cpp
@@ -64,17 +64,18 @@
 
 #include <gdk/gdkprivate.h>
 #include <gtk/gtk.h>
 
 #include "gfxContext.h"
 #include "gfxPlatformGtk.h"
 #include "gfxGdkNativeRenderer.h"
 
-NS_IMPL_ISUPPORTS2(nsNativeThemeGTK, nsITheme, nsIObserver)
+NS_IMPL_ISUPPORTS_INHERITED2(nsNativeThemeGTK, nsNativeTheme, nsITheme,
+                                                              nsIObserver)
 
 static int gLastGdkError;
 
 nsNativeThemeGTK::nsNativeThemeGTK()
 {
   if (moz_gtk_init() != MOZ_GTK_SUCCESS) {
     memset(mDisabledWidgetTypes, 0xff, sizeof(mDisabledWidgetTypes));
     return;
--- a/widget/src/gtk2/nsNativeThemeGTK.h
+++ b/widget/src/gtk2/nsNativeThemeGTK.h
@@ -44,17 +44,17 @@
 
 #include <gtk/gtk.h>
 #include "gtkdrawing.h"
 
 class nsNativeThemeGTK: private nsNativeTheme,
                         public nsITheme,
                         public nsIObserver {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_NSIOBSERVER
 
   // The nsITheme interface.
   NS_IMETHOD DrawWidgetBackground(nsIRenderingContext* aContext,
                                   nsIFrame* aFrame, PRUint8 aWidgetType,
                                   const nsRect& aRect,
                                   const nsRect& aDirtyRect);
--- a/widget/src/qt/nsNativeThemeQt.cpp
+++ b/widget/src/qt/nsNativeThemeQt.cpp
@@ -81,17 +81,17 @@ nsNativeThemeQt::nsNativeThemeQt()
     mNoBackgroundPalette.setColor(QPalette::Window, Qt::transparent);
     ThemeChanged();
 }
 
 nsNativeThemeQt::~nsNativeThemeQt()
 {
 }
 
-NS_IMPL_ISUPPORTS1(nsNativeThemeQt, nsITheme)
+NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeQt, nsNativeTheme, nsITheme)
 
 static inline QRect qRectInPixels(const nsRect &aRect,
                                   const PRInt32 p2a)
 {
     return QRect(NSAppUnitsToIntPixels(aRect.x, p2a),
                  NSAppUnitsToIntPixels(aRect.y, p2a),
                  NSAppUnitsToIntPixels(aRect.width, p2a),
                  NSAppUnitsToIntPixels(aRect.height, p2a));
--- a/widget/src/qt/nsNativeThemeQt.h
+++ b/widget/src/qt/nsNativeThemeQt.h
@@ -54,17 +54,17 @@ class QStyleOptionFrameV2;
 class QStyleOptionComboBox;
 class QRect;
 class nsIFrame;
 
 class nsNativeThemeQt : private nsNativeTheme,
                         public nsITheme
 {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
 
   // The nsITheme interface.
   NS_IMETHOD DrawWidgetBackground(nsIRenderingContext* aContext,
                                   nsIFrame* aFrame,
                                   PRUint8 aWidgetType,
                                   const nsRect& aRect,
                                   const nsRect& aClipRect);
 
--- a/widget/src/windows/nsNativeThemeWin.cpp
+++ b/widget/src/windows/nsNativeThemeWin.cpp
@@ -67,17 +67,17 @@
 #include "gfxMatrix.h"
 #include "gfxWindowsPlatform.h"
 #include "gfxWindowsSurface.h"
 #include "gfxWindowsNativeDrawing.h"
 
 #include "nsUXThemeData.h"
 #include "nsUXThemeConstants.h"
 
-NS_IMPL_ISUPPORTS1(nsNativeThemeWin, nsITheme)
+NS_IMPL_ISUPPORTS_INHERITED1(nsNativeThemeWin, nsNativeTheme, nsITheme)
 
 #ifdef WINCE
 
 /* These functions might or might not be present; FrameRect probably isn't,
  * but GetViewportOrgEx might be -- so #define them to avoid name collisions.
  */
 
 #define FrameRect moz_FrameRect
--- a/widget/src/windows/nsNativeThemeWin.h
+++ b/widget/src/windows/nsNativeThemeWin.h
@@ -44,17 +44,17 @@
 #include <windows.h>
 
 struct nsIntRect;
 struct nsIntSize;
 
 class nsNativeThemeWin : private nsNativeTheme,
                          public nsITheme {
 public:
-  NS_DECL_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
 
   // The nsITheme interface.
   NS_IMETHOD DrawWidgetBackground(nsIRenderingContext* aContext,
                                   nsIFrame* aFrame,
                                   PRUint8 aWidgetType,
                                   const nsRect& aRect,
                                   const nsRect& aDirtyRect);
 
--- a/widget/src/xpwidgets/nsNativeTheme.cpp
+++ b/widget/src/xpwidgets/nsNativeTheme.cpp
@@ -48,19 +48,22 @@
 #include "nsINameSpaceManager.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsILookAndFeel.h"
 #include "nsThemeConstants.h"
 #include "nsIComponentManager.h"
 #include "nsPIDOMWindow.h"
 
 nsNativeTheme::nsNativeTheme()
+: mAnimatedContentTimeout(PR_UINT32_MAX)
 {
 }
 
+NS_IMPL_ISUPPORTS1(nsNativeTheme, nsITimerCallback)
+
 nsIPresShell *
 nsNativeTheme::GetPresShell(nsIFrame* aFrame)
 {
   if (!aFrame)
     return nsnull;
 
   // this is a workaround for the egcs 1.1.2 not inliningg
   // aFrame->GetPresContext(), which causes an undefined symbol
@@ -471,8 +474,72 @@ nsNativeTheme::IsSubmenu(nsIFrame* aFram
         *aLeftOfParent = selfBounds.x < parentBounds.x;
       }
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
+
+PRBool
+nsNativeTheme::QueueAnimatedContentForRefresh(nsIContent* aContent,
+                                              PRUint32 aMinimumFrameRate)
+{
+  NS_ASSERTION(aContent, "Null pointer!");
+  NS_ASSERTION(aMinimumFrameRate, "aMinimumFrameRate must be non-zero!");
+  NS_ASSERTION(aMinimumFrameRate <= 1000,
+               "aMinimumFrameRate must be less than 1000!");
+
+  PRUint32 timeout = PRUint32(NS_floor(1000 / aMinimumFrameRate));
+  timeout = PR_MIN(mAnimatedContentTimeout, timeout);
+
+  if (!mAnimatedContentTimer) {
+    mAnimatedContentTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
+    NS_ENSURE_TRUE(mAnimatedContentTimer, PR_FALSE);
+  }
+
+  if (mAnimatedContentList.IsEmpty() || timeout != mAnimatedContentTimeout) {
+    nsresult rv;
+    if (!mAnimatedContentList.IsEmpty()) {
+      rv = mAnimatedContentTimer->Cancel();
+      NS_ENSURE_SUCCESS(rv, PR_FALSE);
+    }
+
+    rv = mAnimatedContentTimer->InitWithCallback(this, timeout,
+                                                 nsITimer::TYPE_ONE_SHOT);
+    NS_ENSURE_SUCCESS(rv, PR_FALSE);
+
+    mAnimatedContentTimeout = timeout;
+  }
+
+  if (!mAnimatedContentList.AppendElement(aContent)) {
+    NS_WARNING("Out of memory!");
+    return PR_FALSE;
+  }
+
+  return PR_TRUE;
+}
+
+NS_IMETHODIMP
+nsNativeTheme::Notify(nsITimer* aTimer)
+{
+  NS_ASSERTION(aTimer == mAnimatedContentTimer, "Wrong timer!");
+
+  // XXX Assumes that calling nsIFrame::Invalidate won't reenter
+  //     QueueAnimatedContentForRefresh.
+
+  PRUint32 count = mAnimatedContentList.Length();
+  for (PRUint32 index = 0; index < count; index++) {
+    nsIFrame* frame = mAnimatedContentList[index]->GetPrimaryFrame();
+    if (frame) {
+#ifdef MOZ_ENABLE_LIBXUL
+      frame->InvalidateOverflowRect();
+#else
+      frame->InvalidateOverflowRectExternal();
+#endif
+    }
+  }
+
+  mAnimatedContentList.Clear();
+  mAnimatedContentTimeout = PR_UINT32_MAX;
+  return NS_OK;
+}
--- a/widget/src/xpwidgets/nsNativeTheme.h
+++ b/widget/src/xpwidgets/nsNativeTheme.h
@@ -42,25 +42,31 @@
 #include "prtypes.h"
 #include "nsIAtom.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsMargin.h"
 #include "nsILookAndFeel.h"
 #include "nsWidgetAtoms.h"
 #include "nsEventStates.h"
+#include "nsTArray.h"
+#include "nsITimer.h"
 
+class nsIContent;
 class nsIFrame;
 class nsIPresShell;
 class nsPresContext;
 
-class nsNativeTheme
+class nsNativeTheme : public nsITimerCallback
 {
  protected:
 
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITIMERCALLBACK
+
   enum ScrollbarButtonType {
     eScrollbarButton_UpTop   = 0,
     eScrollbarButton_Down    = 1 << 0,
     eScrollbarButton_Bottom  = 1 << 1
   };
 
   enum TreeSortDirection {
     eTreeSortDirection_Descending,
@@ -173,9 +179,17 @@ class nsNativeTheme
   PRBool IsSubmenu(nsIFrame* aFrame, PRBool* aLeftOfParent);
 
   nsIPresShell *GetPresShell(nsIFrame* aFrame);
   PRInt32 CheckIntAttr(nsIFrame* aFrame, nsIAtom* aAtom, PRInt32 defaultValue);
   PRBool CheckBooleanAttr(nsIFrame* aFrame, nsIAtom* aAtom);
 
   PRBool GetCheckedOrSelected(nsIFrame* aFrame, PRBool aCheckSelected);
   PRBool GetIndeterminate(nsIFrame* aFrame);
+
+  PRBool QueueAnimatedContentForRefresh(nsIContent* aContent,
+                                        PRUint32 aMinimumFrameRate);
+
+ private:
+  PRUint32 mAnimatedContentTimeout;
+  nsCOMPtr<nsITimer> mAnimatedContentTimer;
+  nsAutoTArray<nsCOMPtr<nsIContent>, 20> mAnimatedContentList;
 };
--- a/widget/src/xpwidgets/nsWidgetAtomList.h
+++ b/widget/src/xpwidgets/nsWidgetAtomList.h
@@ -114,17 +114,16 @@ WIDGET_ATOM(scrollbarFrame, "ScrollbarFr
 WIDGET_ATOM(scrollbarDownBottom, "scrollbar-down-bottom")
 WIDGET_ATOM(scrollbarDownTop, "scrollbar-down-top")
 WIDGET_ATOM(scrollbarUpBottom, "scrollbar-up-bottom")
 WIDGET_ATOM(scrollbarUpTop, "scrollbar-up-top")
 WIDGET_ATOM(Search, "Search")
 WIDGET_ATOM(selected, "selected")
 WIDGET_ATOM(sortdirection, "sortDirection")
 WIDGET_ATOM(state, "state")
-WIDGET_ATOM(step, "step")
 WIDGET_ATOM(Stop, "Stop")
 WIDGET_ATOM(_true, "true")
 WIDGET_ATOM(tab, "tab")
 WIDGET_ATOM(tree, "tree")
 WIDGET_ATOM(treecolpicker, "treecolpicker")
 WIDGET_ATOM(type, "type")
 WIDGET_ATOM(value, "value")
 WIDGET_ATOM(VolumeUp, "VolumeUp")