Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libqt5xdg for openSUSE:Factory 
checked in at 2021-04-17 00:01:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libqt5xdg (Old)
 and      /work/SRC/openSUSE:Factory/.libqt5xdg.new.12324 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libqt5xdg"

Sat Apr 17 00:01:47 2021 rev:14 rq:885930 version:3.7.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/libqt5xdg/libqt5xdg.changes      2021-04-06 
17:31:57.935271975 +0200
+++ /work/SRC/openSUSE:Factory/.libqt5xdg.new.12324/libqt5xdg.changes   
2021-04-17 00:01:57.569612457 +0200
@@ -1,0 +2,20 @@
+Fri Apr 16 11:23:47 UTC 2021 - Michael Vetter <[email protected]>
+
+- Update 3.7.1:
+  * Fixed compilation against Qt < 5.14.
+  * Added a nullity check for paint device.
+
+-------------------------------------------------------------------
+Fri Apr 16 06:31:20 UTC 2021 - Michael Vetter <[email protected]>
+
+- Update to 3.7.0:
+  * QSvgRenderer is used with a cache for SVG icons, so that LXQt's
+    icon handling could not be broken by intruding icon engines
+       that register themselves for "svg" (like kiconthemes 5.80).
+  * Allow runtime overriding of detachment of processes by
+    setting QTXDG_START_DETACH_TRULY.
+  * XTerm is added as a runtime dependency.
+  * Code cleanup.
+- Remove libqt5xdg-svg-render.patch: upstreamed
+
+-------------------------------------------------------------------

Old:
----
  libqt5xdg-svg-render.patch
  libqtxdg-3.6.0.tar.xz
  libqtxdg-3.6.0.tar.xz.asc

New:
----
  libqtxdg-3.7.1.tar.xz
  libqtxdg-3.7.1.tar.xz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libqt5xdg.spec ++++++
--- /var/tmp/diff_new_pack.EynbTB/_old  2021-04-17 00:01:58.081613264 +0200
+++ /var/tmp/diff_new_pack.EynbTB/_new  2021-04-17 00:01:58.081613264 +0200
@@ -18,7 +18,7 @@
 
 %define _name libqtxdg
 Name:           libqt5xdg
-Version:        3.6.0
+Version:        3.7.1
 Release:        0
 Summary:        Qt implementation of xdg specs for lxqt
 License:        GPL-3.0-only
@@ -27,14 +27,13 @@
 Source:         
https://github.com/lxqt/libqtxdg/releases/download/%{version}/%{_name}-%{version}.tar.xz
 Source1:        
https://github.com/lxqt/libqtxdg/releases/download/%{version}/%{_name}-%{version}.tar.xz.asc
 Source2:        %{name}.keyring
-Patch0:         libqt5xdg-svg-render.patch
 BuildRequires:  cmake >= 3.1.0
 BuildRequires:  fdupes
 BuildRequires:  gcc-c++
 BuildRequires:  libQt5Gui-private-headers-devel
-BuildRequires:  lxqt-build-tools-devel >= 0.8.0
+BuildRequires:  lxqt-build-tools-devel >= 0.9.0
 BuildRequires:  pkgconfig
-BuildRequires:  pkgconfig(Qt5Core) >= 5.10
+BuildRequires:  pkgconfig(Qt5Core) >= 5.12
 BuildRequires:  pkgconfig(Qt5DBus)
 BuildRequires:  pkgconfig(Qt5Svg)
 BuildRequires:  pkgconfig(Qt5Test)
@@ -89,7 +88,6 @@
 
 %prep
 %setup -q -n %{_name}-%{version}
-%patch0 -p1
 
 %build
 %cmake


++++++ libqtxdg-3.6.0.tar.xz -> libqtxdg-3.7.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/CHANGELOG new/libqtxdg-3.7.1/CHANGELOG
--- old/libqtxdg-3.6.0/CHANGELOG        2020-10-30 14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/CHANGELOG        2021-04-16 11:29:21.000000000 +0200
@@ -1,3 +1,20 @@
+libqtxdg-3.7.1 / 2021-04-16
+===========================
+ * Fixed compilation against Qt < 5.14.
+ * Added a nullity check for paint device.
+
+libqtxdg-3.7.0 / 2021-04-15
+===========================
+  * Removed deprecated XdgDesktopFileCache.
+  * Handled Qt 5.15 deprecations.
+  * Use "= default" for trivial constructors/destructors.
+  * Improved readability in container emptiness check.
+  * Ported QStringRef to QStringView.
+  * Moved to Qt5 signal/slot syntax.
+  * Added XTerm as a runtime dependency.
+  * Allow non-detached starting in xdgdesktopfile.
+  * Use QSvgRenderer for SVG icons.
+
 libqtxdg-3.6.0 / 2020-11-01
 ===========================
   * ???Dropped deprecated QLinkedList.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/CMakeLists.txt 
new/libqtxdg-3.7.1/CMakeLists.txt
--- old/libqtxdg-3.6.0/CMakeLists.txt   2020-10-30 14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/CMakeLists.txt   2021-04-16 11:29:21.000000000 +0200
@@ -13,17 +13,18 @@
 set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" 
"${CMAKE_CURRENT_SOURCE_DIR}/cmake")
 
 set(QTXDG_MAJOR_VERSION 3)
-set(QTXDG_MINOR_VERSION 6)
-set(QTXDG_PATCH_VERSION 0)
+set(QTXDG_MINOR_VERSION 7)
+set(QTXDG_PATCH_VERSION 1)
 set(QTXDG_VERSION_STRING 
${QTXDG_MAJOR_VERSION}.${QTXDG_MINOR_VERSION}.${QTXDG_PATCH_VERSION})
 
-set(LXQTBT_MINIMUM_VERSION "0.8.0")
+set(LXQTBT_MINIMUM_VERSION "0.9.0")
 set(QT_MINIMUM_VERSION "5.12.0")
 set(GLIB_MINIMUM_VERSION "2.41.0") # Mime Apps new implementation
 
 find_package(lxqt-build-tools ${LXQTBT_MINIMUM_VERSION} REQUIRED)
 find_package(Qt5 ${QT_MINIMUM_VERSION} CONFIG REQUIRED Widgets Svg Xml DBus)
 find_package(GLIB ${GLIB_MINIMUM_VERSION} REQUIRED COMPONENTS gobject gio 
gio-unix)
+find_package(XTerm)
 
 include(GNUInstallDirs)             # Standard directories for installation
 include(CMakePackageConfigHelpers)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgaction.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgaction.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgaction.cpp  2020-10-30 14:18:22.000000000 
+0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgaction.cpp  2021-04-16 11:29:21.000000000 
+0200
@@ -67,9 +67,7 @@
 }
 
 
-XdgAction::~XdgAction()
-{
-}
+XdgAction::~XdgAction() = default;
 
 
 XdgAction& XdgAction::operator=(const XdgAction& other)
