Skip to content

Commit fb7ab3c

Browse files
committed
Only watch the desktop folders
- Create less fs watchers - Just re-scan when a directory containing .desktop files changes
1 parent 16512ac commit fb7ab3c

File tree

3 files changed

+28
-142
lines changed

3 files changed

+28
-142
lines changed

src/core/desktopentry.cpp

Lines changed: 19 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -384,67 +384,33 @@ DesktopEntry* DesktopEntryManager::byId(const QString& id) {
384384
ObjectModel<DesktopEntry>* DesktopEntryManager::applications() { return &this->mApplications; }
385385

386386
void DesktopEntryManager::handleFileChanges(
387-
const QHash<QString, DesktopEntryMonitor::ChangeEvent>& changes
387+
const QHash<QString, DesktopEntryMonitor::ChangeEvent>&
388388
) {
389+
qCDebug(logDesktopEntry) << "Directory change detected, performing full rescan";
389390

390-
qCDebug(logDesktopEntry) << "Handling file changes:" << changes.size() << "changes";
391-
392-
bool needsUpdate = false;
393-
394-
for (auto it = changes.begin(); it != changes.end(); ++it) {
395-
const QString& path = it.key();
396-
DesktopEntryMonitor::ChangeEvent event = it.value();
397-
398-
switch (event) {
399-
case DesktopEntryMonitor::ChangeEvent::Added:
400-
case DesktopEntryMonitor::ChangeEvent::Modified: {
401-
// Parse the desktop file
402-
QFile file(path);
403-
if (file.open(QFile::ReadOnly)) {
404-
QString id = this->extractIdFromPath(path);
405-
auto* entry = new DesktopEntry(id, this);
406-
entry->parseEntry(QString::fromUtf8(file.readAll()));
407-
408-
if (entry->isValid()) {
409-
// Remove old entry if exists
410-
if (this->desktopEntries.contains(id)) {
411-
auto* oldEntry = this->desktopEntries.value(id);
412-
this->desktopEntries.remove(id);
413-
this->lowercaseDesktopEntries.remove(id.toLower());
414-
oldEntry->deleteLater();
415-
}
416-
417-
this->desktopEntries.insert(id, entry);
418-
this->lowercaseDesktopEntries.insert(id.toLower(), entry);
419-
needsUpdate = true;
420-
421-
qCDebug(logDesktopEntry) << "Updated desktop entry:" << id;
422-
} else {
423-
delete entry;
424-
}
425-
}
426-
break;
427-
}
391+
auto oldEntries = this->desktopEntries;
428392

429-
case DesktopEntryMonitor::ChangeEvent::Removed: {
430-
QString id = this->extractIdFromPath(path);
431-
if (this->desktopEntries.contains(id)) {
432-
auto* entry = this->desktopEntries.take(id);
433-
this->lowercaseDesktopEntries.remove(id.toLower());
434-
entry->deleteLater();
435-
needsUpdate = true;
393+
this->desktopEntries.clear();
394+
this->lowercaseDesktopEntries.clear();
436395

437-
qCDebug(logDesktopEntry) << "Removed desktop entry:" << id;
438-
}
439-
break;
440-
}
396+
this->scanDesktopEntries();
397+
398+
QVector<DesktopEntry*> newApplications;
399+
for (auto& entry: this->desktopEntries.values()) {
400+
if (!entry->noDisplay()) {
401+
newApplications.append(entry);
441402
}
442403
}
443404

444-
if (needsUpdate) {
445-
this->updateApplicationModel();
446-
emit applicationsChanged();
405+
this->mApplications.diffUpdate(newApplications);
406+
407+
for (auto* e: oldEntries) {
408+
if (!this->desktopEntries.contains(e->mId)) {
409+
e->deleteLater();
410+
}
447411
}
412+
413+
emit applicationsChanged();
448414
}
449415

450416
QString DesktopEntryManager::extractIdFromPath(const QString& path) {

src/core/desktopentrymonitor.cpp

Lines changed: 9 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ DesktopEntryMonitor::DesktopEntryMonitor(QObject* parent): QObject(parent) {
3030
this,
3131
&DesktopEntryMonitor::onDirectoryChanged
3232
);
33-
connect(
34-
this->watcher,
35-
&QFileSystemWatcher::fileChanged,
36-
this,
37-
&DesktopEntryMonitor::onFileChanged
38-
);
3933
connect(this->debounceTimer, &QTimer::timeout, this, &DesktopEntryMonitor::processChanges);
4034

4135
// Start monitoring
@@ -68,18 +62,6 @@ void DesktopEntryMonitor::scanAndWatch(const QString& dirPath) {
6862
qCDebug(logDesktopMonitor) << "Added directory to watcher:" << dirPath;
6963
}
7064

71-
// Add .desktop files
72-
for (const auto& entry: dir.entryInfoList({"*.desktop"}, QDir::Files)) {
73-
auto path = entry.absoluteFilePath();
74-
if (!this->watchedFiles.contains(path)) {
75-
if (this->watcher->addPath(path)) {
76-
this->fileTimestamps[path] = entry.lastModified();
77-
this->watchedFiles.insert(path);
78-
qCDebug(logDesktopMonitor) << "Monitoring file:" << path;
79-
}
80-
}
81-
}
82-
8365
// Recurse into subdirs
8466
for (const auto& sub: dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
8567
this->scanAndWatch(dir.absoluteFilePath(sub));
@@ -94,52 +76,11 @@ void DesktopEntryMonitor::onDirectoryChanged(const QString& path) {
9476
if (!dir.exists()) {
9577
qCDebug(logDesktopMonitor) << "Directory no longer exists, cleaning up:" << path;
9678
this->watcher->removePath(path);
97-
98-
// Remove all watched files from this directory and its subdirectories
99-
for (auto it = this->watchedFiles.begin(); it != this->watchedFiles.end();) {
100-
const QString& watchedFile = *it;
101-
if (watchedFile.startsWith(path + "/") || watchedFile == path) {
102-
this->watcher->removePath(watchedFile);
103-
this->fileTimestamps.remove(watchedFile);
104-
this->queueChange(ChangeEvent::Removed, watchedFile);
105-
qCDebug(logDesktopMonitor) << "Removed file due to directory deletion:" << watchedFile;
106-
it = this->watchedFiles.erase(it);
107-
} else {
108-
++it;
109-
}
110-
}
79+
// Directory removal will be handled by full rescan
80+
this->queueChange(ChangeEvent::Modified, path); // Trigger full rescan
11181
return;
11282
}
11383

114-
QList<QString> currentFiles = dir.entryList({"*.desktop"}, QDir::Files);
115-
116-
// Check for new files
117-
for (const QString& file: currentFiles) {
118-
QString fullPath = dir.absoluteFilePath(file);
119-
if (!this->watchedFiles.contains(fullPath)) {
120-
if (this->watcher->addPath(fullPath)) {
121-
this->fileTimestamps[fullPath] = QFileInfo(fullPath).lastModified();
122-
this->watchedFiles.insert(fullPath);
123-
this->queueChange(ChangeEvent::Added, fullPath);
124-
qCDebug(logDesktopMonitor) << "New desktop file detected:" << fullPath;
125-
}
126-
}
127-
}
128-
129-
// Check for deleted files
130-
for (auto it = this->watchedFiles.begin(); it != this->watchedFiles.end();) {
131-
const QString& watchedFile = *it;
132-
if (QFileInfo(watchedFile).dir().absolutePath() == path && !QFile::exists(watchedFile)) {
133-
this->watcher->removePath(watchedFile);
134-
this->fileTimestamps.remove(watchedFile);
135-
this->queueChange(ChangeEvent::Removed, watchedFile);
136-
qCDebug(logDesktopMonitor) << "Desktop file removed:" << watchedFile;
137-
it = this->watchedFiles.erase(it);
138-
} else {
139-
++it;
140-
}
141-
}
142-
14384
// Check for new subdirectories
14485
QList<QString> subdirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
14586
for (const QString& subdir: subdirs) {
@@ -148,27 +89,9 @@ void DesktopEntryMonitor::onDirectoryChanged(const QString& path) {
14889
this->scanAndWatch(subdirPath);
14990
}
15091
}
151-
}
152-
153-
void DesktopEntryMonitor::onFileChanged(const QString& path) {
154-
if (QFileInfo(path).suffix().toLower() != "desktop") return;
15592

156-
QFileInfo info(path);
157-
if (info.exists()) {
158-
QDateTime currentModified = info.lastModified();
159-
if (this->fileTimestamps.value(path) != currentModified) {
160-
this->fileTimestamps[path] = currentModified;
161-
this->queueChange(ChangeEvent::Modified, path);
162-
qCDebug(logDesktopMonitor) << "Desktop file modified:" << path;
163-
}
164-
} else {
165-
// File was deleted
166-
this->watcher->removePath(path);
167-
this->fileTimestamps.remove(path);
168-
this->watchedFiles.remove(path);
169-
this->queueChange(ChangeEvent::Removed, path);
170-
qCDebug(logDesktopMonitor) << "Desktop file removed:" << path;
171-
}
93+
// Queue a change to trigger full rescan of all desktop paths
94+
this->queueChange(ChangeEvent::Modified, path);
17295
}
17396

17497
void DesktopEntryMonitor::queueChange(ChangeEvent event, const QString& path) {
@@ -179,10 +102,12 @@ void DesktopEntryMonitor::queueChange(ChangeEvent event, const QString& path) {
179102
void DesktopEntryMonitor::processChanges() {
180103
if (this->pendingChanges.isEmpty()) return;
181104

182-
qCDebug(logDesktopMonitor) << "Processing" << this->pendingChanges.size() << "pending changes";
105+
qCDebug(logDesktopMonitor) << "Processing directory changes, triggering full rescan";
183106

184-
QHash<QString, ChangeEvent> changes = this->pendingChanges;
107+
// Clear pending changes since we're doing a full rescan
185108
this->pendingChanges.clear();
186109

187-
emit desktopEntriesChanged(changes);
110+
// Emit with empty hash to signal full rescan needed
111+
QHash<QString, ChangeEvent> emptyChanges;
112+
emit desktopEntriesChanged(emptyChanges);
188113
}

src/core/desktopentrymonitor.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
#pragma once
22

3-
#include <qdatetime.h>
43
#include <qfilesystemwatcher.h>
54
#include <qhash.h>
65
#include <qobject.h>
7-
#include <qset.h>
86
#include <qstringlist.h>
97
#include <qtimer.h>
108

@@ -22,7 +20,6 @@ class DesktopEntryMonitor: public QObject {
2220

2321
private slots:
2422
void onDirectoryChanged(const QString& path);
25-
void onFileChanged(const QString& path);
2623
void processChanges();
2724

2825
private:
@@ -34,8 +31,6 @@ private slots:
3431

3532
QFileSystemWatcher* watcher;
3633
QStringList desktopPaths;
37-
QHash<QString, QDateTime> fileTimestamps;
38-
QSet<QString> watchedFiles;
3934
QTimer* debounceTimer;
4035
QHash<QString, ChangeEvent> pendingChanges;
4136
};

0 commit comments

Comments
 (0)