summaryrefslogtreecommitdiffstats
path: root/wayland
diff options
context:
space:
mode:
Diffstat (limited to 'wayland')
-rw-r--r--wayland/democompositor/apps/applistmodel.cpp59
-rw-r--r--wayland/democompositor/apps/applistmodel.h7
-rw-r--r--wayland/democompositor/qml/Screen.qml4
3 files changed, 64 insertions, 6 deletions
diff --git a/wayland/democompositor/apps/applistmodel.cpp b/wayland/democompositor/apps/applistmodel.cpp
index 0b4d620..b0774f7 100644
--- a/wayland/democompositor/apps/applistmodel.cpp
+++ b/wayland/democompositor/apps/applistmodel.cpp
@@ -135,25 +135,74 @@ void AppListModel::addDir(const QString& dirName)
{
QDirIterator dirIt(dirName, QDir::Files | QDir::NoDotAndDotDot | QDir::Readable);
+ // We want to deal with the corner case of some files being
+ // removed. One option would have been to keep a marker bit
+ // inside the AppEntry but that might leak too much of the
+ // implementation to the outside. Let's keep a list of file
+ // names that came from the directory and remove items from
+ // the list as we re-parse them. Once we are done emit the
+ // signals.
+ QVector<QString> deletionCandidates = entriesWithPrefix(dirName);
+
beginResetModel();
- while (dirIt.hasNext())
- doAddFile(dirIt.next());
+ while (dirIt.hasNext()) {
+ auto fileName = dirIt.next();
+ if (!doAddFile(fileName))
+ continue;
+ deletionCandidates.removeAll(fileName);
+ }
+ QVector<AppEntry> removedApps = removeEntries(deletionCandidates);
endResetModel();
+
+ // Announce the apps we removed after the model has been updated
+ for (const auto& app : removedApps) {
+ qCDebug(apps) << "Going to remove entry for " << app.sourceFileName;
+ emit appRemoved(app);
+ }
}
-void AppListModel::doAddFile(const QString& fileName)
+bool AppListModel::doAddFile(const QString& fileName)
{
bool ok;
auto newEntry = AppParser::parseFile(fileName, &ok);
if (!ok)
- return;
+ return false;
for (int i = 0; i < m_rows.count(); ++i) {
if (m_rows[i].sourceFileName == fileName) {
m_rows[i] = newEntry;
- return;
+ return true;
}
}
m_rows.push_back(newEntry);
+ return true;
+}
+
+QVector<QString> AppListModel::entriesWithPrefix(const QString& prefix) const
+{
+ QVector<QString> entries;
+
+ for (const AppEntry& entry : m_rows)
+ if (entry.sourceFileName.startsWith(prefix))
+ entries.push_back(entry.sourceFileName);
+ return entries;
+}
+
+QVector<AppEntry> AppListModel::removeEntries(const QVector<QString>& fileNames)
+{
+ QVector<AppEntry> removedEntries(fileNames.size());
+
+ // Rare but quadratic. The actual removal.
+ for (const auto &toRemoveFile: fileNames) {
+ for (int i = 0; i < m_rows.size(); ++i) {
+ if (m_rows[i].sourceFileName != toRemoveFile)
+ continue;
+ removedEntries.append(m_rows[i]);
+ m_rows.removeAt(i);
+ break;
+ }
+ }
+
+ return removedEntries;
}
diff --git a/wayland/democompositor/apps/applistmodel.h b/wayland/democompositor/apps/applistmodel.h
index 9147f54..4662e8f 100644
--- a/wayland/democompositor/apps/applistmodel.h
+++ b/wayland/democompositor/apps/applistmodel.h
@@ -76,6 +76,9 @@ public:
QVariant data(const QModelIndex& index, int role) const Q_DECL_OVERRIDE;
QHash<int, QByteArray> roleNames() const Q_DECL_OVERRIDE;
+Q_SIGNALS:
+ void appRemoved(const AppEntry& appEntry);
+
public Q_SLOTS:
bool addAndWatchDir(const QString& dirName);
@@ -83,7 +86,9 @@ public Q_SLOTS:
void addDir(const QString& dirName);
private:
- void doAddFile(const QString& fileName);
+ QVector<QString> entriesWithPrefix(const QString& prefix) const;
+ QVector<AppEntry> removeEntries(const QVector<QString>& sourceFileNames);
+ bool doAddFile(const QString& fileName);
QVector<AppEntry> m_rows;
static QHash<int, QByteArray> m_roles;
diff --git a/wayland/democompositor/qml/Screen.qml b/wayland/democompositor/qml/Screen.qml
index ffb8490..7ab7481 100644
--- a/wayland/democompositor/qml/Screen.qml
+++ b/wayland/democompositor/qml/Screen.qml
@@ -89,6 +89,10 @@ WaylandOutput {
AppListModel {
id: apps
+ onAppRemoved: {
+ console.log("Application was removed: " + appEntry.appName);
+ launcher.stop(appEntry);
+ }
}
Component.onCompleted: {