Bug 126744

Summary: Konqueror does not autodetect new plugins.
Product: [Applications] konqueror Reporter: Juergen Weigert <jw>
Component: nspluginscanAssignee: Konqueror Developers <konq-bugs>
Status: RESOLVED FIXED    
Severity: normal CC: l.lunak
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Juergen Weigert 2006-05-04 17:03:24 UTC
Version:            (using KDE KDE 3.5.1)
Installed from:    SuSE RPMs

running nspluginscan is a pain. It opens and reads all *.so files in the plugins directory, each time it runs.

In SUSE Linux we used to run nspluginscan at login, but disabled it for perfomance reasons. 

I suggest the following enhancement:
Record which plugins were already scanned, and rescan only those that changed
or are new. 
Write a message to the status bar explaing the delay, if you want to be nice.

See also http://bugzilla.novell.com/show_bug.cgi?id=160740
Comment 1 Lubos Lunak 2007-08-27 14:55:28 UTC
SVN commit 705205 by lunakl:

Defaulting to no scanning for new plugins is nice from performance point
of view, but it's completely unreasonable to expect the user to run
the check manually. Check timestamps to find out if a full scan is needed.
BUG: 126744



 M  +2 -2      Makefile.am  
 M  +67 -0     kcm_nsplugins.cpp  
 A             plugin_paths.cpp   [License: GPL (v2+)]
 A             plugin_paths.h   [License: no copyright]
 M  +2 -45     pluginscan.cpp  


--- branches/KDE/3.5/kdebase/nsplugins/Makefile.am #705204:705205
@@ -14,11 +14,11 @@
 libnsplugin_la_LIBADD  = -lkparts
 
 bin_PROGRAMS = nspluginscan
-nspluginscan_SOURCES = pluginscan.cpp
+nspluginscan_SOURCES = pluginscan.cpp plugin_paths.cpp
 nspluginscan_LDFLAGS =  $(KDE_RPATH) $(all_libraries) -export-dynamic
 nspluginscan_LDADD = $(LIB_KDEUI) $(LIB_KSYCOCA) -lXt
 
-kcm_nsplugins_la_SOURCES = kcm_nsplugins.cpp
+kcm_nsplugins_la_SOURCES = kcm_nsplugins.cpp plugin_paths.cpp
 kcm_nsplugins_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
 kcm_nsplugins_la_LIBADD = $(LIB_KDECORE)
 
--- branches/KDE/3.5/kdebase/nsplugins/kcm_nsplugins.cpp #705204:705205
@@ -36,6 +36,54 @@
 #include <dcopclient.h>
 #include <kprocio.h>
 
