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

List:       kde-core-devel
Subject:    KDirWatch emitting dirty signal many times for one change
From:       Matthias Kretz <kretz () kde ! org>
Date:       2004-03-23 11:39:36
Message-ID: 200403231239.40801.kretz () kde ! org
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


Hi,

I have a problem with KDirWatch that I just cannot find a way to work with:

In KView the currently shown image is added to the dir watcher:
m_pFileWatch->addFile( m_file );
The dirty signal is connected to slotFileDirty which does a reload of the 
image if the image wasn't modified in KView.

But whenever the image was modified in KView and you call "Save" the 
slotFileDirty slot is called (asynchronous). Problem: KDirWatch apparently 
emits dirty 18 times.

I now have a workaround for KView that disables the slotFileDirty for 100ms 
with a singleShot timer. But this is butt ugly so if there's any way we could 
fix this the right way (TM) I'd be very happy. :-)

I just wrote a testcase to illustrate the point. Do the following:
moc testcase.cpp > testcase.moc
g++ -L$KDEDIR/lib -L$QTDIR/lib -lkio -I$QTDIR/include -I$KDEDIR/include 
testcase.cpp -o testcase
./testcase testfile

I get 271 dirty notifications with that program. :-(

-- 
C'ya
        Matthias
________________________________________________________
Matthias Kretz (Germany)                          <><
http://Vir.homeip.net/
MatthiasKretz@gmx.net, kretz@kde.org,
Matthias.Kretz@urz.uni-heidelberg.de

["testcase.cpp" (text/x-c++src)]

#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kdirwatch.h>
#include <qstring.h>
#include <kdebug.h>
#include <qtimer.h>
#include <qfile.h>
#include <kurl.h>

class Test : public QObject
{
	Q_OBJECT
	public:
		Test( const KURL & url )
		{
			dirwatch = new KDirWatch( this );
			connect( dirwatch, SIGNAL( dirty( const QString & ) ), SLOT( dirty( const QString & ) ) );
			QTimer::singleShot( 0, this, SLOT( openFile() ) );
			filename = url.path();
		}

		~Test()
		{
			delete dirwatch;
		}

	private slots:
		void openFile()
		{
			file.setName( filename );
			file.open( IO_ReadWrite );
			dirwatch->addFile( filename );
			QTimer::singleShot( 100, this, SLOT( saveFile() ) );
		}

		void saveFile()
		{
			for( int i = 0; i < 4 * 1024; ++i )
				file.writeBlock(
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						"foo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\nfoo\n"
						, 1024 );
			file.close();
			QTimer::singleShot( 2000, kapp, SLOT( quit() ) );
		}

		void dirty( const QString & file )
		{
			static int count = 0;
			++count;
			kdDebug() << k_funcinfo << file << " " << count << endl;
		}

	private:
		QString filename;
		QFile file;
		KDirWatch * dirwatch;
};

static KCmdLineOptions options[] =
{
	{ "+URL", "testcase file", 0 },
	KCmdLineLastOption
};

int main( int argc, char ** argv )
{
	KCmdLineArgs::init( argc, argv, "test", "test", "test", "1.0" );
	KCmdLineArgs::addCmdLineOptions( options );
	KApplication app;
	KCmdLineArgs * args = KCmdLineArgs::parsedArgs();
	if( ! args->url( 0 ).isEmpty() )
	{
		Test * test = new Test( args->url( 0 ) );
		return app.exec();
	}
}

// vim: sw=4 ts=4
#include "testcase.moc"

[Attachment #6 (application/pgp-signature)]

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

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