diff --git a/src/util/dicontheme.cpp b/src/util/dicontheme.cpp index 7e96ab4..dfb13d8 100644 --- a/src/util/dicontheme.cpp +++ b/src/util/dicontheme.cpp @@ -186,7 +186,8 @@ QIcon DIconTheme::Cached::findQIcon(const QString &iconName, Options options, co } auto newIcon = new QIcon(DIconTheme::findQIcon(iconName, options)); - data->cache.insert(cacheKey, newIcon); + if (!newIcon->isNull()) + data->cache.insert(cacheKey, newIcon); if (newIcon->isNull()) return fallback; diff --git a/src/util/private/diconproxyengine.cpp b/src/util/private/diconproxyengine.cpp index 707983e..058c199 100644 --- a/src/util/private/diconproxyengine.cpp +++ b/src/util/private/diconproxyengine.cpp @@ -86,6 +86,22 @@ static inline QIconEngine *createDBuiltinIconEngine(const QString &iconName) return nullptr; } +#ifdef DTK_DISABLE_LIBXDG +static inline QIconEngine *createQIconEngine(const QString &iconName) +{ + QIconEngine *engine = nullptr; + + // fallback to QPlatformTheme::createIconEngine ==> QIconLoaderEngine + QPlatformTheme * const platformTheme = QGuiApplicationPrivate::platformTheme(); + bool hasUserTheme = QIconLoader::instance()->hasUserTheme(); + if (platformTheme && !hasUserTheme) { + engine = platformTheme->QPlatformTheme::createIconEngine(iconName); + } + + return engine; +} +#endif + static bool hasDciIcon(const QString &iconName, const QString &iconThemeName) { QString iconPath; @@ -103,6 +119,11 @@ static inline bool isDciIconEngine(QIconEngine *engine) return dynamic_cast(engine); } +static inline bool isDBuiltinIconEngine(QIconEngine *engine) +{ + return dynamic_cast(engine); +} + DIconProxyEngine::DIconProxyEngine(const QString &iconName, DIconTheme::Options options) : m_iconName(iconName) , m_option(options) @@ -216,6 +237,16 @@ void DIconProxyEngine::virtual_hook(int id, void *data) } } +void DIconProxyEngine::createQXIconengine() +{ +#ifdef DTK_DISABLE_LIBXDG + if (Q_UNLIKELY(!m_option.testFlag(DIconTheme::DontFallbackToQIconFromTheme))) + m_iconEngine = createQIconEngine(m_iconName); +#else + m_iconEngine = createXdgProxyIconEngine(m_iconName); +#endif +} + void DIconProxyEngine::ensureEngine() { if (m_iconName.isEmpty()) @@ -227,8 +258,12 @@ void DIconProxyEngine::ensureEngine() static QMap> nonCache; const auto it = nonCache.find(theme); - if (it != nonCache.end() && it->contains(m_iconName)) - return; + if (it != nonCache.end() && it->contains(m_iconName)) { + if (isDciIconEngine(m_iconEngine) || isDBuiltinIconEngine(m_iconEngine)) + return; + + createQXIconengine(); + } if (m_iconEngine) { // dci => dci @@ -257,21 +292,11 @@ void DIconProxyEngine::ensureEngine() if (!m_iconEngine && Q_UNLIKELY(!m_option.testFlag(DIconTheme::IgnoreBuiltinIcons)) ) { m_iconEngine = createDBuiltinIconEngine(m_iconName); } -#ifdef DTK_DISABLE_LIBXDG - if (!m_iconEngine && Q_UNLIKELY(!m_option.testFlag(DIconTheme::DontFallbackToQIconFromTheme))) { - // fallback to QPlatformTheme::createIconEngine ==> QIconLoaderEngine - QPlatformTheme * const platformTheme = QGuiApplicationPrivate::platformTheme(); - bool hasUserTheme = QIconLoader::instance()->hasUserTheme(); - if (platformTheme && !hasUserTheme) { - m_iconEngine = platformTheme->QPlatformTheme::createIconEngine(m_iconName); - } - } -#else - if (!m_iconEngine ) { - m_iconEngine = createXdgProxyIconEngine(m_iconName); - } -#endif - if (!m_iconEngine ) { + + if (!m_iconEngine ) + m_iconEngine = createQXIconengine(); + + if (!m_iconEngine && !nonCache[theme].contains(m_iconName)) { qErrnoWarning("create icon [%s] engine failed.[theme:%s] nonCache[theme].size[%d]", m_iconName.toUtf8().data(), theme.toUtf8().data(), nonCache[theme].size()); @@ -279,6 +304,14 @@ void DIconProxyEngine::ensureEngine() return; } + if (m_iconEngine && m_iconEngine->isNull()) { + // QIcon::setThemeSearchPaths(QIcon::themeSearchPaths()); + delete m_iconEngine; + m_iconEngine = nullptr; + } else if (m_iconEngine && !m_iconEngine->isNull() && nonCache[theme].contains(m_iconName)) { + nonCache[theme].remove(m_iconName); + } + m_iconThemeName = theme; } diff --git a/src/util/private/diconproxyengine_p.h b/src/util/private/diconproxyengine_p.h index c7aafdf..7efa8bb 100644 --- a/src/util/private/diconproxyengine_p.h +++ b/src/util/private/diconproxyengine_p.h @@ -50,6 +50,7 @@ class Q_DECL_HIDDEN DIconProxyEngine : public QIconEngine void ensureEngine(); DIconProxyEngine(const DIconProxyEngine &other); + void createQXIconengine(); QString m_iconName; QString m_iconThemeName; QIconEngine *m_iconEngine = nullptr;