+#include "plugin_paths.h"
+
+static QDateTime lastChanged( QString dir )
+{
+    QDateTime t = QFileInfo( dir ).lastModified();
+    if( t.isNull())
+        return t;
+    QStringList subdirs = QDir( dir ).entryList();
+    for( QStringList::ConstIterator it = subdirs.begin();
+         it != subdirs.end();
+         ++it )
+    {
+        if( *it == "." || *it == ".." )
+            continue;
+        QDateTime t2 = lastChanged( *it );
+        if( !t2.isNull() && t2 > t )
+            t = t2;
+    }
+    return t;
+}
+
+static bool checkSearchPathTimestamps( QStringList paths, QStringList timestamps )
+{
+    QStringList currentTimestamps;
+    bool changed = false;
+    QStringList::ConstIterator t = timestamps.begin();
+    for( QStringList::ConstIterator it = paths.begin();
+         it != paths.end();
+         ++it, ++t )
+    {
+        QDateTime current = lastChanged( *it );
+        // store non-existent directory as "N" string rather than empty string, KConfig
+        // has a bug with storing a list of empty items
+        if( *t == "N" ? !current.isNull() : current != QDateTime::fromString( *t, Qt::ISODate ))
+            changed = true;
+        currentTimestamps.append( current.isNull() ? "N" : current.toString( Qt::ISODate ));
+    }
+    if( changed )
+    {
+        KConfig config("kcmnspluginrc");
+        config.setGroup("Misc");
+        config.writeEntry( "lastSearchPaths", paths );
+        config.writeEntry( "lastSearchTimestamps", currentTimestamps );
+        return true;
+    }
+    return false;
+}
+
 extern "C"
 {
     KDE_EXPORT void init_nsplugin()
@@ -44,6 +92,25 @@
         config->setGroup("Misc");
         bool scan = config->readBoolEntry( "startkdeScan", false );
         bool firstTime = config->readBoolEntry( "firstTime", true );
+        
+        if( !scan )
+        {
+        // check if plugins have changed, as just ignoring everything and requiring the user
+        // to trigger the check manually is not reasonable - that probably actually obsoletes
+        // both options
+            QStringList searchPaths = getSearchPaths();
+            QStringList lastSearchPaths = config->readListEntry( "lastSearchPaths" );
+            QStringList lastTimestamps = config->readListEntry ( "lastSearchTimestamps" );
+            if( searchPaths != lastSearchPaths || lastTimestamps.count() != lastSearchPaths.count())
+            { // count changed, set empty timestamps, still call checkSearchPathTimestamps()
+              // in order to save the current timestamps for the next time
+                lastSearchPaths = searchPaths;
+                lastTimestamps.clear();
+                lastTimestamps.insert( lastTimestamps.end(), searchPaths.count(), QString());
+            }
+            if( checkSearchPathTimestamps( lastSearchPaths, lastTimestamps ))
+                scan = true;
+        }
         delete config;
 
         if ( scan || firstTime )
--- branches/KDE/3.5/kdebase/nsplugins/pluginscan.cpp #705204:705205
@@ -56,6 +56,8 @@
 #include "sdk/npupp.h"
 #include <X11/Intrinsic.h>
 
+#include "plugin_paths.h"
+
 static int showProgress=0;
 
 // provide these symbols when compiling with gcc 3.x
@@ -444,51 +446,6 @@
 }
 
 
-QStringList getSearchPaths()
-{
-    QStringList searchPaths;
-
-    KConfig *config = new KConfig("kcmnspluginrc", false);
-    config->setGroup("Misc");
-
-    // setup default paths
-    if ( !config->hasKey("scanPaths") ) {
-        QStringList paths;
-        paths.append("$HOME/.mozilla/plugins");
-        paths.append("$HOME/.netscape/plugins");
-        paths.append("/usr/lib/firefox/plugins");
-        paths.append("/usr/lib64/browser-plugins");
-        paths.append("/usr/lib/browser-plugins");
-        paths.append("/usr/local/netscape/plugins");
-        paths.append("/opt/mozilla/plugins");
-	paths.append("/opt/mozilla/lib/plugins");
-        paths.append("/opt/netscape/plugins");
-        paths.append("/opt/netscape/communicator/plugins");
-        paths.append("/usr/lib/netscape/plugins");
-        paths.append("/usr/lib/netscape/plugins-libc5");
-        paths.append("/usr/lib/netscape/plugins-libc6");
-        paths.append("/usr/lib/mozilla/plugins");
-	paths.append("/usr/lib64/netscape/plugins");
-	paths.append("/usr/lib64/mozilla/plugins");
-        paths.append("$MOZILLA_HOME/plugins");
-        config->writeEntry( "scanPaths", paths );
-    }
-
-    // read paths
-    config->setDollarExpansion( true );
-    searchPaths = config->readListEntry( "scanPaths" );
-    delete config;
-
-    // append environment variable NPX_PLUGIN_PATH
-    QStringList envs = QStringList::split(':', getenv("NPX_PLUGIN_PATH"));
-    QStringList::Iterator it;
-    for (it = envs.begin(); it != envs.end(); ++it)
-        searchPaths.append(*it);
-
-    return searchPaths;
-}
-
-
 void writeServicesFile( QStringList mimeTypes )
 {
     QString fname = KGlobal::dirs()->saveLocation("services", "")