Index: libs/libmythui/mythuitype.h
===================================================================
--- libs/libmythui/mythuitype.h	(revision 23233)
+++ libs/libmythui/mythuitype.h	(working copy)
@@ -115,6 +115,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 *);
 
@@ -181,6 +191,9 @@
     QPoint m_XYDestination;
     QPoint m_XYSpeed;
 
+    unsigned m_NextPulse;
+    unsigned m_NextChildPulse;
+
     FontMap *m_Fonts;
 
     MythUIType *m_Parent;
Index: libs/libmythui/mythuitype.cpp
===================================================================
--- libs/libmythui/mythuitype.cpp	(revision 23233)
+++ libs/libmythui/mythuitype.cpp	(working copy)
@@ -44,6 +44,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)
     {
@@ -69,6 +72,7 @@
  */
 void MythUIType::Reset()
 {
+    SetNextPulse(true);
     // Reset all children
     QMutableListIterator<MythUIType *> it(m_ChildrenList);
     while (it.hasNext())
@@ -88,6 +92,7 @@
         return;
 
     m_ChildrenList.push_back(child);
+    FixupNextChildPulse();
 }
 
 static QObject *qChildHelper(const char *objName, const char *inheritsClass,
@@ -149,6 +154,7 @@
         {
             type->deleteLater();
             it.remove();
+            FixupNextChildPulse();
             return;
         }
     }
@@ -171,6 +177,7 @@
         {
             type->deleteLater();
             it.remove();
+            FixupNextChildPulse();
             child = NULL;
             return;
         }
@@ -191,6 +198,7 @@
     }
 
     m_ChildrenList.clear();
+    FixupNextChildPulse();
 }
 
 /** \brief Return the first MythUIType which accepts focus found at the given
@@ -307,10 +315,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();
@@ -344,16 +358,23 @@
     }
 
     m_Area.moveTopLeft(curXY);
+    SetNextPulse(animMovement, m_Moving);
 }
 
 void MythUIType::HandleAlphaPulse(void)
 {
     if (!GetMythPainter()->SupportsAlpha() ||
         !GetMythPainter()->SupportsAnimation())
+    {
+        SetNextPulse(animAlpha, false);
         return;
+    }
 
     if (m_AlphaChangeMode == 0)
+    {
+        SetNextPulse(animAlpha, false);
         return;
+    }
 
     m_Alpha += m_AlphaChange;
 
@@ -377,6 +398,7 @@
     }
 
     SetRedraw();
+    SetNextPulse(animAlpha, (m_AlphaChangeMode != 0));
 }
 
 void MythUIType::Pulse(void)
@@ -384,12 +406,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 & (1 << animPulse))
+    {
+        QList<MythUIType *>::Iterator it;
+        for (it = m_ChildrenList.begin(); it != m_ChildrenList.end(); ++it)
+            (*it)->Pulse();
+    }
+    SetNextPulse(animPulse, false);
 }
 
 int MythUIType::CalcAlpha(int alphamod)
@@ -532,7 +560,10 @@
                              int maxalpha)
 {
     if (!GetMythPainter()->SupportsAlpha())
+    {
+        SetNextPulse(animAlpha, false);
         return;
+    }
 
     m_AlphaChangeMode = mode;
     m_AlphaChange = alphachange;
@@ -543,6 +574,7 @@
         m_Alpha = m_AlphaMax;
     if (m_Alpha < m_AlphaMin)
         m_Alpha = m_AlphaMin;
+    SetNextPulse(animAlpha, (m_AlphaChangeMode != 0));
 }
 
 void MythUIType::SetAlpha(int newalpha)
@@ -615,6 +647,7 @@
         emit Showing();
     else
         emit Hiding();
+    FixupNextChildPulse();
 }
 
 void MythUIType::SetEnabled(bool enable)
@@ -677,6 +710,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)
@@ -840,3 +876,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/mythuiimage.cpp
===================================================================
--- libs/libmythui/mythuiimage.cpp	(revision 23233)
+++ libs/libmythui/mythuiimage.cpp	(working copy)
@@ -280,6 +280,7 @@
     m_Delay = delayms;
     m_LastDisplay = QTime::currentTime();
     m_CurPos = 0;
+    SetNextPulse(animPulse, (m_Delay > 0));
 }
 
 /**
@@ -298,6 +299,7 @@
     m_Filename = img->GetFileName();
     Clear();
     m_Delay = -1;
+    SetNextPulse(animPulse, false);
 
     img->UpRef();
 
@@ -839,6 +841,7 @@
     }
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, (m_Delay > 0));
 }
 
 /**
@@ -982,7 +985,10 @@
     else if (element.tagName() == "crop")
         m_cropRect = parseRect(element);
     else if (element.tagName() == "delay")
+    {
         m_Delay = getFirstText(element).toInt();
+        SetNextPulse(animPulse, (m_Delay > 0));
+    }
     else if (element.tagName() == "reflection")
     {
         m_isReflected = true;
Index: libs/libmythui/mythuitext.cpp
===================================================================
--- libs/libmythui/mythuitext.cpp	(revision 23233)
+++ libs/libmythui/mythuitext.cpp	(working copy)
@@ -315,6 +315,7 @@
     //
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, (m_colorCycling || m_scrolling));
 
     if (m_colorCycling)
     {
Index: libs/libmythui/mythuiwebbrowser.cpp
===================================================================
--- libs/libmythui/mythuiwebbrowser.cpp	(revision 23233)
+++ libs/libmythui/mythuiwebbrowser.cpp	(working copy)
@@ -534,6 +534,7 @@
     }
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, (m_updateInterval != 0));
 }
 
 void MythUIWebBrowser::DrawSelf(MythPainter *p, int xoffset, int yoffset,
Index: libs/libmythui/mythuitextedit.cpp
===================================================================
--- libs/libmythui/mythuitextedit.cpp	(revision 23233)
+++ libs/libmythui/mythuitextedit.cpp	(working copy)
@@ -73,7 +73,10 @@
 void MythUITextEdit::Pulse(void)
 {
     if (!m_cursorImage)
+    {
+        SetNextPulse(animPulse, false);
         return;
+    }
 
     if (m_HasFocus)
     {
@@ -92,6 +95,7 @@
         m_cursorImage->SetVisible(false);
 
     MythUIType::Pulse();
+    SetNextPulse(animPulse, true);
 }
 
 bool MythUITextEdit::ParseElement(QDomElement &element)
Index: libs/libmythui/mythuiclock.cpp
===================================================================
--- libs/libmythui/mythuiclock.cpp	(revision 23233)
+++ libs/libmythui/mythuiclock.cpp	(working copy)
@@ -64,6 +64,7 @@
     }
 
     MythUIText::Pulse();
+    SetNextPulse(animPulse, true);
 }
 
 bool MythUIClock::ParseElement(QDomElement &element)