@@ -94,7 +92,7 @@
         setText(mDesktopFile.name().replace(QLatin1Char('&'), 
QLatin1String("&&")));
         setToolTip(mDesktopFile.comment());
 
-        connect(this, SIGNAL(triggered()), this, SLOT(runConmmand()));
+        connect(this, &XdgAction::triggered, this, &XdgAction::runConmmand);
         QMetaObject::invokeMethod(this, "updateIcon", Qt::QueuedConnection);
     }
     else
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgdesktopfile.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgdesktopfile.cpp     2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.cpp     2021-04-16 
11:29:21.000000000 +0200
@@ -57,6 +57,7 @@
 #include <QTextStream>
 #include <QUrl>
 #include <QtAlgorithms>
+#include <QCoreApplication>
 
 
 /**
@@ -85,8 +86,6 @@
 static const QLatin1String urlKey("URL");
 static const QLatin1String iconKey("Icon");
 
-static const QLatin1String initialPreferenceKey("InitialPreference");
-
 // Helper functions prototypes
 bool checkTryExec(const QString& progName);
 QString &doEscape(QString& str, const QHash<QChar,QChar> &repl);
@@ -106,24 +105,33 @@
 
 namespace
 {
-    //! Simple helper for getting timeout for starting of DBus activatable 
applications
-    class DBusActivateTimeout
+    //! Simple helper for getting values based on env variables
+    template <typename Value_t, char const * EnvVariable, Value_t DefaultValue>
+        class EnvDrivenValue
     {
     private:
-        int mTimeoutMs;
-        DBusActivateTimeout()
+        Value_t mValue;
+        EnvDrivenValue()
         {
             bool ok;
-            mTimeoutMs = 
qEnvironmentVariableIntValue("QTXDG_DBUSACTIVATE_TIMEOUT", &ok);
+            mValue = qEnvironmentVariableIntValue(EnvVariable, &ok);
             if (!ok)
-                mTimeoutMs = 1500;
+                mValue = DefaultValue;
         }
-        static DBusActivateTimeout msInstance;
+        static EnvDrivenValue msInstance;
     public:
-        static const DBusActivateTimeout & instance() { return msInstance; }
-        operator int() const { return mTimeoutMs; }
+        static const EnvDrivenValue & instance() { return msInstance; }
+        operator Value_t() const { return mValue; }
     };
-    DBusActivateTimeout DBusActivateTimeout::msInstance;
+    template <typename Value_t, char const * EnvVariable, Value_t DefaultValue>
+        EnvDrivenValue<Value_t, EnvVariable, DefaultValue> 
EnvDrivenValue<Value_t, EnvVariable, DefaultValue>::msInstance;
+
+    //! Timeout [miliseconds] for starting of DBus activatable applications
+    constexpr char DBusActivateTimeoutEnv[] = "QTXDG_DBUSACTIVATE_TIMEOUT";
+    using DBusActivateTimeout = EnvDrivenValue<int, DBusActivateTimeoutEnv, 
1500>;
+    //! Flag [1/0] if "startDetached" processes should be truly detached 
(become child of root process)
+    constexpr char StartDetachTrulyEnv[] = "QTXDG_START_DETACH_TRULY";
+    using StartDetachTruly = EnvDrivenValue<bool, StartDetachTrulyEnv, true>;
 }
 
 QString &doEscape(QString& str, const QHash<QChar,QChar> &repl)
@@ -468,14 +476,17 @@
         args.prepend(term);
     }
 
-    bool nonDetach = false;
-    for (const QString &s : nonDetachExecs)
+    bool detach = StartDetachTruly::instance();
+    if (detach)
     {
-        for (const QString &a : qAsConst(args))
+        for (const QString &s : nonDetachExecs)
         {
-            if (a.contains(s))
+            for (const QString &a : qAsConst(args))
             {
-                nonDetach = true;
+                if (a.contains(s))
+                {
+                    detach = false;
+                }
             }
         }
     }
@@ -485,7 +496,10 @@
     if (!workingDir.isEmpty() && !QDir(workingDir).exists())
            workingDir = QString();
 
-    if (nonDetach)
+    if (detach)
+    {
+        return QProcess::startDetached(cmd, args, workingDir);
+    } else
     {
         QScopedPointer<QProcess> p(new QProcess);
         p->setStandardInputFile(QProcess::nullDevice());
@@ -499,13 +513,10 @@
             QProcess* proc = p.take(); //release the pointer(will be 
selfdestroyed upon finish)
             QObject::connect(proc, static_cast<void (QProcess::*)(int, 
QProcess::ExitStatus)>(&QProcess::finished),
                 proc, &QProcess::deleteLater);
+            QObject::connect(QCoreApplication::instance(), 
&QCoreApplication::aboutToQuit, proc, &QProcess::terminate);
         }
         return started;
     }
-    else
-    {
-        return QProcess::startDetached(cmd, args, workingDir);
-    }
 }
 
 
@@ -602,8 +613,11 @@
         if (!q->contains(used_key))
             return QStringList();
     }
-
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+    return q->value(used_key).toString().split(QLatin1Char(';'), 
Qt::SkipEmptyParts);
+#else
     return q->value(used_key).toString().split(QLatin1Char(';'), 
QString::SkipEmptyParts);
+#endif
 }
 
 
@@ -644,9 +658,7 @@
 }
 
 
-XdgDesktopFile::~XdgDesktopFile()
-{
-}
+XdgDesktopFile::~XdgDesktopFile() = default;
 
 
 XdgDesktopFile& XdgDesktopFile::operator=(const XdgDesktopFile& other)
@@ -698,11 +710,18 @@
         if (sect != section)
         {
             section = sect;
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+            stream << QLatin1Char('[') << section << QLatin1Char(']') << 
Qt::endl;
+#else
             stream << QLatin1Char('[') << section << QLatin1Char(']') << endl;
-
+#endif
         }
         QString key = path.section(QLatin1Char('/'), 1);
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+        stream << key << QLatin1Char('=') << i.value().toString() << Qt::endl;
+#else
         stream << key << QLatin1Char('=') << i.value().toString() << endl;
+#endif
         ++i;
     }
     return true;
@@ -915,7 +934,11 @@
 
 QStringList XdgDesktopFile::mimeTypes() const
 {
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+    return value(mimeTypeKey).toString().split(QLatin1Char(';'), 
Qt::SkipEmptyParts);
+#else
     return value(mimeTypeKey).toString().split(QLatin1Char(';'), 
QString::SkipEmptyParts);
+#endif
 }
 
 
@@ -1407,75 +1430,6 @@
 }
 
 
-XdgDesktopFile* XdgDesktopFileCache::getFile(const QString& fileName)
-{
-    if (fileName.isEmpty())
-        return nullptr;
-
-    if (instance().m_fileCache.contains(fileName))
-    {
-        return instance().m_fileCache.value(fileName);
-    }
-
-    QString file;
-    if (!fileName.startsWith(QDir::separator()))
-    {
-        // Relative path
-        // Search desktop file ..................
-        file = findDesktopFile(fileName);
-        if (file.isEmpty())
-            return nullptr;
-    }
-    else
-    {
-        file = fileName;
-    }
-
-    XdgDesktopFile* desktopFile;
-
-    // The file was found
-    if (!instance().m_fileCache.contains(file))
-    {
-        desktopFile = load(file);
-        if (desktopFile)
-        {
-            instance().m_fileCache.insert(file, desktopFile);
-            return desktopFile;
-        }
-        else
-        {
-            return nullptr;
-        }
-    }
-    else
-    {
-        // already in the cache
-        desktopFile = instance().m_fileCache.value(file);
-        return desktopFile;
-    }
-
-}
-
-QList<XdgDesktopFile*> XdgDesktopFileCache::getAllFiles()
-{
-    return instance().m_fileCache.values();
-}
-
-
-
-XdgDesktopFileCache & XdgDesktopFileCache::instance()
-{
-    static XdgDesktopFileCache cache;
-    if (!cache.m_IsInitialized)
-    {
-       cache.initialize();
-       cache.m_IsInitialized = true;
-    }
-
-    return cache;
-}
-
-
 /*!
  * Handles files with a syntax similar to desktopfiles as QSettings files.
  * The differences between ini-files and desktopfiles are:
@@ -1518,7 +1472,11 @@
 
         if (value.contains(QLatin1Char(';')))
         {
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+            map.insert(key, value.split(QLatin1Char(';'), Qt::SkipEmptyParts));
+#else
             map.insert(key, value.split(QLatin1Char(';'), 
QString::SkipEmptyParts));
+#endif
         }
         else
         {
@@ -1591,174 +1549,3 @@
     return true;
 }
 
-
-void XdgDesktopFileCache::initialize(const QString& dirName)
-{
-    QDir dir(dirName);
-    // Directories have the type "application/x-directory", but in the desktop 
file
-    // are shown as "inode/directory". To handle these cases, we use this hash.
-    QHash<QString, QString> specials;
-    specials.insert(QLatin1String("inode/directory"), 
QLatin1String("application/x-directory"));
-
-
-    // Working recursively ............
-    const QFileInfoList files = dir.entryInfoList(QStringList(), QDir::Files | 
QDir::Dirs | QDir::NoDotAndDotDot);
-    for (const QFileInfo &f : files)
-    {
-        if (f.isDir())
-        {
-            initialize(f.absoluteFilePath());
-            continue;
-        }
-
-
-        XdgDesktopFile* df = load(f.absoluteFilePath());
-        if (!df)
-            continue;
-
-        if (! m_fileCache.contains(f.absoluteFilePath()))
-        {
-            m_fileCache.insert(f.absoluteFilePath(), df);
-        }
-
-        const QStringList mimes = 
df->value(mimeTypeKey).toString().split(QLatin1Char(';'), 
QString::SkipEmptyParts);
-
-        for (const QString &mime : mimes)
-        {
-            int pref = df->value(initialPreferenceKey, 0).toInt();
-            // We move the desktopFile forward in the list for this mime, so 
that
-            // no desktopfile in front of it have a lower initialPreference.
-            int position = m_defaultAppsCache[mime].length();
-            while (position > 0 && m_defaultAppsCache[mime][position - 
1]->value(initialPreferenceKey, 0).toInt() < pref)
-            {
-                position--;
-            }
-            m_defaultAppsCache[mime].insert(position, df);
-        }
-    }
-
-}
-
-
-XdgDesktopFile* XdgDesktopFileCache::load(const QString& fileName)
-{
-    XdgDesktopFile* desktopFile = new XdgDesktopFile();
-
-    Q_CHECK_PTR(desktopFile);
-    if (desktopFile && desktopFile->load(fileName))
-        return desktopFile;
-
-    delete desktopFile;
-    return nullptr;
-}
-
-
-QSettings::Format XdgDesktopFileCache::desktopFileSettingsFormat()
-{
-    static QSettings::Format format = QSettings::InvalidFormat;
-
-    if (format == QSettings::InvalidFormat)
-        format = QSettings::registerFormat(QLatin1String("*.list"), 
readDesktopFile, writeDesktopFile);
-
-    return format;
-}
-
-
-XdgDesktopFileCache::XdgDesktopFileCache() :
-    m_IsInitialized(false),
-        m_defaultAppsCache(),
-        m_fileCache()
-{
-}
-
-
-XdgDesktopFileCache::~XdgDesktopFileCache()
-{
-}
-
-
-void XdgDesktopFileCache::initialize()
-{
-    QStringList dataDirs = XdgDirs::dataDirs();
-    dataDirs.prepend(XdgDirs::dataHome(false));
-
-    for (const QString &dirname : qAsConst(dataDirs))
-    {
-        initialize(dirname + QLatin1String("/applications"));
-    }
-}
-
-QList<XdgDesktopFile*> XdgDesktopFileCache::getAppsOfCategory(const QString& 
category)
-{
-    QList<XdgDesktopFile*> list;
-    const QString _category = category.toUpper();
-    const QHash<QString, XdgDesktopFile*> fileCache = instance().m_fileCache;
-    for (XdgDesktopFile *desktopFile : fileCache)
-    {
-        QStringList categories = 
desktopFile->value(categoriesKey).toString().toUpper().split(QLatin1Char(';'));
-        if (!categories.isEmpty() && (categories.contains(_category) || 
categories.contains(QLatin1String("X-") + _category)))
-            list.append(desktopFile);
-    }
-    return list;
-}
-
-QList<XdgDesktopFile*>  XdgDesktopFileCache::getApps(const QString& mimetype)
-{
-    return instance().m_defaultAppsCache.value(mimetype);
-}
-
-
-XdgDesktopFile* XdgDesktopFileCache::getDefaultApp(const QString& mimetype)
-{
-    // First, we look in following places for a default in specified order:
-    // ~/.config/mimeapps.list
-    // /etc/xdg/mimeapps.list
-    // ~/.local/share/applications/mimeapps.list
-    // /usr/local/share/applications/mimeapps.list
-    // /usr/share/applications/mimeapps.list
-    QStringList mimeDirsList;
-
-    mimeDirsList.append(XdgDirs::configHome(false));
-    mimeDirsList.append(XdgDirs::configDirs());
-    mimeDirsList.append(XdgDirs::dataHome(false) + 
QLatin1String("/applications"));
-    mimeDirsList.append(XdgDirs::dataDirs(QLatin1String("/applications")));
-
-    for (const QString &mimeDir : qAsConst(mimeDirsList))
-    {
-        QString defaultsListPath = mimeDir + QLatin1String("/mimeapps.list");
-        if (QFileInfo::exists(defaultsListPath))
-        {
-            QSettings defaults(defaultsListPath, desktopFileSettingsFormat());
-
-
-            defaults.beginGroup(QLatin1String("Default Applications"));
-            if (defaults.contains(mimetype))
-            {
-                QVariant value = defaults.value(mimetype);
-                if (value.canConvert<QStringList>()) // A single string can 
also convert to a stringlist
-                {
-                    const QStringList values = value.toStringList();
-                    for (const QString &desktopFileName : values)
-                    {
-                        XdgDesktopFile* desktopFile = 
XdgDesktopFileCache::getFile(desktopFileName);
-                        if (desktopFile)
-                        {
-                            return desktopFile;
-                        }
-                        else
-                        {
-                            qWarning() << desktopFileName << "not a valid 
desktopfile";
-                        }
-                    }
-                }
-            }
-            defaults.endGroup();
-        }
-    }
-
-    // If we havent found anything up to here, we look for a desktopfile that 
declares
-    // the ability to handle the given mimetype. See getApps.
-    QList<XdgDesktopFile*> apps = getApps(mimetype);
-    XdgDesktopFile* desktopFile = apps.isEmpty() ? 0 : apps[0];
-    return desktopFile;
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgdesktopfile.h 
new/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.h
--- old/libqtxdg-3.6.0/src/qtxdg/xdgdesktopfile.h       2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgdesktopfile.h       2021-04-16 
11:29:21.000000000 +0200
@@ -257,37 +257,4 @@
 /// Synonym for QList<XdgDesktopFile>
 typedef QList<XdgDesktopFile> XdgDesktopFileList;
 
-
-class QTXDG_API QTXDG_DEPRECATED XdgDesktopFileCache
-{
-public:
-    static XdgDesktopFile* getFile(const QString& fileName);
-    static QList<XdgDesktopFile*> getAllFiles();
-    static QList<XdgDesktopFile*> getApps(const QString & mimeType);
-    static XdgDesktopFile* getDefaultApp(const QString& mimeType);
-    static QSettings::Format desktopFileSettingsFormat();
-
-    /*! Return all desktop apps that have category for their Categories key
-     * Note that, according to xdg's spec, for non-standard categories "X-"
-     * is added to the beginning of the category's name. This method takes care
-     * of both cases.
-     * See 
http://standards.freedesktop.org/menu-spec/menu-spec-latest.html#desktop-entry-extensions
-     */
-    static QList<XdgDesktopFile*> getAppsOfCategory(const QString &category);
-
-private:
-    static XdgDesktopFileCache & instance();
-    static XdgDesktopFile* load(const QString & fileName);
-
-    XdgDesktopFileCache();
-    ~XdgDesktopFileCache();
-
-    void initialize();
-    void initialize(const QString & dirName);
-    bool m_IsInitialized;
-    QHash<QString, QList<XdgDesktopFile*> > m_defaultAppsCache;
-    QHash<QString, XdgDesktopFile*> m_fileCache;
- };
-
-
 #endif // QTXDG_XDGDESKTOPFILE_H
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgdirs.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgdirs.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgdirs.cpp    2020-10-30 14:18:22.000000000 
+0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgdirs.cpp    2021-04-16 11:29:21.000000000 
+0200
@@ -263,7 +263,11 @@
 QStringList XdgDirs::dataDirs(const QString &postfix)
 {
     QString d = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+    QStringList dirs = d.split(QLatin1Char(':'), Qt::SkipEmptyParts);
+#else
     QStringList dirs = d.split(QLatin1Char(':'), QString::SkipEmptyParts);
+#endif
 
     if (dirs.isEmpty()) {
         dirs.append(QString::fromLatin1("/usr/local/share"));
@@ -291,7 +295,11 @@
     if (env.isEmpty())
         dirs.append(QString::fromLatin1("/etc/xdg"));
     else
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+        dirs = env.split(QLatin1Char(':'), Qt::SkipEmptyParts);
+#else
         dirs = env.split(QLatin1Char(':'), QString::SkipEmptyParts);
+#endif
 
     cleanAndAddPostfix(dirs, postfix);
     return dirs;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgicon.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgicon.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgicon.cpp    2020-10-30 14:18:22.000000000 
+0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgicon.cpp    2021-04-16 11:29:21.000000000 
+0200
@@ -58,14 +58,10 @@
 }
 
 
-XdgIcon::XdgIcon()
-{
-}
+XdgIcon::XdgIcon() = default;
 
 
-XdgIcon::~XdgIcon()
-{
-}
+XdgIcon::~XdgIcon() = default;
 
 
 /************************************************
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmenu.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmenu.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmenu.cpp    2020-10-30 14:18:22.000000000 
+0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmenu.cpp    2021-04-16 11:29:21.000000000 
+0200
@@ -75,12 +75,12 @@
     mRebuildDelayTimer.setSingleShot(true);
     mRebuildDelayTimer.setInterval(REBUILD_DELAY);
 
-    connect(&mRebuildDelayTimer, SIGNAL(timeout()), this, SLOT(rebuild()));
-    connect(&mWatcher, SIGNAL(fileChanged(QString)), &mRebuildDelayTimer, 
SLOT(start()));
-    connect(&mWatcher, SIGNAL(directoryChanged(QString)), &mRebuildDelayTimer, 
SLOT(start()));
+    connect(&mRebuildDelayTimer, &QTimer::timeout, this, 
&XdgMenuPrivate::rebuild);
+    connect(&mWatcher, &QFileSystemWatcher::fileChanged, &mRebuildDelayTimer, 
QOverload<>::of(&QTimer::start));
+    connect(&mWatcher, &QFileSystemWatcher::directoryChanged, 
&mRebuildDelayTimer, QOverload<>::of(&QTimer::start));
 
 
-    connect(this, SIGNAL(changed()), q_ptr, SIGNAL(changed()));
+    connect(this, &XdgMenuPrivate::changed, q_ptr, &XdgMenu::changed);
 }
 
 
@@ -410,14 +410,18 @@
         return QDomElement();
 
 
+#if (QT_VERSION >= QT_VERSION_CHECK(5,15,0))
+    const QStringList names = path.split(QLatin1Char('/'), Qt::SkipEmptyParts);
+#else
     const QStringList names = path.split(QLatin1Char('/'), 
QString::SkipEmptyParts);
+#endif
     QDomElement el = baseElement;
-    for (const QString &name : names)
+    for (const QString &n : names)
     {
         QDomElement p = el;
         el = d->mXml.createElement(QLatin1String("Menu"));
         p.appendChild(el);
-        el.setAttribute(QLatin1String("name"), name);
+        el.setAttribute(QLatin1String("name"), n);
     }
     return el;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmenu_p.h 
new/libqtxdg-3.7.1/src/qtxdg/xdgmenu_p.h
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmenu_p.h    2020-10-30 14:18:22.000000000 
+0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmenu_p.h    2021-04-16 11:29:21.000000000 
+0200
@@ -37,7 +37,7 @@
 class QString;
 class QDomDocument;
 
-class XdgMenuPrivate: QObject
+class XdgMenuPrivate : public QObject
 {
 Q_OBJECT
 public:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmenuapplinkprocessor.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmenuapplinkprocessor.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmenuapplinkprocessor.cpp    2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmenuapplinkprocessor.cpp    2021-04-16 
11:29:21.000000000 +0200
@@ -51,9 +51,7 @@
 }
 
 
-XdgMenuApplinkProcessor::~XdgMenuApplinkProcessor()
-{
-}
+XdgMenuApplinkProcessor::~XdgMenuApplinkProcessor() = default;
 
 
 void XdgMenuApplinkProcessor::run()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmenureader.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmenureader.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmenureader.cpp      2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmenureader.cpp      2021-04-16 
11:29:21.000000000 +0200
@@ -49,10 +49,7 @@
 }
 
 
-XdgMenuReader::~XdgMenuReader()
-{
-
-}
+XdgMenuReader::~XdgMenuReader() = default;
 
 
 bool XdgMenuReader::load(const QString& fileName, const QString& baseDir)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmenurules.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmenurules.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmenurules.cpp       2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmenurules.cpp       2021-04-16 
11:29:21.000000000 +0200
@@ -43,9 +43,7 @@
 }
 
 
-XdgMenuRule::~XdgMenuRule()
-{
-}
+XdgMenuRule::~XdgMenuRule() = default;
 
 
 /************************************************
@@ -114,8 +112,7 @@
     for (std::list<XdgMenuRule*>::const_iterator i=mChilds.cbegin(); 
i!=mChilds.cend(); ++i)
         if (!(*i)->check(desktopFileId, desktopFile))  return false;
 
-    //FIXME: Doon't use implicit casts
-    return mChilds.size();
+    return !mChilds.empty();
 }
 
 
@@ -200,9 +197,7 @@
 }
 
 
-XdgMenuRules::~XdgMenuRules()
-{
-}
+XdgMenuRules::~XdgMenuRules() = default;
 
 
 void XdgMenuRules::addInclude(const QDomElement& element)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmimeapps.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmimeapps.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmimeapps.cpp        2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmimeapps.cpp        2021-04-16 
11:29:21.000000000 +0200
@@ -42,9 +42,7 @@
     });
 }
 
-XdgMimeAppsPrivate::~XdgMimeAppsPrivate()
-{
-}
+XdgMimeAppsPrivate::~XdgMimeAppsPrivate() = default;
 
 XdgMimeApps::XdgMimeApps(QObject *parent)
     : QObject(*new XdgMimeAppsPrivate, parent)
@@ -52,9 +50,7 @@
     d_func()->init();
 }
 
-XdgMimeApps::~XdgMimeApps()
-{
-}
+XdgMimeApps::~XdgMimeApps() = default;
 
 bool XdgMimeApps::addSupport(const QString &mimeType, const XdgDesktopFile 
&app)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libqtxdg-3.6.0/src/qtxdg/xdgmimeappsbackendinterface.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmimeappsbackendinterface.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmimeappsbackendinterface.cpp        
2020-10-30 14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmimeappsbackendinterface.cpp        
2021-04-16 11:29:21.000000000 +0200
@@ -25,6 +25,4 @@
 {
 }
 
-XdgMimeAppsBackendInterface::~XdgMimeAppsBackendInterface()
-{
-}
+XdgMimeAppsBackendInterface::~XdgMimeAppsBackendInterface() = default;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/qtxdg/xdgmimetype.cpp 
new/libqtxdg-3.7.1/src/qtxdg/xdgmimetype.cpp
--- old/libqtxdg-3.6.0/src/qtxdg/xdgmimetype.cpp        2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/qtxdg/xdgmimetype.cpp        2021-04-16 
11:29:21.000000000 +0200
@@ -86,9 +86,7 @@
     std::swap(dx, other.dx);
 }
 
-XdgMimeType::~XdgMimeType()
-{
-}
+XdgMimeType::~XdgMimeType() = default;
 
 
 QString XdgMimeType::iconName() const
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/tools/mat/defappmatcommand.cpp 
new/libqtxdg-3.7.1/src/tools/mat/defappmatcommand.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/defappmatcommand.cpp       2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/defappmatcommand.cpp       2021-04-16 
11:29:21.000000000 +0200
@@ -113,9 +113,7 @@
    Q_CHECK_PTR(parser);
 }
 
-DefAppMatCommand::~DefAppMatCommand()
-{
-}
+DefAppMatCommand::~DefAppMatCommand() = default;
 
 int DefAppMatCommand::run(const QStringList & /*arguments*/)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libqtxdg-3.6.0/src/tools/mat/defemailclientmatcommand.cpp 
