From b4250871ecbf8a2704377a2c26040253bd04efcb Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Jun 2024 12:42:45 +0200 Subject: [PATCH] DocumentManager: Use FilePath::watch() instead of QFileSystemWatcher Change-Id: I9fcbbc62366f3191bfca3ecce937ad11109e885c Reviewed-by: Eike Ziller Reviewed-by: hjk --- src/plugins/coreplugin/documentmanager.cpp | 100 ++++++++++++--------- src/plugins/coreplugin/documentmanager.h | 2 +- 2 files changed, 60 insertions(+), 42 deletions(-) diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 7752c6a922a..3c6487d9ae1 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -135,13 +135,55 @@ struct FileState FileStateItem expected; }; +class FileWatchers : public QObject +{ + Q_OBJECT +public: + FilePaths files() const { return watchers.keys(); } + + bool addPath(const FilePath &path) + { + if (watchers.contains(path)) + return false; + + auto res = path.watch(); + QTC_ASSERT_EXPECTED(res, return false;); + + connect(res->get(), &FilePathWatcher::pathChanged, this, [this, path] { + emit fileChanged(path); + }); + watchers.insert(path, std::move(*res)); + return true; + } + + void addPaths(const FilePaths &paths) + { + for (const FilePath &path : paths) + addPath(path); + } + + bool removePath(const FilePath &path) + { + if (!watchers.contains(path)) + return false; + + watchers.remove(path); + return true; + } + +signals: + void fileChanged(const FilePath &filePath); + +protected: + QMap> watchers; +}; + class DocumentManagerPrivate final : public QObject { public: DocumentManagerPrivate(); - QFileSystemWatcher *fileWatcher(); - QFileSystemWatcher *linkWatcher(); + FileWatchers *fileWatcher(); void checkOnNextFocusChange(); void onApplicationFocusChange(); @@ -159,8 +201,7 @@ public: bool m_checkOnFocusChange = false; bool m_useProjectsDirectory = kUseProjectsDirectoryDefault; - QFileSystemWatcher *m_fileWatcher = nullptr; // Delayed creation. - QFileSystemWatcher *m_linkWatcher = nullptr; // Delayed creation (only UNIX/if a link is seen). + FileWatchers m_fileWatcher; // Delayed creation. FilePath m_lastVisitedDirectory = FilePath::fromString(QDir::currentPath()); FilePath m_defaultLocationForNewFiles; FilePath m_projectsDirectory; @@ -177,29 +218,9 @@ public: static DocumentManager *m_instance; static DocumentManagerPrivate *d; -QFileSystemWatcher *DocumentManagerPrivate::fileWatcher() +FileWatchers *DocumentManagerPrivate::fileWatcher() { - if (!m_fileWatcher) { - m_fileWatcher= new QFileSystemWatcher(m_instance); - QObject::connect(m_fileWatcher, &QFileSystemWatcher::fileChanged, - m_instance, &DocumentManager::changedFile); - } - return m_fileWatcher; -} - -QFileSystemWatcher *DocumentManagerPrivate::linkWatcher() -{ - if (HostOsInfo::isAnyUnixHost()) { - if (!m_linkWatcher) { - m_linkWatcher = new QFileSystemWatcher(m_instance); - m_linkWatcher->setObjectName(QLatin1String("_qt_autotest_force_engine_poller")); - QObject::connect(m_linkWatcher, &QFileSystemWatcher::fileChanged, - m_instance, &DocumentManager::changedFile); - } - return m_linkWatcher; - } - - return fileWatcher(); + return &m_fileWatcher; } void DocumentManagerPrivate::checkOnNextFocusChange() @@ -238,6 +259,9 @@ DocumentManager::DocumentManager(QObject *parent) d = new DocumentManagerPrivate; m_instance = this; + QObject::connect( + &d->m_fileWatcher, &FileWatchers::fileChanged, this, &DocumentManager::changedFile); + connect(Utils::GlobalFileChangeBlocker::instance(), &Utils::GlobalFileChangeBlocker::stateChanged, this, [](bool blocked) { d->m_postponeAutoReload = blocked; @@ -302,7 +326,7 @@ static void addFileInfos(const QList &documents) linkPathsToWatch.append(d->m_states.value(filePath).watchedFilePath); pathsToWatch.append(d->m_states.value(resolvedFilePath).watchedFilePath); } - } else if (!filePath.needsDevice()) { + } else { pathsToWatch.append(d->m_states.value(filePath).watchedFilePath); } } @@ -311,11 +335,11 @@ static void addFileInfos(const QList &documents) // update link targets, even if there are multiple documents registered for it if (!pathsToWatch.isEmpty()) { qCDebug(log) << "adding full watch for" << pathsToWatch; - d->fileWatcher()->addPaths(Utils::transform(pathsToWatch, &FilePath::toString)); + d->fileWatcher()->addPaths(pathsToWatch); } if (!linkPathsToWatch.isEmpty()) { qCDebug(log) << "adding link watch for" << linkPathsToWatch; - d->linkWatcher()->addPaths(Utils::transform(linkPathsToWatch, &FilePath::toString)); + d->fileWatcher()->addPaths(linkPathsToWatch); } } @@ -379,16 +403,9 @@ static void removeFileInfo(IDocument *document) if (d->m_states.value(filePath).lastUpdatedState.isEmpty()) { const FilePath &watchedFilePath = d->m_states.value(filePath).watchedFilePath; if (!watchedFilePath.needsDevice()) { - const QString &localFilePath = watchedFilePath.path(); - if (d->m_fileWatcher - && d->m_fileWatcher->files().contains(localFilePath)) { - qCDebug(log) << "removing watch for" << localFilePath; - d->m_fileWatcher->removePath(localFilePath); - } - if (d->m_linkWatcher - && d->m_linkWatcher->files().contains(localFilePath)) { - qCDebug(log) << "removing watch for" << localFilePath; - d->m_linkWatcher->removePath(localFilePath); + if (d->m_fileWatcher.files().contains(watchedFilePath)) { + qCDebug(log) << "removing watch for" << watchedFilePath; + d->m_fileWatcher.removePath(watchedFilePath); } } d->m_states.remove(filePath); @@ -1031,9 +1048,8 @@ FilePaths DocumentManager::getOpenFileNames(const QString &filters, return files; } -void DocumentManager::changedFile(const QString &fileName) +void DocumentManager::changedFile(const FilePath &filePath) { - const FilePath filePath = FilePath::fromString(fileName); const bool wasempty = d->m_changedFiles.isEmpty(); if (d->m_states.contains(filePathKey(filePath, KeepLinks))) @@ -1567,3 +1583,5 @@ FileChangeBlocker::~FileChangeBlocker() } } // namespace Core + +#include "documentmanager.moc" diff --git a/src/plugins/coreplugin/documentmanager.h b/src/plugins/coreplugin/documentmanager.h index 67b65659a4b..4e40660fa12 100644 --- a/src/plugins/coreplugin/documentmanager.h +++ b/src/plugins/coreplugin/documentmanager.h @@ -148,7 +148,7 @@ private: void documentDestroyed(QObject *obj); void checkForNewFileName(IDocument *document); void checkForReload(); - void changedFile(const QString &file); + void changedFile(const Utils::FilePath &file); void updateSaveAll(); static void registerSaveAllAction();