Taken from nixpkgs, see
grantleetheme: merge themes across multiple prefixes
<https://github.com/NixOS/nixpkgs/commits/master/pkgs/applications/kde/grantleetheme/grantlee-merge-theme-dirs.patch>


diff --git a/src/grantleetheme.cpp b/src/grantleetheme.cpp
index 27d5bc8..8d43140 100644
--- a/src/grantleetheme.cpp
+++ b/src/grantleetheme.cpp
@@ -46,7 +46,7 @@ ThemePrivate::ThemePrivate(const ThemePrivate &other)
     , description(other.description)
     , name(other.name)
     , dirName(other.dirName)
-    , absolutePath(other.absolutePath)
+    , absolutePaths(other.absolutePaths)
     , author(other.author)
     , email(other.email)
     , loader(other.loader)
@@ -64,12 +64,15 @@ void ThemePrivate::setupEngine()
 
 void ThemePrivate::setupLoader()
 {
-    // Get the parent dir with themes, we set the theme directory separately
-    QDir dir(absolutePath);
-    dir.cdUp();
+    QStringList templateDirs;
+    for (const QString& path : absolutePaths) {
+        QDir dir(path);
+        dir.cdUp();
+        templateDirs << dir.absolutePath();
+    }
 
     loader = QSharedPointer<GrantleeTheme::QtResourceTemplateLoader>::create();
-    loader->setTemplateDirs({ dir.absolutePath() });
+    loader->setTemplateDirs(templateDirs);
     loader->setTheme(dirName);
 
     if (!sEngine) {
@@ -121,7 +124,7 @@ Theme::Theme(const QString &themePath, const QString &dirName, const QString &de
     KConfigGroup group(&config, QStringLiteral("Desktop Entry"));
     if (group.isValid()) {
         d->dirName = dirName;
-        d->absolutePath = themePath;
+        d->absolutePaths = QStringList(themePath);
         d->name = group.readEntry("Name", QString());
         d->description = group.readEntry("Description", QString());
         d->themeFileName = group.readEntry("FileName", QString());
@@ -140,7 +143,7 @@ Theme::~Theme()
 
 bool Theme::operator==(const Theme &other) const
 {
-    return isValid() && other.isValid() && d->absolutePath == other.absolutePath();
+    return isValid() && other.isValid() && d->absolutePaths == other.absolutePaths();
 }
 
 Theme &Theme::operator=(const Theme &other)
@@ -184,7 +187,15 @@ QString Theme::dirName() const
 
 QString Theme::absolutePath() const
 {
-    return d->absolutePath;
+    if (! d->absolutePaths.isEmpty()) {
+      return d->absolutePaths.first();
+    };
+    return QString();
+}
+
+QStringList Theme::absolutePaths() const
+{
+    return d->absolutePaths;
 }
 
 QString Theme::author() const
@@ -223,6 +231,13 @@ QString Theme::render(const QString &templateName, const QVariantHash &data, con
     return result;
 }
 
+void Theme::addThemeDir(const QString& path)
+{
+    QDir dir(path);
+    dir.cdUp();
+    d->absolutePaths << dir.absolutePath();
+}
+
 void Theme::addPluginPath(const QString &path)
 {
     if (!ThemePrivate::sEngine) {
diff --git a/src/grantleetheme.h b/src/grantleetheme.h
index a25c27b..be38299 100644
--- a/src/grantleetheme.h
+++ b/src/grantleetheme.h
@@ -48,11 +48,14 @@ public:
     Q_REQUIRED_RESULT QStringList displayExtraVariables() const;
     Q_REQUIRED_RESULT QString dirName() const;
     Q_REQUIRED_RESULT QString absolutePath() const;
+    Q_REQUIRED_RESULT QStringList absolutePaths() const;
     Q_REQUIRED_RESULT QString author() const;
     Q_REQUIRED_RESULT QString authorEmail() const;
 
     Q_REQUIRED_RESULT QString render(const QString &templateName, const QVariantHash &data, const QByteArray &applicationDomain = QByteArray());
 
+    void addThemeDir(const QString&);
+
     static void addPluginPath(const QString &path);
 
 private:
diff --git a/src/grantleetheme_p.h b/src/grantleetheme_p.h
index eb73dcb..00510e9 100644
--- a/src/grantleetheme_p.h
+++ b/src/grantleetheme_p.h
@@ -43,7 +43,7 @@ public:
     QString description;
     QString name;
     QString dirName;
-    QString absolutePath;
+    QStringList absolutePaths;
     QString author;
     QString email;
 
diff --git a/src/grantleethememanager.cpp b/src/grantleethememanager.cpp
index 606d717..dc99041 100644
--- a/src/grantleethememanager.cpp
+++ b/src/grantleethememanager.cpp
@@ -125,25 +125,18 @@ public:
 
         for (const QString &directory : qAsConst(themesDirectories)) {
             QDirIterator dirIt(directory, QStringList(), QDir::AllDirs | QDir::NoDotAndDotDot);
-            QStringList alreadyLoadedThemeName;
             while (dirIt.hasNext()) {
                 dirIt.next();
                 const QString dirName = dirIt.fileName();
                 GrantleeTheme::Theme theme = q->loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName);
                 if (theme.isValid()) {
                     QString themeName = theme.name();
-                    if (alreadyLoadedThemeName.contains(themeName)) {
-                        int i = 2;
-                        const QString originalName(theme.name());
-                        while (alreadyLoadedThemeName.contains(themeName)) {
-                            themeName = originalName + QStringLiteral(" (%1)").arg(i);
-                            ++i;
-                        }
-                        theme.d->name = themeName;
+                    QMap<QString, GrantleeTheme::Theme>::iterator i = themes.find(dirName);
+                    if (i != themes.end()) {
+                        i.value().addThemeDir(dirIt.filePath());
+                    } else {
+                        themes.insert(dirName, theme);
                     }
-                    alreadyLoadedThemeName << themeName;
-                    themes.insert(dirName, theme);
-                    //qDebug()<<" theme.name()"<<theme.name();
                 }
             }
             watch->addDir(directory);
@@ -366,7 +359,7 @@ QString ThemeManager::pathFromThemes(const QString &themesRelativePath, const QS
                 GrantleeTheme::Theme theme = loadTheme(dirIt.filePath(), dirName, defaultDesktopFileName);
                 if (theme.isValid()) {
                     if (dirName == themeName) {
-                        return theme.absolutePath();
+                        return theme.absolutePaths().first();
                     }
                 }
             }