From d1f6c608868dc6ace83f488552714e11f4cd0c2c Mon Sep 17 00:00:00 2001
From: Capsia <cmsuser3754@zoho.eu>
Date: Sat, 16 Aug 2025 14:28:04 +0200
Subject: [PATCH 1/7] Refreshes app icons on icon cache changes

Adds a file system watcher to monitor changes on icon cache files.
When an icon cache file is modified, a signal is emitted to refresh the
application icons, ensuring that the launcher displays the most up-to-date
icons.

Signed-off-by: Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
---
 plugins/Lomiri/Launcher/CMakeLists.txt       |  1 +
 plugins/Lomiri/Launcher/appdrawermodel.cpp   |  5 ++
 plugins/Lomiri/Launcher/appdrawermodel.h     |  2 +
 plugins/Lomiri/Launcher/iconcachewatcher.cpp | 65 ++++++++++++++++++++
 plugins/Lomiri/Launcher/iconcachewatcher.h   | 34 ++++++++++
 5 files changed, 107 insertions(+)
 create mode 100644 plugins/Lomiri/Launcher/iconcachewatcher.cpp
 create mode 100644 plugins/Lomiri/Launcher/iconcachewatcher.h

diff --git a/plugins/Lomiri/Launcher/CMakeLists.txt b/plugins/Lomiri/Launcher/CMakeLists.txt
index 50b67f0ab..2170e511e 100644
--- a/plugins/Lomiri/Launcher/CMakeLists.txt
+++ b/plugins/Lomiri/Launcher/CMakeLists.txt
@@ -27,6 +27,7 @@ set(QMLLAUNCHERPLUGIN_SRC
     appdrawermodel.cpp
     ualwrapper.cpp
     xdgwatcher.cpp
+    iconcachewatcher.cpp
     ${CMAKE_SOURCE_DIR}/plugins/AccountsService/AccountsServiceDBusAdaptor.cpp
     ${APPLICATION_API_INCLUDEDIR}/lomiri/shell/application/ApplicationManagerInterface.h
     ${APPLICATION_API_INCLUDEDIR}/lomiri/shell/application/ApplicationInfoInterface.h
diff --git a/plugins/Lomiri/Launcher/appdrawermodel.cpp b/plugins/Lomiri/Launcher/appdrawermodel.cpp
index 870a8b9a9..e13a1fee9 100644
--- a/plugins/Lomiri/Launcher/appdrawermodel.cpp
+++ b/plugins/Lomiri/Launcher/appdrawermodel.cpp
@@ -18,6 +18,7 @@
 #include "appdrawermodel.h"
 #include "ualwrapper.h"
 #include "xdgwatcher.h"
+#include "iconcachewatcher.h"
 
 #include <QDebug>
 #include <QDateTime>
@@ -35,6 +36,7 @@ AppDrawerModel::AppDrawerModel(QObject *parent):
     AppDrawerModelInterface(parent),
     m_ual(new UalWrapper(this)),
     m_xdgWatcher(new XdgWatcher(this)),
+    m_iconCacheWatcher(new IconCacheWatcher(this)),
     m_refreshing(false)
 {
     connect(&m_refreshFutureWatcher, &QFutureWatcher<ItemList>::finished,
@@ -45,6 +47,9 @@ AppDrawerModel::AppDrawerModel(QObject *parent):
     connect(m_xdgWatcher, &XdgWatcher::appRemoved, this, &AppDrawerModel::appRemoved, Qt::QueuedConnection);
     connect(m_xdgWatcher, &XdgWatcher::appInfoChanged, this, &AppDrawerModel::appInfoChanged, Qt::QueuedConnection);
 
+    // Refresh app icons when icon cache changes
+    connect(m_iconCacheWatcher, &IconCacheWatcher::iconCacheChanged, this, &AppDrawerModel::refresh, Qt::QueuedConnection);
+
     refresh();
 }
 
diff --git a/plugins/Lomiri/Launcher/appdrawermodel.h b/plugins/Lomiri/Launcher/appdrawermodel.h
index 2b1030171..43e650770 100644
--- a/plugins/Lomiri/Launcher/appdrawermodel.h
+++ b/plugins/Lomiri/Launcher/appdrawermodel.h
@@ -24,6 +24,7 @@
 class UalWrapper;
 class XdgWatcher;
 
+class IconCacheWatcher;
 class AppDrawerModel: public AppDrawerModelInterface
 {
     Q_OBJECT
@@ -59,6 +60,7 @@ private:
     ItemList m_list;
     UalWrapper *m_ual;
     XdgWatcher *m_xdgWatcher;
+    IconCacheWatcher *m_iconCacheWatcher;
     QFutureWatcher<ItemList> m_refreshFutureWatcher;
     bool m_refreshing;
 };
diff --git a/plugins/Lomiri/Launcher/iconcachewatcher.cpp b/plugins/Lomiri/Launcher/iconcachewatcher.cpp
new file mode 100644
index 000000000..187971a88
--- /dev/null
+++ b/plugins/Lomiri/Launcher/iconcachewatcher.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2025 UBports Foundation
+ * Author(s): Riccardo Riccio <riccardo.riccio@ubports.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "iconcachewatcher.h"
+
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+
+IconCacheWatcher::IconCacheWatcher(QObject *parent)
+    : QObject(parent),
+      m_watcher(new QFileSystemWatcher(this))
+{
+    // Standard icon directories
+    QStringList iconDirs = {
+        "/usr/share/icons",
+        "/usr/local/share/icons",
+        QDir::homePath() + "/.local/share/icons"
+    };
+
+    QStringList cacheFiles;
+    for (const QString &dir : iconDirs) {
+        QDir d(dir);
+        if (!d.exists()) continue;
+        // Look for icon-theme.cache in all subdirs
+        QFileInfoList subdirs = d.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
+        for (const QFileInfo &subdir : subdirs) {
+            QString cachePath = subdir.absoluteFilePath() + "/icon-theme.cache";
+            if (QFile::exists(cachePath)) {
+                cacheFiles << cachePath;
+            }
+        }
+    }
+
+    if (cacheFiles.isEmpty()) {
+        qWarning() << "No icon-theme.cache files found in standard icon directories.";
+    } else {
+        m_watcher->addPaths(cacheFiles);
+        connect(m_watcher, &QFileSystemWatcher::fileChanged,
+                this, &IconCacheWatcher::onCacheFileChanged);
+    }
+}
+
+void IconCacheWatcher::onCacheFileChanged(const QString &path)
+{
+    Q_EMIT iconCacheChanged();
+    // Re-add the path in case the file was recreated
+    if (QFile::exists(path)) {
+        m_watcher->addPath(path);
+    }
+}
diff --git a/plugins/Lomiri/Launcher/iconcachewatcher.h b/plugins/Lomiri/Launcher/iconcachewatcher.h
new file mode 100644
index 000000000..4fd60aead
--- /dev/null
+++ b/plugins/Lomiri/Launcher/iconcachewatcher.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 UBports Foundation
+ * Author(s): Riccardo Riccio <riccardo.riccio@ubports.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <QFileSystemWatcher>
+
+class IconCacheWatcher : public QObject
+{
+    Q_OBJECT
+public:
+    explicit IconCacheWatcher(QObject *parent = nullptr);
+
+Q_SIGNALS:
+    void iconCacheChanged();
+
+private Q_SLOTS:
+    void onCacheFileChanged(const QString &path);
+
+private:
+    QFileSystemWatcher *m_watcher;
+};
-- 
2.47.2