new/libqtxdg-3.7.1/src/tools/mat/defemailclientmatcommand.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/defemailclientmatcommand.cpp       
2020-10-30 14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/defemailclientmatcommand.cpp       
2021-04-16 11:29:21.000000000 +0200
@@ -88,13 +88,13 @@
     QStringList posArgs = parser->positionalArguments();
     posArgs.removeAt(0);
 
-    if (isDefEmailClientNameSet && posArgs.size() > 0) {
+    if (isDefEmailClientNameSet && !posArgs.empty()) {
         *errorMessage = QSL("Extra arguments given: ");
         errorMessage->append(posArgs.join(QLatin1Char(',')));
         return CommandLineError;
     }
 
-    if (isListAvailableSet && (isDefEmailClientNameSet || posArgs.size() > 0)) 
{
+    if (isListAvailableSet && (isDefEmailClientNameSet || !posArgs.empty())) {
         *errorMessage = QSL("list-available can't be used with other options 
and doesn't take arguments");
         return CommandLineError;
     }
@@ -117,9 +117,7 @@
    Q_CHECK_PTR(parser);
 }
 
-DefEmailClientMatCommand::~DefEmailClientMatCommand()
-{
-}
+DefEmailClientMatCommand::~DefEmailClientMatCommand() = default;
 
 int DefEmailClientMatCommand::run(const QStringList & /*arguments*/)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libqtxdg-3.6.0/src/tools/mat/deffilemanagermatcommand.cpp 
new/libqtxdg-3.7.1/src/tools/mat/deffilemanagermatcommand.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/deffilemanagermatcommand.cpp       
2020-10-30 14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/deffilemanagermatcommand.cpp       
2021-04-16 11:29:21.000000000 +0200
@@ -88,13 +88,13 @@
     QStringList posArgs = parser->positionalArguments();
     posArgs.removeAt(0);
 
-    if (isDefFileManagerNameSet && posArgs.size() > 0) {
+    if (isDefFileManagerNameSet && !posArgs.empty()) {
         *errorMessage = QSL("Extra arguments given: ");
         errorMessage->append(posArgs.join(QLatin1Char(',')));
         return CommandLineError;
     }
 
-    if (isListAvailableSet && (isDefFileManagerNameSet || posArgs.size() > 0)) 
{
+    if (isListAvailableSet && (isDefFileManagerNameSet || !posArgs.empty())) {
         *errorMessage = QSL("list-available can't be used with other options 
and doesn't take arguments");
         return CommandLineError;
     }
@@ -117,9 +117,7 @@
    Q_CHECK_PTR(parser);
 }
 
-DefFileManagerMatCommand::~DefFileManagerMatCommand()
-{
-}
+DefFileManagerMatCommand::~DefFileManagerMatCommand() = default;
 
 int DefFileManagerMatCommand::run(const QStringList & /*arguments*/)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libqtxdg-3.6.0/src/tools/mat/defwebbrowsermatcommand.cpp 
new/libqtxdg-3.7.1/src/tools/mat/defwebbrowsermatcommand.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/defwebbrowsermatcommand.cpp        
2020-10-30 14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/defwebbrowsermatcommand.cpp        
2021-04-16 11:29:21.000000000 +0200
@@ -88,18 +88,18 @@
     QStringList posArgs = parser->positionalArguments();
     posArgs.removeAt(0);
 
-    if (isDefWebBrowserNameSet && posArgs.size() > 0) {
+    if (isDefWebBrowserNameSet && !posArgs.empty()) {
         *errorMessage = QSL("Extra arguments given: ");
         errorMessage->append(posArgs.join(QLatin1Char(',')));
         return CommandLineError;
     }
 
-    if (!isDefWebBrowserNameSet && posArgs.size() > 0) {
+    if (!isDefWebBrowserNameSet && !posArgs.empty()) {
         *errorMessage = QSL("To set the default browser use the -s/--set 
option");
         return CommandLineError;
     }
 
-    if (isListAvailableSet && (isDefWebBrowserNameSet || posArgs.size() > 0)) {
+    if (isListAvailableSet && (isDefWebBrowserNameSet || !posArgs.empty())) {
         *errorMessage = QSL("list-available can't be used with other options 
and doesn't take arguments");
         return CommandLineError;
     }
@@ -122,9 +122,7 @@
    Q_CHECK_PTR(parser);
 }
 
-DefWebBrowserMatCommand::~DefWebBrowserMatCommand()
-{
-}
+DefWebBrowserMatCommand::~DefWebBrowserMatCommand() = default;
 
 int DefWebBrowserMatCommand::run(const QStringList & /*arguments*/)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/tools/mat/matcommandinterface.cpp 
new/libqtxdg-3.7.1/src/tools/mat/matcommandinterface.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/matcommandinterface.cpp    2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/matcommandinterface.cpp    2021-04-16 
11:29:21.000000000 +0200
@@ -32,9 +32,7 @@
     Q_CHECK_PTR(parser);
 }
 
-MatCommandInterface::~MatCommandInterface()
-{
-}
+MatCommandInterface::~MatCommandInterface() = default;
 
 void MatCommandInterface::showHelp(int exitCode) const
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/tools/mat/matcommandmanager.cpp 
new/libqtxdg-3.7.1/src/tools/mat/matcommandmanager.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/matcommandmanager.cpp      2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/matcommandmanager.cpp      2021-04-16 
11:29:21.000000000 +0200
@@ -27,9 +27,7 @@
 #include <QDebug>
 
 
-MatCommandManager::MatCommandManager()
-{
-}
+MatCommandManager::MatCommandManager() = default;
 
 MatCommandManager::~MatCommandManager()
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/tools/mat/mimetypematcommand.cpp 
new/libqtxdg-3.7.1/src/tools/mat/mimetypematcommand.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/mimetypematcommand.cpp     2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/mimetypematcommand.cpp     2021-04-16 
11:29:21.000000000 +0200
@@ -44,9 +44,7 @@
 {
 }
 
-MimeTypeMatCommand::~MimeTypeMatCommand()
-{
-}
+MimeTypeMatCommand::~MimeTypeMatCommand() = default;
 
 static CommandLineParseResult parseCommandLine(QCommandLineParser *parser, 
QString *file, QString *errorMessage)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/tools/mat/openmatcommand.cpp 
new/libqtxdg-3.7.1/src/tools/mat/openmatcommand.cpp
--- old/libqtxdg-3.6.0/src/tools/mat/openmatcommand.cpp 2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/tools/mat/openmatcommand.cpp 2021-04-16 
11:29:21.000000000 +0200
@@ -45,9 +45,7 @@
 {
 }
 
-OpenMatCommand::~OpenMatCommand()
-{
-}
+OpenMatCommand::~OpenMatCommand() = default;
 
 static CommandLineParseResult parseCommandLine(QCommandLineParser *parser, 
QStringList *files, QString *errorMessage)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/xdgiconloader/xdgiconloader.cpp 
new/libqtxdg-3.7.1/src/xdgiconloader/xdgiconloader.cpp
--- old/libqtxdg-3.6.0/src/xdgiconloader/xdgiconloader.cpp      2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/xdgiconloader/xdgiconloader.cpp      2021-04-16 
11:29:21.000000000 +0200
@@ -48,10 +48,14 @@
 #include <QtCore/QList>
 #include <QtCore/QDir>
 #include <QtCore/QSettings>
+#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
+#include <QtCore/QStringView>
+#endif
 #include <QtGui/QPainter>
 #include <QImageReader>
 #include <QXmlStreamReader>
 #include <QFileSystemWatcher>
+#include <QSvgRenderer>
 
 #include <private/qhexstring_p.h>
 
@@ -107,7 +111,11 @@
 {
 public:
     explicit QIconCacheGtkReader(const QString &themeDir);
+#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
+    QVector<const char *> lookup(QStringView);
+#else
     QVector<const char *> lookup(const QStringRef &);
+#endif
     bool isValid() const { return m_isValid; }
     bool reValid(bool infoRefresh);
 private:
@@ -217,7 +225,12 @@
     with this name is present. The char* are pointers to the mapped data.
     For example, this would return { "32x32/apps", "24x24/apps" , ... }
  */
+
+#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
+QVector<const char *> QIconCacheGtkReader::lookup(QStringView name)
+#else
 QVector<const char *> QIconCacheGtkReader::lookup(const QStringRef &name)
+#endif
 {
     QVector<const char *> ret;
     if (!isValid() || name.isEmpty())
@@ -399,7 +412,11 @@
     const QString xpmext(QLatin1String(".xpm"));
 
 
+#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
+    QStringView iconNameFallback(iconName);
+#else
     QStringRef iconNameFallback(&iconName);
+#endif
 
     // Iterate through all icon's fallbacks in current theme
     if (info.entries.isEmpty()) {
@@ -613,17 +630,18 @@
         m_info.entries.clear();
         m_info.iconName.clear();
 
-        Q_ASSERT(m_info.entries.size() == 0);
+        Q_ASSERT(m_info.entries.empty());
         m_info = XdgIconLoader::instance()->loadIcon(m_iconName);
         m_key = QIconLoader::instance()->themeKey();
     }
 }
 
 void XdgIconLoaderEngine::paint(QPainter *painter, const QRect &rect,
-                             QIcon::Mode mode, QIcon::State state)
+                                QIcon::Mode mode, QIcon::State state)
 {
     QSize pixmapSize = rect.size();
-    const qreal dpr = painter->device()->devicePixelRatioF();
+    auto paintDevice = painter->device();
+    const qreal dpr = paintDevice ? paintDevice->devicePixelRatioF() : 
qApp->devicePixelRatio();
     painter->drawPixmap(rect, pixmap(QSizeF(pixmapSize * dpr).toSize(), mode, 
state));
 }
 
@@ -786,121 +804,141 @@
     return cachedPixmap;
 }
 
-// XXX: duplicated from qiconloader.cpp, because this symbol isn't exported :(
+// NOTE: For SVG, QSvgRenderer is used to prevent our icon handling from
+// being broken by icon engines that register themselves for SVG.
 QPixmap ScalableEntry::pixmap(const QSize &size, QIcon::Mode mode, 
QIcon::State state)
 {
-    if (svgIcon.isNull())
-        svgIcon = QIcon(filename);
+    QPixmap pm;
+    if (size.isEmpty())
+        return pm;
 
-    // Bypass QIcon API, as that will scale by device pixel ratio of the
-    // highest DPR screen since we're not passing on any QWindow.
-    if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine 
: nullptr)
-        return engine->pixmap(size, mode, state);
+    QString key = QLatin1String("lxqt_")
+                  % filename
+                  % HexString<int>(mode)
+                  % HexString<int>(state)
+                  % HexString<int>(size.width())
+                  % HexString<int>(size.height());
+    if (!QPixmapCache::find(key, &pm))
+    {
+        int icnSize = qMin(size.width(), size.height());
+        pm = QPixmap(icnSize, icnSize);
+        pm.fill(Qt::transparent);
+
+        QSvgRenderer renderer;
+        if (renderer.load(filename))
+        {
+            QPainter p;
+            p.begin(&pm);
+            renderer.render(&p, QRect(0, 0, icnSize, icnSize));
+            p.end();
+        }
 
-    return QPixmap();
+        svgIcon = QIcon(pm);
+        if (QIconEngine *engine = svgIcon.data_ptr() ? 
svgIcon.data_ptr()->engine : nullptr)
+            pm = engine->pixmap(size, mode, state);
+        QPixmapCache::insert(key, pm);
+    }
+
+    return pm;
 }
 
 static const QString STYLE = QStringLiteral("\n.ColorScheme-Text, 
.ColorScheme-NeutralText {color:%1;}\
 \n.ColorScheme-Background {color:%2;}\
 \n.ColorScheme-Highlight {color:%3;}");
-// Note: Qt palette does not have any colors for positive/negative text
+// NOTE: Qt palette does not have any colors for positive/negative text
 // .ColorScheme-PositiveText,ColorScheme-NegativeText {color:%4;}
 
 QPixmap ScalableFollowsColorEntry::pixmap(const QSize &size, QIcon::Mode mode, 
QIcon::State state)
 {
     QPixmap pm;
-    // see ScalableEntry::pixmap() for the reason
-    if (QIconEngine *engine = svgIcon.data_ptr() ? svgIcon.data_ptr()->engine 
: nullptr)
-        pm = engine->pixmap(size, mode, state);
-
-    // Note: not checking the QIcon::isNull(), because in Qt5.10 the isNull() 
is not reliable
-    // for svg icons desierialized from stream (see 
https://codereview.qt-project.org/#/c/216086/)
-    if (pm.isNull())
+    if (size.isEmpty())
+        return pm;
+
+    const QPalette pal = qApp->palette();
+    QString txtCol, bgCol, hCol;
+    if (mode == QIcon::Disabled)
+    {
+        txtCol = pal.color(QPalette::Disabled, QPalette::WindowText).name();
+        bgCol = pal.color(QPalette::Disabled, QPalette::Window).name();
+        hCol = pal.color(QPalette::Disabled, QPalette::Highlight).name();
+    }
+    else
     {
-        // The following lines are adapted and updated from KDE's 
"kiconloader.cpp" ->
-        // KIconLoaderPrivate::processSvg() and 
KIconLoaderPrivate::createIconImage().
-        // They read the SVG color scheme of SVG icons and give images based 
on the icon mode.
-        QHash<int, QByteArray> svg_buffers;
+        if (mode == QIcon::Selected)
+        {
+            txtCol = pal.highlightedText().color().name();
+            bgCol = pal.highlight().color().name();
+        }
+        else // normal or active
+        {
+            txtCol = pal.windowText().color().name();
+            bgCol = pal.window().color().name();
+        }
+        hCol = pal.highlight().color().name();
+    }
+    QString key = QLatin1String("lxqt_")
+                  % filename
+                  % HexString<int>(mode)
+                  % HexString<int>(state)
+                  % HexString<int>(size.width())
+                  % HexString<int>(size.height())
+                  % txtCol % bgCol % hCol;
+    if (!QPixmapCache::find(key, &pm))
+    {
+        int icnSize = qMin(size.width(), size.height());
+        pm = QPixmap(icnSize, icnSize);
+        pm.fill(Qt::transparent);
+
         QFile device{filename};
         if (device.open(QIODevice::ReadOnly))
         {
-            const QPalette pal = qApp->palette();
-            // Note: indexes are assembled as in qtsvg 
(QSvgIconEnginePrivate::hashKey())
-            QMap<int, QString> style_sheets;
-            style_sheets[(QIcon::Normal<<4)|QIcon::Off] = 
STYLE.arg(pal.windowText().color().name(), pal.window().color().name(), 
pal.highlight().color().name());
-            style_sheets[(QIcon::Selected<<4)|QIcon::Off] = 
STYLE.arg(pal.highlightedText().color().name(), pal.highlight().color().name(), 
pal.highlightedText().color().name());
-            QMap<int, QSharedPointer<QXmlStreamWriter> > writers;
-            for (auto i = style_sheets.cbegin(); i != style_sheets.cend(); ++i)
-            {
-                writers[i.key()].reset(new 
QXmlStreamWriter{&svg_buffers[i.key()]});
-            }
-
+            QString styleSheet = STYLE.arg(txtCol, bgCol, hCol);
+            QByteArray svgBuffer;
+            QXmlStreamWriter writer(&svgBuffer);
             QXmlStreamReader xmlReader(&device);
             while (!xmlReader.atEnd())
             {
                 if (xmlReader.readNext() == QXmlStreamReader::StartElement
-                        && xmlReader.qualifiedName() == QLatin1String("style")
-                        && xmlReader.attributes().value(QLatin1String("id")) 
== QLatin1String("current-color-scheme"))
+                    && xmlReader.qualifiedName() == QLatin1String("style")
+                    && xmlReader.attributes().value(QLatin1String("id")) == 
QLatin1String("current-color-scheme"))
                 {
                     const auto attribs = xmlReader.attributes();
                     // store original data/text of the <style> element
-                    QString original_data;
+                    QString origData;
                     while (xmlReader.tokenType() != 
QXmlStreamReader::EndElement)
                     {
                         if (xmlReader.tokenType() == 
QXmlStreamReader::Characters)
-                            original_data += xmlReader.text();
+                            origData += xmlReader.text();
                         xmlReader.readNext();
                     }
-                    for (auto i = style_sheets.cbegin(); i != 
style_sheets.cend(); ++i)
-                    {
-                        QXmlStreamWriter & writer = *writers[i.key()];
-                        writer.writeStartElement(QLatin1String("style"));
-                        writer.writeAttributes(attribs);
-                        // Note: We're writting the original style text to 
leave
-                        // there "defaults" for unknown/unsupported classes.
-                        // Then appending our "overrides"
-                        writer.writeCharacters(original_data);
-                        writer.writeCharacters(*i);
-                        writer.writeEndElement();
-                    }
-                } else if (xmlReader.tokenType() != QXmlStreamReader::Invalid)
-                {
-                    for (auto i = style_sheets.cbegin(); i != 
style_sheets.cend(); ++i)
-                    {
-                        writers[i.key()]->writeCurrentToken(xmlReader);
-                    }
+                    writer.writeStartElement(QLatin1String("style"));
+                    writer.writeAttributes(attribs);
+                    writer.writeCharacters(origData);
+                    writer.writeCharacters(styleSheet);
+                    writer.writeEndElement();
                 }
+                else if (xmlReader.tokenType() != QXmlStreamReader::Invalid)
+                    writer.writeCurrentToken(xmlReader);
             }
-            // duplicate the contets also for opposite state
-            svg_buffers[(QIcon::Normal<<4)|QIcon::On] = 
svg_buffers[(QIcon::Normal<<4)|QIcon::Off];
-            svg_buffers[(QIcon::Selected<<4)|QIcon::On] = 
svg_buffers[(QIcon::Selected<<4)|QIcon::Off];
-        }
-        // use the QSvgIconEngine
-        //  - assemble the content as it is done by the operator 
<<(QDataStream &s, const QIcon &icon)
-        //  (the QSvgIconEngine::key() + QSvgIconEngine::write())
-        //  - create the QIcon from the content by usage of the 
QIcon::operator >>(QDataStream &s, const QIcon &icon)
-        //  (icon with the (QSvgIconEngine) will be used)
-        QByteArray icon_arr;
-        QDataStream str{&icon_arr, QIODevice::WriteOnly};
-        str.setVersion(QDataStream::Qt_4_4);
-        QHash<int, QString> filenames;
-        filenames[0] = filename; // Note: filenames are ignored in the 
QSvgIconEngine::read()
-        str << QStringLiteral("svg") << filenames << 
static_cast<int>(0)/*isCompressed*/ << svg_buffers << 
static_cast<int>(0)/*hasAddedPimaps*/;
 
-        QDataStream str_read{&icon_arr, QIODevice::ReadOnly};
-        str_read.setVersion(QDataStream::Qt_4_4);
+            if (!svgBuffer.isEmpty())
+            {
+                QSvgRenderer renderer;
+                renderer.load(svgBuffer);
+                QPainter p;
+                p.begin(&pm);
+                renderer.render(&p, QRect(0, 0, icnSize, icnSize));
+                p.end();
+            }
+        }
 
-        str_read >> svgIcon;
+        // Do not use this pixmap directly but first get the icon
+        // for QIcon::pixmap() to handle states and modes,
+        // especially the disabled mode.
+        svgIcon = QIcon(pm);
         if (QIconEngine *engine = svgIcon.data_ptr() ? 
svgIcon.data_ptr()->engine : nullptr)
             pm = engine->pixmap(size, mode, state);
-
-        // load the icon directly from file, if still null
-        if (pm.isNull())
-        {
-            svgIcon = QIcon(filename);
-            if (QIconEngine *engine = svgIcon.data_ptr() ? 
svgIcon.data_ptr()->engine : nullptr)
-                pm = engine->pixmap(size, mode, state);
-        }
+        QPixmapCache::insert(key, pm);
     }
 
     return pm;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libqtxdg-3.6.0/src/xdgiconloader/xdgiconloader_p.h 
new/libqtxdg-3.7.1/src/xdgiconloader/xdgiconloader_p.h
--- old/libqtxdg-3.6.0/src/xdgiconloader/xdgiconloader_p.h      2020-10-30 
14:18:22.000000000 +0100
+++ new/libqtxdg-3.7.1/src/xdgiconloader/xdgiconloader_p.h      2021-04-16 
11:29:21.000000000 +0200
@@ -63,7 +63,7 @@
 
 struct ScalableFollowsColorEntry : public ScalableEntry
 {
-    QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) 
Q_DECL_OVERRIDE;
+    QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) 
override;
 };
 
 //class QIconLoaderEngine : public QIconEngine
@@ -73,18 +73,18 @@
     XdgIconLoaderEngine(const QString& iconName = QString());
     ~XdgIconLoaderEngine() override;
 
-    void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, 
QIcon::State state) Q_DECL_OVERRIDE;
-    QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) 
Q_DECL_OVERRIDE;
-    QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) 
Q_DECL_OVERRIDE;
-    QIconEngine *clone() const Q_DECL_OVERRIDE;
-    bool read(QDataStream &in) Q_DECL_OVERRIDE;
-    bool write(QDataStream &out) const Q_DECL_OVERRIDE;
+    void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, 
QIcon::State state) override;
+    QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) 
override;
+    QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) 
override;
+    QIconEngine *clone() const override;
+    bool read(QDataStream &in) override;
+    bool write(QDataStream &out) const override;
 
 private:
-    QString key() const Q_DECL_OVERRIDE;
+    QString key() const override;
     bool hasIcon() const;
     void ensureLoaded();
-    void virtual_hook(int id, void *data) Q_DECL_OVERRIDE;
+    void virtual_hook(int id, void *data) override;
     QIconLoaderEngineEntry *entryForSize(const QSize &size, int scale = 1);
     XdgIconLoaderEngine(const XdgIconLoaderEngine &other);
     QThemeIconInfo m_info;

Reply via email to