[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    KDirWatch regression with FAM (#38490)
From:       Malte Starostik <malte () kde ! org>
Date:       2002-02-22 20:27:50
[Download RAW message or body]

Hi,

in KDE 2, when only a single file, i.e. its mtime or size, changed, KDirWatch 
emitted fileDirty(), now it emits dirDirty() for the parent directory. This 
leads to constants reloads of the home directory in konq whenever 
~/.xsession-errors is written to. Since konq tends to write debug info into 
it on some mouse movements, this is rather bad :-(
I had a look at kdirwatch.cpp, but there seems to be a design flaw wrt single 
file changes in it - AFAIK this was not the case in the KDE 2 version of it:
KDirWatchPrivate only passes an Entry * to its clients (KDirWatch). This Entry 
has isDir set to false in this case as a directory is being watched, but only 
a file changed. Thus, in the case of FAM, KDirWatchPrivate knows that only a 
file was changed but has no way to pass that info on to KDirWatch and instead 
tells KDirWatch that the whole dir changed.
Attached patch fixes this particular case, but it looks a little bit hacky to 
me...

-- 
Malte Starostik
PGP: 1024D/D2F3C787 [C138 2121 FAF3 410A 1C2A  27CD 5431 7745 D2F3 C787]

["kdirwatch.diff" (text/x-diff)]

Index: kdirwatch.cpp
===================================================================
RCS file: /home/kde/kdelibs/kio/kio/kdirwatch.cpp,v
retrieving revision 1.65
diff -u -3 -d -p -r1.65 kdirwatch.cpp
--- kdirwatch.cpp	2002/02/20 19:18:31	1.65
+++ kdirwatch.cpp	2002/02/22 20:26:58
@@ -676,7 +676,7 @@ int KDirWatchPrivate::scanEntry(Entry* e
  * and stored pending events. When watching is stopped, the event is
  * added to the pending events.
  */
-void KDirWatchPrivate::emitEvent(Entry* e, int event)
+void KDirWatchPrivate::emitEvent(Entry* e, int event, const QString &fileName)
 {
   Client* c = e->m_clients.first();
   for(;c;c=e->m_clients.next()) {
@@ -714,7 +714,9 @@ void KDirWatchPrivate::emitEvent(Entry* 
     }
 
     if (event & Changed) {
-      if (e->isDir)
+      if (!fileName.isEmpty())
+	c->instance->setFileDirty(e->path + fileName);
+      else if (e->isDir)
 	c->instance->setDirDirty(e->path);
       else
 	c->instance->setFileDirty(e->path);      
@@ -872,7 +874,10 @@ void KDirWatchPrivate::checkFAMEvent(FAM
     // leads to a never ending stream of cause & result.
     if (strncmp(fe->filename, ".directory", 10) == 0) return;
 
-    emitEvent(e, Changed);
+    if (fe->code == FAMChanged)
+      emitEvent(e, Changed, fe->filename);
+    else
+      emitEvent(e, Changed);
 
     if (fe->code == FAMCreated) {
       // check for creation of a directory we have to watch
Index: kdirwatch_p.h
===================================================================
RCS file: /home/kde/kdelibs/kio/kio/kdirwatch_p.h,v
retrieving revision 1.2
diff -u -3 -d -p -r1.2 kdirwatch_p.h
--- kdirwatch_p.h	2002/01/24 23:52:04	1.2
+++ kdirwatch_p.h	2002/02/22 20:26:58
@@ -77,7 +77,7 @@ public:
 
   Entry* entry(const QString&);
   int scanEntry(Entry* e);
-  void emitEvent(Entry* e, int event);
+  void emitEvent(Entry* e, int event, const QString &fileName = QString::null);
 
 public slots:
   void slotRescan();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic