Details
-
Bug
-
Resolution: Unresolved
-
P4: Low
-
None
-
5.15.2, 6.4.3, 6.6.2
-
None
-
Linux Ubuntu 22.04
Description
When renaming or moving a directory that is watched by the QFileSystemWatcher, no directoryChanged update is received for the given directory. Furthermore, the renamed / moved directory is still watched, and every modification done in the renamed dir, will be reported with the path to the old directory.
#include <QCoreApplication> #include <QFileSystemWatcher> #include <QDirIterator> #include <QDebug> void addRecursively(QFileSystemWatcher& watcher, const QString& path) { watcher.addPath(path); // Add the root path to watcher qDebug() << "Adding path to watcher " << path; QDirIterator it(path, QDir::Files|QDir::Dirs|QDir::NoDotAndDotDot, QDirIterator::Subdirectories); while (it.hasNext()) { QString entry(it.next()); qDebug() << "Adding path to watcher " << entry; watcher.addPath(entry); // Add every entry in path to watcher } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); /// CHANGE THIS TO YOUR PATH, or add test_folder to build dir. QString target = "./test_folder"; QFileSystemWatcher watcher; addRecursively(watcher, target); QObject::connect(&watcher, &QFileSystemWatcher::directoryChanged, [&](const QString& path) { qDebug() << "directoryChanged: " << path; addRecursively(watcher, path); }); QObject::connect(&watcher, &QFileSystemWatcher::fileChanged, [&](const QString& path) { qDebug() << "fileChanged: " << path; }); return a.exec(); }
In the above example we watch the test_folder and every directory and file inside of it for changes.
For our example the test_folder looks like this:
. ├── directory │ └── some_file.txt └── file.txt
Inside the test_folder renaming the directory to renamed_dir will result in a directory change for the test_folder, but no directory change for directory.
mv directory renamed_dir
The new renamed_dir will be added to the watch list resulting in the following output:
directoryChanged: "./test_folder" Adding path to watcher "./test_folder" Adding path to watcher "./test_folder/renamed_dir" Adding path to watcher "./test_folder/renamed_dir/some_file.txt" Adding path to watcher "./test_folder/file.txt"
Expectation would be that a directoryChanged signal to be emitted for the directory and that to be removed from the watcher. (It is not)
After this, modifying any file inside the renamed_dir will emit a directoryChanged signal with the wrong path (the old directory).
For example, creating a file inside the renamed_dir
touch renamed_dir/new_file.txt
Will give the following output:
directoryChanged: "./test_folder/directory" Adding path to watcher "./test_folder/directory"
Note that ./test_folder/directory doesn't even exist!
Expectation would be that the directoryChanged path would be ./test_folder/renamed_dir
Expectations based on documentation:
"The fileChanged() signal is emitted when a file has been modified, renamed or removed from disk. Similarly, the directoryChanged() signal is emitted when a directory or its contents is modified or removed. Note that QFileSystemWatcher stops monitoring files once they have been renamed or removed from disk, and directories once they have been removed from disk."
https://doc.qt.io/qt-6/qfilesystemwatcher.html