[plasma/discover] libdiscover: pk+flatpak: Simplify fetching icons by reusing code
Aleix Pol Gonzalez <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 95e6cad9e87e4be3227e31a95c8cb1dc6dcdf5a1 by Aleix Pol Gonzalez, on behalf of Aleix Pol.
Committed on 24/07/2026 at 09:42.
Pushed by apol into branch 'master'.
pk+flatpak: Simplify fetching icons by reusing code
M +39 -0 libdiscover/appstream/AppStreamUtils.cpp
M +4 -0 libdiscover/appstream/AppStreamUtils.h
M +12 -44 libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
M +0 -1 libdiscover/backends/FlatpakBackend/FlatpakResource.h
M +4 -33 libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp
https://invent.kde.org/plasma/discover/-/commit/95e6cad9e87e4be3227e31a95c8cb1dc6dcdf5a1
diff --git a/libdiscover/appstream/AppStreamUtils.cpp b/libdiscover/appstream/AppStreamUtils.cpp
index 3fe58a0aa..23f4bf290 100644
--- a/libdiscover/appstream/AppStreamUtils.cpp
+++ b/libdiscover/appstream/AppStreamUtils.cpp
@@ -9,6 +9,7 @@
#include "utils.h"
#include <AppStreamQt/category.h>
#include <AppStreamQt/component.h>
+#include <AppStreamQt/icon.h>
#include <AppStreamQt/pool.h>
#include <AppStreamQt/release.h>
#include <AppStreamQt/screenshot.h>
@@ -19,6 +20,8 @@
#include <KLocalizedString>
#include <QCoroTimer>
#include <QDebug>
+#include <QDir>
+#include <QDirIterator>
#include <QJsonArray>
#include <QJsonObject>
#include <QMetaEnum>
@@ -235,3 +238,39 @@ DISCOVERCOMMON_EXPORT bool AppStreamUtils::kIconLoaderHasIcon(const QString &nam
}();
return icons.contains(name);
}
+
+QIcon AppStreamUtils::iconForComponent(const AppStream::Component &component, const QString &iconPath)
+{
+ QIcon ret;
+ for (const AppStream::Icon &icon : component.icons()) {
+ switch (icon.kind()) {
+ case AppStream::Icon::KindLocal:
+ case AppStream::Icon::KindCached: {
+ const QString path = icon.url().toLocalFile();
+ if (QDir::isRelativePath(path) && !iconPath.isEmpty()) {
+ QDirIterator it(iconPath, QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ const auto currentPath = it.next();
+ if (it.fileName() == path) {
+ ret.addFile(currentPath, icon.size());
+ }
+ }
+ } else {
+ ret.addFile(path, icon.size());
+ }
+ break;
+ }
+ case AppStream::Icon::KindRemote:
+ break;
+ case AppStream::Icon::KindStock:
+ if (kIconLoaderHasIcon(icon.name())) {
+ ret = QIcon::fromTheme(icon.name());
+ }
+ break;
+ case AppStream::Icon::KindUnknown:
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/libdiscover/appstream/AppStreamUtils.h b/libdiscover/appstream/AppStreamUtils.h
index f3f66f944..b8cee929c 100644
--- a/libdiscover/appstream/AppStreamUtils.h
+++ b/libdiscover/appstream/AppStreamUtils.h
@@ -7,9 +7,11 @@
#pragma once
#include <AppStreamQt/component.h>
+#include <AppStreamQt/icon.h>
#include <AppStreamQt/image.h>
#include <AppStreamQt/pool.h>
#include <QColor>
+#include <QIcon>
#include <QList>
#include <QUrl>
#include <resources/AbstractResource.h>
@@ -40,4 +42,6 @@ DISCOVERCOMMON_EXPORT QFuture<AppStream::ComponentBox>
componentsByCategoriesTask(AppStream::ConcurrentPool *pool, const std::shared_ptr<Category> &cat, AppStream::Bundle::Kind kind);
DISCOVERCOMMON_EXPORT bool kIconLoaderHasIcon(const QString &name);
+
+DISCOVERCOMMON_EXPORT QIcon iconForComponent(const AppStream::Component &component, const QString &iconPath = {});
}
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp b/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
index 2e6660da9..3bd3beafa 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
+++ b/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp
@@ -34,7 +34,6 @@
#include <QCoroCore>
#include <QDesktopServices>
#include <QDir>
-#include <QDirIterator>
#include <QEvent>
#include <QFileInfo>
#include <QFutureWatcher>
@@ -189,13 +188,12 @@ quint64 FlatpakResource::downloadSize() const
void FlatpakResource::resolveIcon()
{
- m_icon = QIcon();
const auto icons = m_appdata.icons();
- m_stockIcon = std::ranges::any_of(icons, [](const AppStream::Icon &icon) {
+ const bool hasStockIcon = std::ranges::any_of(icons, [](const AppStream::Icon &icon) {
return icon.kind() == AppStream::Icon::KindStock && AppStreamUtils::kIconLoaderHasIcon(icon.name());
});
- if (!m_remoteIconFetchInitiated && !m_stockIcon && !icons.isEmpty() && !std::ranges::any_of(icons, [](const AppStream::Icon &icon) {
+ if (!m_remoteIconFetchInitiated && !hasStockIcon && !icons.isEmpty() && !std::ranges::any_of(icons, [](const AppStream::Icon &icon) {
return icon.kind() == AppStream::Icon::KindLocal || icon.kind() == AppStream::Icon::KindCached;
})) {
m_remoteIconFetchInitiated = true;
@@ -230,50 +228,20 @@ void FlatpakResource::resolveIcon()
if (!m_bundledIcon.isNull()) {
m_icon = QIcon(m_bundledIcon);
- } else if (icons.isEmpty()) {
- m_icon = QIcon::fromTheme(QStringLiteral("package-x-generic"));
} else {
- for (const AppStream::Icon &icon : icons) {
- switch (icon.kind()) {
- case AppStream::Icon::KindLocal:
- case AppStream::Icon::KindCached: {
- const QString path = icon.url().toLocalFile();
- if (QDir::isRelativePath(path)) {
- const QString appstreamLocation =
- installationPath() + "/appstream/"_L1 + origin() + '/'_L1 + QString::fromUtf8(flatpak_get_default_arch()) + "/active/icons/"_L1;
- QDirIterator dit(appstreamLocation, QDirIterator::Subdirectories);
- while (dit.hasNext()) {
- const auto currentPath = dit.next();
- if (dit.fileName() == path) {
- m_icon->addFile(currentPath, icon.size());
- }
- }
- } else {
- m_icon->addFile(path, icon.size());
- }
- break;
- }
- case AppStream::Icon::KindStock: {
- if (m_stockIcon) {
- m_icon = QIcon::fromTheme(icon.name());
- }
- break;
- }
- case AppStream::Icon::KindRemote: {
- const QString fileName = iconCachePath(icon);
- if (QFileInfo::exists(fileName)) {
- m_icon->addFile(fileName, icon.size());
- }
- break;
+ m_icon = AppStreamUtils::iconForComponent(m_appdata, m_iconPath);
+ for (const auto &icon : icons) {
+ if (icon.kind() != AppStream::Icon::KindRemote) {
+ continue;
}
- case AppStream::Icon::KindUnknown:
- break;
+ const QString fileName = iconCachePath(icon);
+ if (QFileInfo::exists(fileName)) {
+ m_icon->addFile(fileName, icon.size());
}
}
- }
-
- if (m_icon->isNull()) {
- m_icon = QIcon::fromTheme(QStringLiteral("package-x-generic"));
+ if (m_icon->isNull()) {
+ m_icon = QIcon::fromTheme(QStringLiteral("package-x-generic"));
+ }
}
Q_EMIT iconChanged();
diff --git a/libdiscover/backends/FlatpakBackend/FlatpakResource.h b/libdiscover/backends/FlatpakBackend/FlatpakResource.h
index 22436362f..33123bef0 100644
--- a/libdiscover/backends/FlatpakBackend/FlatpakResource.h
+++ b/libdiscover/backends/FlatpakBackend/FlatpakResource.h
@@ -263,7 +263,6 @@ private:
static const QStringList s_topObjects;
static const QStringList s_bottomObjects;
QVector<QByteArray> m_toUpdate;
- bool m_stockIcon = false;
bool m_remoteIconFetchInitiated = false;
std::optional<QIcon> m_icon;
QString m_newPermissions;
diff --git a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp
index a51e74c6d..5e147f8db 100644
--- a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp
+++ b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp
@@ -8,7 +8,6 @@
#include "utils.h"
#include <AppStreamQt/component.h>
#include <AppStreamQt/developer.h>
-#include <AppStreamQt/icon.h>
#include <AppStreamQt/image.h>
#include <AppStreamQt/provided.h>
#include <AppStreamQt/release.h>
@@ -20,10 +19,7 @@
#include <LazyIconResolver.h>
#include <PackageKit/Daemon>
#include <QDebug>
-#include <QFile>
#include <QIcon>
-#include <QProcess>
-#include <QStandardPaths>
#include <QUrlQuery>
#include <appstream/AppStreamUtils.h>
@@ -66,34 +62,6 @@ QString AppPackageKitResource::longDescription()
return PackageKitResource::longDescription();
}
-static QIcon componentIcon(const AppStream::Component &comp)
-{
- QIcon ret;
- const auto icons = comp.icons();
- for (const AppStream::Icon &icon : icons) {
- switch (icon.kind()) {
- case AppStream::Icon::KindLocal:
- ret.addFile(icon.url().toLocalFile(), icon.size());
- break;
- case AppStream::Icon::KindCached:
- ret.addFile(icon.url().toLocalFile(), icon.size());
- break;
- case AppStream::Icon::KindStock: {
- if (AppStreamUtils::kIconLoaderHasIcon(icon.name())) {
- return QIcon::fromTheme(icon.name());
- }
- break;
- }
- default:
- break;
- }
- }
- if (ret.isNull()) {
- ret = QIcon::fromTheme(QStringLiteral("package-x-generic"));
- }
- return ret;
-}
-
QVariant AppPackageKitResource::icon() const
{
if (m_icon.has_value()) {
@@ -324,7 +292,10 @@ bool AppPackageKitResource::hasResolvedIcon() const
void AppPackageKitResource::resolveIcon()
{
- m_icon = componentIcon(m_appdata);
+ m_icon = AppStreamUtils::iconForComponent(m_appdata);
+ if (m_icon->isNull()) {
+ m_icon = QIcon::fromTheme(QStringLiteral("package-x-generic"));
+ }
Q_EMIT iconChanged();
}