From 3d1febd3813b4fe0fdf8f958e6ff4a6f433dfd21 Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Sat, 27 Sep 2025 14:17:00 +0200 Subject: [PATCH] [activitymananger] Fix activity background image The code looks into the appletsrc file to load the wallpaper for a given activity. However that only worked when a custom image was specified by full path. When any of the built-in wallpapers is used the Image key instead points to the wallpaper package folder, not any specific image. Also when the default wallpaper is used the key is empty. Fix all of these cases by selecting one image when given a folder, and fall back to the default wallpaper (called Next) when no config is present. Also when using a color background use the actual default color instead of black BUG: 378693 --- .../activitymanager/sortedactivitiesmodel.cpp | 81 +++++++++++++++++-- 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/imports/activitymanager/sortedactivitiesmodel.cpp b/imports/activitymanager/sortedactivitiesmodel.cpp index bcefab9d6c..f200d0655d 100644 --- a/imports/activitymanager/sortedactivitiesmodel.cpp +++ b/imports/activitymanager/sortedactivitiesmodel.cpp @@ -13,8 +13,11 @@ // Qt #include +#include +#include #include #include +#include // KDE #include @@ -24,6 +27,8 @@ static const char *s_plasma_config = "plasma-org.kde.plasma.desktop-appletsrc"; +using namespace Qt::Literals; + namespace { class BackgroundCache : public QObject @@ -74,20 +79,80 @@ public: } } + QSize parseSize(QStringView str) const + { + const int index = str.indexOf(QLatin1Char('x')); + + if (index != -1) { + return QSize(str.left(index).toInt(), str.mid(index + 1).toInt()); + } + + return QSize(); + } + + double distance(const QSize &size, const QSize &desired) const + { + const double desiredAspectRatio = (desired.height() > 0) ? desired.width() / static_cast(desired.height()) : 0; + const double candidateAspectRatio = (size.height() > 0) ? size.width() / static_cast(size.height()) : std::numeric_limits::max(); + + double delta = size.width() - desired.width(); + delta = delta >= 0.0 ? delta : -delta * 2; // Penalize for scaling up + + return std::abs(candidateAspectRatio - desiredAspectRatio) * 25000 + delta; + } + + QString findImageInWallpaperPackage(const QString &folderName) const + { + QString preferred; + const QStringList images = QDir(folderName).entryList(); + + if (images.empty()) { + return preferred; + } + + double best = std::numeric_limits::max(); + + for (const QString &entry : images) { + QSize candidate = parseSize(QFileInfo(entry).baseName()); + + if (candidate.isEmpty()) { + continue; + } + + const double dist = distance(candidate, QSize(1920, 1080)); + + if (preferred.isEmpty() || dist < best) { + preferred = entry; + best = dist; + } + } + + return folderName + u"/" + preferred; + } + QString backgroundFromConfig(const KConfigGroup &config) const { auto wallpaperPlugin = config.readEntry("wallpaperplugin"); auto wallpaperConfig = config.group(QStringLiteral("Wallpaper")).group(wallpaperPlugin).group(QStringLiteral("General")); - if (wallpaperConfig.hasKey("Image")) { - // Trying for the wallpaper - auto wallpaper = wallpaperConfig.readEntry("Image", QString()); - if (!wallpaper.isEmpty()) { - return wallpaper; + if (wallpaperPlugin == u"org.kde.image") { + // we can have three cases: + // - Image is a URL to a specific image -> use that + // - Image is a URL to a wallpaper package folder -> pick one image from that folder + // - Image is empty -> use default wallpaper + + const QUrl defaultWallpaper = + QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, u"wallpapers/Next"_s, QStandardPaths::LocateDirectory)); + + const QUrl wallpaper = wallpaperConfig.readEntry("Image", defaultWallpaper); + + if (QFileInfo(wallpaper.toLocalFile()).isDir()) { + return findImageInWallpaperPackage(wallpaper.toLocalFile() + u"/contents/images"); + } else { + return wallpaper.toString(); } - } - if (wallpaperConfig.hasKey("Color")) { - auto backgroundColor = wallpaperConfig.readEntry("Color", QColor(0, 0, 0)); + } else if (wallpaperPlugin == u"org.kde.color") { + auto backgroundColor = wallpaperConfig.readEntry("Color", QColor(29, 153, 243)); return backgroundColor.name(); }