From 517403096dedc848f4a8ca3a7b74623dda17eb5d Mon Sep 17 00:00:00 2001 From: Marco Martin Date: Tue, 4 Feb 2014 12:06:09 +0100 Subject: [PATCH] port improve cache file dropping to plasma-framework this ports revision c03052935b082 on kdelibs improve cache file dropping * fix regression: version the image cache file name * version the svg elements * drop old svg elements files * respond to changes at runtime by watching the theme's metadata.desktop for changes * move creation of the svg elements file into ThemePrivate::useCache() REVIEW:115397 --- src/plasma/private/theme_p.cpp | 95 ++++++++++++++++++++++++++-------- src/plasma/private/theme_p.h | 2 + src/plasma/theme.cpp | 10 ++-- 3 files changed, 80 insertions(+), 27 deletions(-) diff --git a/src/plasma/private/theme_p.cpp b/src/plasma/private/theme_p.cpp index f8ddfec46..66dc8f64e 100644 --- a/src/plasma/private/theme_p.cpp +++ b/src/plasma/private/theme_p.cpp @@ -129,22 +129,46 @@ KConfigGroup &ThemePrivate::config() bool ThemePrivate::useCache() { + bool cachesTooOld = false; + if (cacheTheme && !pixmapCache) { if (cacheSize == 0) { ThemeConfig config; cacheSize = config.themeCacheKb(); } const bool isRegularTheme = themeName != systemColorsTheme; - const QString cacheFile = "plasma_theme_" + themeName; + QString cacheFile = "plasma_theme_" + themeName; + + // clear any cached values from the previous theme cache + themeVersion.clear(); + + if (!themeMetadataPath.isEmpty()) { + KDirWatch::self()->removeFile(themeMetadataPath); + } + themeMetadataPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1Literal("desktoptheme/") % themeName % QLatin1Literal("/metadata.desktop")); + if (isRegularTheme) { const QString cacheFileBase = cacheFile + "*.kcache"; - const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "desktoptheme/" + themeName + "/metadata.desktop"); QString currentCacheFileName; - if (!path.isEmpty()) { - const KPluginInfo pluginInfo(path); - currentCacheFileName = cacheFile + "_v" + pluginInfo.version() + ".kcache"; + if (!themeMetadataPath.isEmpty()) { + // now we record the theme version, if we can + const KPluginInfo pluginInfo(themeMetadataPath); + themeVersion = pluginInfo.version(); + if (!themeVersion.isEmpty()) { + cacheFile += "_v" + themeVersion; + currentCacheFileName = cacheFile + ".kcache"; + } + + // watch the metadata file for changes at runtime + KDirWatch::self()->addFile(themeMetadataPath); + QObject::connect(KDirWatch::self(), SIGNAL(created(QString)), + this, SLOT(settingsFileChanged(QString)), + Qt::UniqueConnection); + QObject::connect(KDirWatch::self(), SIGNAL(dirty(QString)), + this, SLOT(settingsFileChanged(QString)), + Qt::UniqueConnection); } // now we check for, and remove if necessary, old caches @@ -157,19 +181,48 @@ bool ThemePrivate::useCache() } - pixmapCache = new KImageCache(cacheFile, cacheSize * 1024); - // now we do a sanity check: if the metadata.desktop file is newer than the cache, drop - // the cache - if (isRegularTheme) { + // now we do a sanity check: if the metadata.desktop file is newer than the cache, drop the cache + if (isRegularTheme && !themeMetadataPath.isEmpty()) { + // now we check to see if the theme metadata file itself is newer than the pixmap cache + // this is done before creating the pixmapCache object since that can change the mtime + // on the cache file + // FIXME: when using the system colors, if they change while the application is not running // the cache should be dropped; we need a way to detect system color change when the // application is not running. - const QFile f(cacheFile); - const QFileInfo fileInfo(f); - if (fileInfo.lastModified().toTime_t() > uint(pixmapCache->lastModifiedTime().toTime_t())) { - discardCache(PixmapCache | SvgElementsCache); + // check for expired cache + const QString cacheFilePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + '/' + cacheFile; + if (!cacheFilePath.isEmpty()) { + const QFileInfo cacheFileInfo(cacheFilePath); + const QFileInfo metadataFileInfo(themeMetadataPath); + cachesTooOld = cacheFileInfo.lastModified().toTime_t() > metadataFileInfo.lastModified().toTime_t(); } } + + ThemeConfig config; + pixmapCache = new KImageCache(cacheFile, config.themeCacheKb() * 1024); + + if (cachesTooOld) { + discardCache(PixmapCache | SvgElementsCache); + } + } + + if (cacheTheme && !svgElementsCache) { + const QString svgElementsFileNameBase = "plasma-svgelements-" + themeName; + QString svgElementsFileName = svgElementsFileNameBase; + if (!themeVersion.isEmpty()) { + svgElementsFileName += "_v" + themeVersion; + } + + // now we check for (and remove) old caches + foreach (const QString &file, QStandardPaths::locateAll(QStandardPaths::CacheLocation, svgElementsFileNameBase + "*")) { + if (cachesTooOld || !file.endsWith(svgElementsFileName)) { + QFile::remove(file); + } + } + + const QString svgElementsFile = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + '/' + svgElementsFileName; + svgElementsCache = KSharedConfig::openConfig(svgElementsFile); } return cacheTheme; @@ -246,14 +299,7 @@ void ThemePrivate::discardCache(CacheTypes caches) discoveries.clear(); invalidElements.clear(); - if (svgElementsCache) { - QFile f(svgElementsCache->name()); - svgElementsCache = 0; - f.remove(); - } - - const QString svgElementsFile = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1Char('/') + "plasma-svgelements-" + themeName; - svgElementsCache = KSharedConfig::openConfig(svgElementsFile); + svgElementsCache = 0; } } @@ -388,7 +434,12 @@ const QString ThemePrivate::svgStyleSheet() void ThemePrivate::settingsFileChanged(const QString &file) { qDebug() << "settingsFile: " << file; - if (file.endsWith(themeRcFile)) { + if (file == themeMetadataPath) { + const KPluginInfo pluginInfo(themeMetadataPath); + if (themeVersion != pluginInfo.version()) { + scheduleThemeChangeNotification(SvgElementsCache); + } + } else if (file.endsWith(themeRcFile)) { config().config()->reparseConfiguration(); settingsChanged(); } diff --git a/src/plasma/private/theme_p.h b/src/plasma/private/theme_p.h index 3dcd14044..c99776e8d 100644 --- a/src/plasma/private/theme_p.h +++ b/src/plasma/private/theme_p.h @@ -135,6 +135,8 @@ public: QTimer *updateNotificationTimer; unsigned cacheSize; CacheTypes cachesToDiscard; + QString themeVersion; + QString themeMetadataPath; bool locolor : 1; bool compositingActive : 1; diff --git a/src/plasma/theme.cpp b/src/plasma/theme.cpp index a0ff7c4ef..e2632eabb 100644 --- a/src/plasma/theme.cpp +++ b/src/plasma/theme.cpp @@ -348,7 +348,7 @@ void Theme::insertIntoCache(const QString& key, const QPixmap& pix, const QStrin bool Theme::findInRectsCache(const QString &image, const QString &element, QRectF &rect) const { - if (!d->svgElementsCache) { + if (!d->useCache()) { return false; } @@ -381,7 +381,7 @@ bool Theme::findInRectsCache(const QString &image, const QString &element, QRect QStringList Theme::listCachedRectKeys(const QString &image) const { - if (!d->svgElementsCache) { + if (!d->useCache()) { return QStringList(); } @@ -404,7 +404,7 @@ QStringList Theme::listCachedRectKeys(const QString &image) const void Theme::insertIntoRectsCache(const QString& image, const QString &element, const QRectF &rect) { - if (!d->svgElementsCache) { + if (!d->useCache()) { return; } @@ -427,7 +427,7 @@ void Theme::insertIntoRectsCache(const QString& image, const QString &element, c void Theme::invalidateRectsCache(const QString& image) { - if (d->svgElementsCache) { + if (d->useCache()) { KConfigGroup imageGroup(d->svgElementsCache, image); imageGroup.deleteGroup(); } @@ -439,7 +439,7 @@ void Theme::releaseRectsCache(const QString &image) { QHash >::iterator it = d->invalidElements.find(image); if (it != d->invalidElements.end()) { - if (!d->svgElementsCache) { + if (d->useCache()) { KConfigGroup imageGroup(d->svgElementsCache, it.key()); imageGroup.writeEntry("invalidElements", it.value().toList()); }