Bug 91240

Summary: konqueror sends commands to X server, even when window is minimized.
Product: [Applications] konqueror Reporter: theosib
Component: generalAssignee: Konqueror Developers <konq-bugs>
Status: RESOLVED FIXED    
Severity: wishlist CC: camil, dax, maksim, syntaxaire
Priority: NOR    
Version: 3.3   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description theosib 2004-10-13 14:43:32 UTC
Version:           3.3 (using KDE KDE 3.3.0)
Compiler:          gcc 
OS:                Linux

I noticed that my X server was using 14% of CPU time for no good reason.  I tracked it down to a Konqueror window which was minimized but which had animations going on.  'top' did not report any other process using appreciable CPU.

My assertion is that if a window is minimized, konqueror (well, Qt, I guess) should not be sending commands to the X server that are just going to get clipped and discarded anyhow.

[soapbox]And while I agree that the X server should be better designed so that it doesn't waste CPU time for nothing, only when every party involved agrees to take the initiative to resolve the problem on their own (rather than saying "it's not my problem") will anything EVER get done.[/soapbox]
Comment 1 Dik Takken 2004-10-13 23:36:15 UTC
Well, the same happens to Firefox. Displaying a few animated gifs like these:

http://www.gifs.net/animate/pagelett.htm

take 70% of my 800 MHz, no matter if the window is minimised or not.

Could it be the responsibility of the window manager to unmap a window when minimized?
Comment 2 theosib 2004-10-14 03:58:58 UTC
A window manager DOES unmap a window when it's minimized.

I develop X11 drivers (DDX modules) for OpenWindows (Sun's X server under Solaris), and when we were trying to get certification from Sun, one of the 'problems' they reported back to us was that with our DDX, the X server was using a non-trivial amount of CPU time when an application was drawing with a planemask of zero, with a rop of GXnoop, or to a window which was iconified.  We fixed that, and now, very little CPU time is used by Xsun when doing these pathological things.

I would definately agree with anyone that says that drawing to a minimized window is an X server internals issue.  However, there are two reasons why it's also a Konqueror/Qt issue:

1) X11 apps need to be well-behaved, and something as important as KDE should be a paragon of 'well behaved'.

2) You'll die before the X.org people will get around to fixing this problem themselves.

Comment 3 Stephan Kulow 2004-10-14 10:35:59 UTC
*** Bug 91283 has been marked as a duplicate of this bug. ***
Comment 4 Tommi Tervo 2005-04-13 14:08:26 UTC
*** Bug 103345 has been marked as a duplicate of this bug. ***
Comment 5 Martin Koller 2006-12-30 00:44:25 UTC
*** Bug 34134 has been marked as a duplicate of this bug. ***
Comment 6 Martin Koller 2006-12-31 01:37:45 UTC
SVN commit 618069 by mkoller:

BUG: 91240

Pause animations whenever a HTML view is hidden and resume animations
when it's shown again. This greatly reduces CPU usage when there are
a lot of animated images in hidden tabs or minimized windows


 M  +5 -0      khtmlview.cpp  
 M  +33 -0     misc/loader.cpp  
 M  +4 -0      misc/loader.h  


--- branches/KDE/3.5/kdelibs/khtml/khtmlview.cpp #618068:618069
@@ -50,6 +50,7 @@
 #include "css/csshelper.h"
 #include "misc/htmlhashes.h"
 #include "misc/helper.h"
+#include "misc/loader.h"
 #include "khtml_settings.h"
 #include "khtml_printsettings.h"
 
@@ -571,11 +572,15 @@
 void KHTMLView::hideEvent(QHideEvent* e)
 {
     QScrollView::hideEvent(e);
+    if ( m_part && m_part->xmlDocImpl() )
+        m_part->xmlDocImpl()->docLoader()->pauseAnimations();
 }
 
 void KHTMLView::showEvent(QShowEvent* e)
 {
     QScrollView::showEvent(e);
+    if ( m_part && m_part->xmlDocImpl() )
+        m_part->xmlDocImpl()->docLoader()->resumeAnimations();
 }
 
 void KHTMLView::resizeEvent (QResizeEvent* e)
--- branches/KDE/3.5/kdelibs/khtml/misc/loader.cpp #618068:618069
@@ -794,6 +794,17 @@
     }
 }
 
+void CachedImage::pauseAnimations()
+{
+    if ( m ) m->pause();
+}
+
+void CachedImage::resumeAnimations()
+{
+    if ( m ) m->unpause();
+}
+
+
 void CachedImage::deleteMovie()
 {
     delete m; m = 0;
@@ -1088,6 +1099,28 @@
         }
 }
 
+void DocLoader::pauseAnimations()
+{
+    for ( QPtrDictIterator<CachedObject> it( m_docObjects ); it.current(); ++it )
+        if ( it.current()->type() == CachedObject::Image )
+        {
+            CachedImage *img = const_cast<CachedImage*>( static_cast<const CachedImage *>( it.current() ) );
+
+            img->pauseAnimations();
+        }
+}
+
+void DocLoader::resumeAnimations()
+{
+    for ( QPtrDictIterator<CachedObject> it( m_docObjects ); it.current(); ++it )
+        if ( it.current()->type() == CachedObject::Image )
+        {
+            CachedImage *img = const_cast<CachedImage*>( static_cast<const CachedImage *>( it.current() ) );
+
+            img->resumeAnimations();
+        }
+}
+
 // ------------------------------------------------------------------------------------------
 
 Loader::Loader() : QObject()
--- branches/KDE/3.5/kdelibs/khtml/misc/loader.h #618068:618069
@@ -287,6 +287,8 @@
 #endif
 
         void setShowAnimations( KHTMLSettings::KAnimationAdvice );
+        void pauseAnimations();
+        void resumeAnimations();
 
         virtual bool schedule() const { return true; }
 
@@ -363,6 +365,8 @@
         void setAutoloadImages( bool );
         void setCachePolicy( KIO::CacheControl cachePolicy ) { m_cachePolicy = cachePolicy; }
         void setShowAnimations( KHTMLSettings::KAnimationAdvice );
+        void pauseAnimations();
+        void resumeAnimations();
         void insertCachedObject( CachedObject* o ) const;
         void removeCachedObject( CachedObject* o) const { m_docObjects.remove( o ); }
 
Comment 7 Martin Koller 2009-09-30 22:00:55 UTC
*** Bug 132932 has been marked as a duplicate of this bug. ***