Index: libs/libmythui/mythuitype.cpp
===================================================================
--- libs/libmythui/mythuitype.cpp	(revision 26040)
+++ libs/libmythui/mythuitype.cpp	(working copy)
@@ -45,6 +45,9 @@
     m_XYSpeed = QPoint(0, 0);
     m_deferload = false;
 
+    m_NextPulse = (1 << animNUMTYPES) - 1; // all bits set
+    m_NextChildPulse = 0;
+
     m_Parent = NULL;
     if (parent)
     {
@@ -70,6 +73,7 @@
  */
 void MythUIType::Reset()
 {
+    SetNextPulse(true);
     // Reset all children
     QMutableListIterator<MythUIType *> it(m_ChildrenList);
     while (it.hasNext())
@@ -89,6 +93,7 @@
         return;
 
     m_ChildrenList.push_back(child);
+    FixupNextChildPulse();
 }
 
 static QObject *qChildHelper(const char *objName, const char *inheritsClass,
@@ -150,6 +155,7 @@
         {
             delete type;
             it.remove();
+            FixupNextChildPulse();
             return;
         }
     }
@@ -172,6 +178,7 @@
         {
             delete type;
             it.remove();
+            FixupNextChildPulse();
             child = NULL;
             return;
         }
@@ -196,6 +203,7 @@
         delete *it;
 
     m_ChildrenList.clear();
+    FixupNextChildPulse();
 }
 
 /** \brief Return the first MythUIType which accepts focus found at the given
@@ -323,10 +331,16 @@
 void MythUIType::HandleMovementPulse(void)
 {
     if (!GetMythPainter()->SupportsAnimation())
+    {
+        SetNextPulse(animMovement, false);
         return;
+    }
 
     if (!m_Moving)
+    {
+        SetNextPulse(animMovement, false);
         return;
+    }
 
     QPoint curXY = m_Area.topLeft().toQPoint();
     m_DirtyRegion = m_Area.toQRect();
@@ -360,6 +374,7 @@
     }
 
     m_Area.moveTopLeft(curXY);
+    SetNextPulse(animMovement, m_Moving);
 }
 
 /**
@@ -371,10 +386,16 @@
 {
     if (!GetMythPainter()->SupportsAlpha() ||
         !GetMythPainter()->SupportsAnimation())
+    {
+        SetNextPulse(animAlpha, false);
         return;
+    }
 
     if (m_AlphaChangeMode == 0)
+    {
+        SetNextPulse(animAlpha, false);
         return;
+    }
 
     m_Alpha += m_AlphaChange;
 
@@ -398,6 +419,7 @@
     }
 
     SetRedraw();
+    SetNextPulse(animAlpha, (m_AlphaChangeMode != 0));
 }
 
 /**
@@ -411,12 +433,18 @@
     if (!m_Visible)
         return;
 
-    HandleMovementPulse();
-    HandleAlphaPulse();
+    if (m_NextPulse & (1 << animMovement))
+        HandleMovementPulse();
+    if (m_NextPulse & (1 << animAlpha))
+        HandleAlphaPulse();
 
-    QList<MythUIType *>::Iterator it;
-    for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
-        (*it)->Pulse();
+    if (m_NextChildPulse)
+    {
+        QList<MythUIType *>::Iterator it;
+        for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
+            (*it)->Pulse();
+    }
+    SetNextPulse(animPulse, false);
 }
 
 int MythUIType::CalcAlpha(int alphamod)
@@ -661,7 +689,10 @@
                              int maxalpha)
 {
     if (!GetMythPainter()->SupportsAlpha())
+    {
+        SetNextPulse(animAlpha, false);
         return;
+    }
 
     m_AlphaChangeMode = mode;
     m_AlphaChange = alphachange;
@@ -672,6 +703,7 @@
         m_Alpha = m_AlphaMax;
     if (m_Alpha < m_AlphaMin)
         m_Alpha = m_AlphaMin;
+    SetNextPulse(animAlpha, (m_AlphaChangeMode != 0));
 }
 
 void MythUIType::SetAlpha(int newalpha)
@@ -755,6 +787,7 @@
         emit Showing();
     else
         emit Hiding();
+    FixupNextChildPulse();
 }
 
 void MythUIType::SetEnabled(bool enable)
@@ -822,6 +855,9 @@
     m_XYSpeed = base->m_XYSpeed;
     m_deferload = base->m_deferload;
 
+    m_NextPulse = m_Visible ? (1 << animNUMTYPES) - 1 : 0;
+    FixupNextChildPulse();
+
     QList<MythUIType *>::Iterator it;
     for (it = base->m_ChildrenList.begin(); it != base->m_ChildrenList.end();
          ++it)
@@ -1007,3 +1043,59 @@
     return false;
 }
 
+// Recompute m_NextChildPulse, and if anything has changed, continue
+// up the tree.
+void MythUIType::FixupNextChildPulse(bool recomputeChildren)
+{
+    for (MythUIType *current=this; current; current=current->m_Parent)
+    {
+        unsigned oldNextPulse = current->m_NextPulse;
+        unsigned oldNextChildPulse = current->m_NextChildPulse;
+
+        if (current->m_Visible)
+        {
+            // If necessary, recompute m_NextChildPulse as the min of
+            // m_NextPulse and m_NextChildPulse across all children.
+            if (recomputeChildren)
+            {
+                current->m_NextChildPulse = 0;
+                QList<MythUIType*>::iterator it;
+                for (it = current->m_ChildrenList.begin(); it != current->m_ChildrenList.end(); ++it)
+                {
+                    current->m_NextChildPulse |= (*it)->m_NextPulse;
+                    current->m_NextChildPulse |= (*it)->m_NextChildPulse;
+                }
+            }
+
+        } else {
+            current->m_NextPulse = 0;
+            current->m_NextChildPulse = 0;
+        }
+
+        // If anything changed, continue up the tree.  Also continue
+        // if current=this, since the method might have been called as
+        // a result of m_NextPulse changing.
+        unsigned oldmin = oldNextPulse | oldNextChildPulse;
+        unsigned newmin = current->m_NextPulse | current->m_NextChildPulse;
+        if (oldmin == newmin && current != this)
+            break;
+        recomputeChildren = true;
+    }
+}
+
+void MythUIType::SetNextPulse(AnimationType type, bool flag)
+{
+    unsigned oldMask = m_NextPulse;
+    if (flag)
+        m_NextPulse |= (1 << type);
+    else
+        m_NextPulse &= ~(1 << type);
+    if (m_NextPulse != oldMask)
+        FixupNextChildPulse(false);
+}
+
+void MythUIType::SetNextPulse(bool flag)
+{
+    for (unsigned i=0; i<animNUMTYPES; i++)
+        SetNextPulse((AnimationType)i, flag);
+}
Index: libs/libmythui/mythuitype.h
===================================================================
--- libs/libmythui/mythuitype.h	(revision 26040)
+++ libs/libmythui/mythuitype.h	(working copy)
@@ -121,6 +121,16 @@
 
     bool ContainsPoint(const QPoint &point) const;
 
+    enum AnimationType {
+        animMovement=0,
+        animAlpha,
+        animPulse,
+        animNUMTYPES
+    };
+    void SetNextPulse(AnimationType type, bool flag); // true=asap, false=never
+    void SetNextPulse(bool flag); // true=asap, false=never
+    void FixupNextChildPulse(bool recomputeChildren=true);
+
   protected:
     virtual void customEvent(QEvent *);
 
@@ -190,6 +200,9 @@
     QPoint m_XYDestination;
     QPoint m_XYSpeed;
 
+    unsigned m_NextPulse;
+    unsigned m_NextChildPulse;
+
     FontMap *m_Fonts;
 
     MythUIType *m_Parent;
Index: libs/libmythui/mythuiimage.cpp
===================================================================
--- libs/libmythui/mythuiimage.cpp	(revision 26040)
+++ libs/libmythui/mythuiimage.cpp	(working copy)
@@ -308,6 +308,7 @@
     m_Delay = delayms;
     m_LastDisplay = QTime::currentTime();
     m_CurPos = 0;
+    SetNextPulse(animPulse, (m_Delay > 0));
 }
 
 /**
@@ -345,6 +346,7 @@
     m_Filename = img->GetFileName();
     Clear();
     m_Delay = -1;
+    SetNextPulse(animPulse, false);
 
     img->UpRef();
 
@@ -1009,6 +1011,7 @@
     }
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, (m_Delay > 0));
 }
 
 /**
@@ -1189,6 +1192,7 @@
         {
             m_Delay = value.toInt();
         }
+        SetNextPulse(animPulse, (m_Delay > 0));
     }
     else if (element.tagName() == "reflection")
     {
@@ -1307,6 +1311,7 @@
     //SetImages(im->m_Images);
 
     MythUIType::CopyFrom(base);
+    SetNextPulse(animPulse, (m_Delay > 0));
 
     m_NeedLoad = im->m_NeedLoad;
 
Index: libs/libmythui/mythuitext.cpp
===================================================================
--- libs/libmythui/mythuitext.cpp	(revision 26040)
+++ libs/libmythui/mythuitext.cpp	(working copy)
@@ -453,6 +453,7 @@
     //
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, (m_colorCycling || m_scrolling));
 
     if (m_colorCycling)
     {
@@ -524,6 +525,7 @@
     incB = (endColor.blue() * 1.0 - curB) / m_numSteps;
 
     m_colorCycling = true;
+    SetNextPulse(animPulse, true);
 }
 
 void MythUIText::StopCycling(void)
@@ -673,6 +675,7 @@
             m_colorCycling = false;
 
         m_colorCycling = parseBool(element.attribute("disable"));
+        SetNextPulse(animPulse, (m_colorCycling || m_scrolling));
     }
     else if (element.tagName() == "scroll")
     {
@@ -696,6 +699,7 @@
         }
         else
             m_scrolling = false;
+        SetNextPulse(animPulse, (m_colorCycling || m_scrolling));
     }
     else if (element.tagName() == "case")
     {
@@ -769,6 +773,7 @@
     m_textCase = text->m_textCase;
 
     MythUIType::CopyFrom(base);
+    SetNextPulse(animPulse, (m_colorCycling || m_scrolling));
 }
 
 void MythUIText::CreateCopy(MythUIType *parent)
Index: libs/libmythui/mythuiwebbrowser.cpp
===================================================================
--- libs/libmythui/mythuiwebbrowser.cpp	(revision 26040)
+++ libs/libmythui/mythuiwebbrowser.cpp	(working copy)
@@ -621,6 +621,7 @@
     }
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, (m_updateInterval != 0));
 }
 
 /**
@@ -875,6 +876,7 @@
     {
         QString interval = getFirstText(element);
         m_updateInterval = interval.toInt();
+        SetNextPulse(animPulse, (m_updateInterval != 0));
     }
     else if (element.tagName() == "background")
     {
@@ -909,6 +911,7 @@
     m_widgetUrl = browser->m_widgetUrl;
     m_userCssFile = browser->m_userCssFile;
     m_updateInterval = browser->m_updateInterval;
+    SetNextPulse(animPulse, (m_updateInterval != 0));
 
     Init();
 }
Index: libs/libmythui/mythuitextedit.cpp
===================================================================
--- libs/libmythui/mythuitextedit.cpp	(revision 26040)
+++ libs/libmythui/mythuitextedit.cpp	(working copy)
@@ -78,7 +78,10 @@
 void MythUITextEdit::Pulse(void)
 {
     if (!m_cursorImage)
+    {
+        SetNextPulse(animPulse, false);
         return;
+    }
 
     if (m_HasFocus)
     {
@@ -102,6 +105,7 @@
         m_cursorImage->SetVisible(false);
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, true);
 }
 
 bool MythUITextEdit::ParseElement(
Index: libs/libmythui/mythuiclock.cpp
===================================================================
--- libs/libmythui/mythuiclock.cpp	(revision 26040)
+++ libs/libmythui/mythuiclock.cpp	(working copy)
@@ -52,6 +52,7 @@
     }
 
     MythUIText::Pulse();
+    SetNextPulse(animPulse, true);
 }
 
 /**
