Draft: Replace QString cache IDs with a struct-based version
As it turns out, QString::number() is quite expensive, especially when using it in a code path that is called a lot of times. So instead, use a struct with a custom hash method as cache ID. This is significantly faster since we do not need to do memory allocations or string conversions.
This commit is contained in:
parent
b1b91fb3eb
commit
f09b46bec6
@ -33,6 +33,7 @@ target_link_libraries(corebindingsplugin
|
|||||||
KF5::Declarative
|
KF5::Declarative
|
||||||
KF5::IconThemes
|
KF5::IconThemes
|
||||||
KF5::I18n
|
KF5::I18n
|
||||||
|
Qt5::Svg
|
||||||
KF5::Service #for kplugininfo.h
|
KF5::Service #for kplugininfo.h
|
||||||
KF5::WindowSystem
|
KF5::WindowSystem
|
||||||
KF5::Plasma
|
KF5::Plasma
|
||||||
|
@ -83,7 +83,7 @@ ecm_generate_export_header(KF5Plasma
|
|||||||
GROUP_BASE_NAME KF
|
GROUP_BASE_NAME KF
|
||||||
VERSION ${KF5_VERSION}
|
VERSION ${KF5_VERSION}
|
||||||
DEPRECATED_BASE_VERSION 0
|
DEPRECATED_BASE_VERSION 0
|
||||||
DEPRECATION_VERSIONS 5.6 5.19 5.28 5.30 5.36 5.46 5.67 5.77
|
DEPRECATION_VERSIONS 5.6 5.19 5.28 5.30 5.36 5.46 5.67 5.77 5.78
|
||||||
)
|
)
|
||||||
# TODO: add support for EXCLUDE_DEPRECATED_BEFORE_AND_AT to all Plasma libs
|
# TODO: add support for EXCLUDE_DEPRECATED_BEFORE_AND_AT to all Plasma libs
|
||||||
# needs fixing of undeprecated API being still implemented using own deprecated API
|
# needs fixing of undeprecated API being still implemented using own deprecated API
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
namespace Plasma
|
namespace Plasma
|
||||||
{
|
{
|
||||||
|
|
||||||
QHash<ThemePrivate *, QHash<QString, QWeakPointer<FrameData>> > FrameSvgPrivate::s_sharedFrames;
|
QHash<ThemePrivate *, QHash<uint, QWeakPointer<FrameData>> > FrameSvgPrivate::s_sharedFrames;
|
||||||
|
|
||||||
// Any attempt to generate a frame whose width or height is larger than this
|
// Any attempt to generate a frame whose width or height is larger than this
|
||||||
// will be rejected
|
// will be rejected
|
||||||
@ -332,7 +332,7 @@ QRegion FrameSvg::mask() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString id = d->cacheId(d->frame.data(), QString());
|
uint id = qHash(d->cacheId(d->frame.data(), QString()), SvgRectsCache::s_seed);
|
||||||
|
|
||||||
QRegion* obj = d->frame->cachedMasks.object(id);
|
QRegion* obj = d->frame->cachedMasks.object(id);
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ QPixmap FrameSvgPrivate::alphaMask()
|
|||||||
|
|
||||||
QSharedPointer<FrameData> FrameSvgPrivate::lookupOrCreateMaskFrame(const QSharedPointer<FrameData> &frame, const QString &maskPrefix, const QString &maskRequestedPrefix)
|
QSharedPointer<FrameData> FrameSvgPrivate::lookupOrCreateMaskFrame(const QSharedPointer<FrameData> &frame, const QString &maskPrefix, const QString &maskRequestedPrefix)
|
||||||
{
|
{
|
||||||
const QString key = cacheId(frame.data(), maskPrefix);
|
const uint key = qHash(cacheId(frame.data(), maskPrefix));
|
||||||
QSharedPointer<FrameData> mask = s_sharedFrames[q->theme()->d].value(key);
|
QSharedPointer<FrameData> mask = s_sharedFrames[q->theme()->d].value(key);
|
||||||
|
|
||||||
// See if we can find a suitable candidate in the shared frames.
|
// See if we can find a suitable candidate in the shared frames.
|
||||||
@ -488,17 +488,19 @@ void FrameSvgPrivate::generateBackground(const QSharedPointer<FrameData> &frame)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString id = cacheId(frame.data(), frame->prefix);
|
const uint id = qHash(cacheId(frame.data(), frame->prefix));
|
||||||
|
|
||||||
bool frameCached = !frame->cachedBackground.isNull();
|
bool frameCached = !frame->cachedBackground.isNull();
|
||||||
bool overlayCached = false;
|
bool overlayCached = false;
|
||||||
|
//TODO KF6: Kill Overlays
|
||||||
const bool overlayAvailable = !frame->prefix.startsWith(QLatin1String("mask-")) && q->hasElement(frame->prefix % QLatin1String("overlay"));
|
const bool overlayAvailable = !frame->prefix.startsWith(QLatin1String("mask-")) && q->hasElement(frame->prefix % QLatin1String("overlay"));
|
||||||
QPixmap overlay;
|
QPixmap overlay;
|
||||||
if (q->isUsingRenderingCache()) {
|
if (q->isUsingRenderingCache()) {
|
||||||
frameCached = q->theme()->findInCache(id, frame->cachedBackground, frame->lastModified) && !frame->cachedBackground.isNull();
|
frameCached = q->theme()->findInCache(QString::number(id), frame->cachedBackground, frame->lastModified) && !frame->cachedBackground.isNull();
|
||||||
|
|
||||||
if (overlayAvailable) {
|
if (overlayAvailable) {
|
||||||
overlayCached = q->theme()->findInCache(QLatin1String("overlay_") % id, overlay, frame->lastModified) && !overlay.isNull();
|
const uint overlayId = qHash(cacheId(frame.data(), frame->prefix % QLatin1String("overlay")));
|
||||||
|
overlayCached = q->theme()->findInCache(QString::number(overlayId), overlay, frame->lastModified) && !overlay.isNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,10 +624,10 @@ QRect FrameSvgPrivate::contentGeometry(const QSharedPointer<FrameData> &frame, c
|
|||||||
void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType)
|
void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType)
|
||||||
{
|
{
|
||||||
auto fd = frame;
|
auto fd = frame;
|
||||||
QString newKey;
|
uint newKey = 0;
|
||||||
|
|
||||||
if (fd) {
|
if (fd) {
|
||||||
const QString oldKey = fd->cacheId;
|
const uint oldKey = fd->cacheId;
|
||||||
|
|
||||||
const QString oldPath = fd->imagePath;
|
const QString oldPath = fd->imagePath;
|
||||||
const FrameSvg::EnabledBorders oldBorders = fd->enabledBorders;
|
const FrameSvg::EnabledBorders oldBorders = fd->enabledBorders;
|
||||||
@ -635,7 +637,7 @@ void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType)
|
|||||||
fd->frameSize = pendingFrameSize;
|
fd->frameSize = pendingFrameSize;
|
||||||
fd->imagePath = q->imagePath();
|
fd->imagePath = q->imagePath();
|
||||||
|
|
||||||
newKey = cacheId(fd.data(), prefix);
|
newKey = qHash(cacheId(fd.data(), prefix));
|
||||||
|
|
||||||
//reset frame to old values
|
//reset frame to old values
|
||||||
fd->enabledBorders = oldBorders;
|
fd->enabledBorders = oldBorders;
|
||||||
@ -671,8 +673,8 @@ void FrameSvgPrivate::updateFrameData(uint lastModified, UpdateType updateType)
|
|||||||
fd->imagePath = q->imagePath();
|
fd->imagePath = q->imagePath();
|
||||||
fd->lastModified = lastModified;
|
fd->lastModified = lastModified;
|
||||||
//was fd just created empty now?
|
//was fd just created empty now?
|
||||||
if (newKey.isEmpty()) {
|
if (newKey == 0) {
|
||||||
newKey = cacheId(fd.data(), prefix);
|
newKey = qHash(cacheId(fd.data(), prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
// we know it isn't in s_sharedFrames due to the check above, so insert it now
|
// we know it isn't in s_sharedFrames due to the check above, so insert it now
|
||||||
@ -752,11 +754,10 @@ void FrameSvgPrivate::paintCorner(QPainter& p, const QSharedPointer<FrameData> &
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FrameSvgPrivate::cacheId(FrameData *frame, const QString &prefixToSave) const
|
SvgPrivate::CacheId FrameSvgPrivate::cacheId(FrameData *frame, const QString &prefixToSave) const
|
||||||
{
|
{
|
||||||
const QSize size = frameSize(frame).toSize();
|
const QSize size = frameSize(frame).toSize();
|
||||||
const QLatin1Char s('_');
|
return SvgPrivate::CacheId{double(size.width()), double(size.height()), frame->imagePath, prefixToSave, q->status(), q->scaleFactor(), q->devicePixelRatio(), q->colorGroup(), frame->enabledBorders, q->Svg::d->lastModified};
|
||||||
return QString::number(frame->enabledBorders) % s % QString::number(size.width()) % s % QString::number(size.height()) % s % QString::number(q->scaleFactor()) % s % QString::number(q->devicePixelRatio()) % s % prefixToSave % s % frame->imagePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameSvgPrivate::cacheFrame(const QString &prefixToSave, const QPixmap &background, const QPixmap &overlay)
|
void FrameSvgPrivate::cacheFrame(const QString &prefixToSave, const QPixmap &background, const QPixmap &overlay)
|
||||||
@ -770,15 +771,16 @@ void FrameSvgPrivate::cacheFrame(const QString &prefixToSave, const QPixmap &bac
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString id = cacheId(frame.data(), prefixToSave);
|
const uint id = qHash(cacheId(frame.data(), prefixToSave));
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA)<<"Saving to cache frame"<<id;
|
//qCDebug(LOG_PLASMA)<<"Saving to cache frame"<<id;
|
||||||
|
|
||||||
q->theme()->insertIntoCache(id, background, QString::number((qint64)q, 16) % prefixToSave);
|
q->theme()->insertIntoCache(QString::number(id), background, QString::number((qint64)q, 16) % prefixToSave);
|
||||||
|
|
||||||
if (!overlay.isNull()) {
|
if (!overlay.isNull()) {
|
||||||
//insert overlay
|
//insert overlay
|
||||||
q->theme()->insertIntoCache(QLatin1String("overlay_") % id, overlay, QString::number((qint64)q, 16) % prefixToSave % QLatin1String("overlay"));
|
const uint overlayId = qHash(cacheId(frame.data(), frame->prefix % QLatin1String("overlay")));
|
||||||
|
q->theme()->insertIntoCache(QString::number(overlayId), overlay, QString::number((qint64)q, 16) % prefixToSave % QLatin1String("overlay"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
#include <Plasma/Theme>
|
#include <Plasma/Theme>
|
||||||
|
|
||||||
|
#include "svg_p.h"
|
||||||
|
|
||||||
namespace Plasma
|
namespace Plasma
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -73,12 +75,12 @@ public:
|
|||||||
QString requestedPrefix;
|
QString requestedPrefix;
|
||||||
FrameSvg::EnabledBorders enabledBorders;
|
FrameSvg::EnabledBorders enabledBorders;
|
||||||
QPixmap cachedBackground;
|
QPixmap cachedBackground;
|
||||||
QCache<QString, QRegion> cachedMasks;
|
QCache<uint, QRegion> cachedMasks;
|
||||||
static const int MAX_CACHED_MASKS = 10;
|
static const int MAX_CACHED_MASKS = 10;
|
||||||
uint lastModified = 0;
|
uint lastModified = 0;
|
||||||
|
|
||||||
QSize frameSize;
|
QSize frameSize;
|
||||||
QString cacheId;
|
uint cacheId;
|
||||||
|
|
||||||
//measures
|
//measures
|
||||||
int topHeight;
|
int topHeight;
|
||||||
@ -145,7 +147,7 @@ public:
|
|||||||
|
|
||||||
void generateBackground(const QSharedPointer<FrameData> &frame);
|
void generateBackground(const QSharedPointer<FrameData> &frame);
|
||||||
void generateFrameBackground(const QSharedPointer<FrameData> &);
|
void generateFrameBackground(const QSharedPointer<FrameData> &);
|
||||||
QString cacheId(FrameData *frame, const QString &prefixToUse) const;
|
SvgPrivate::CacheId cacheId(FrameData *frame, const QString &prefixToUse) const;
|
||||||
void cacheFrame(const QString &prefixToSave, const QPixmap &background, const QPixmap &overlay);
|
void cacheFrame(const QString &prefixToSave, const QPixmap &background, const QPixmap &overlay);
|
||||||
void updateSizes(FrameData* frame) const;
|
void updateSizes(FrameData* frame) const;
|
||||||
void updateSizes(const QSharedPointer<FrameData> &frame) const { return updateSizes(frame.data()); }
|
void updateSizes(const QSharedPointer<FrameData> &frame) const { return updateSizes(frame.data()); }
|
||||||
@ -178,7 +180,7 @@ public:
|
|||||||
//this can differ from frame->frameSize if we are in a transition
|
//this can differ from frame->frameSize if we are in a transition
|
||||||
QSize pendingFrameSize;
|
QSize pendingFrameSize;
|
||||||
|
|
||||||
static QHash<ThemePrivate *, QHash<QString, QWeakPointer<FrameData>> > s_sharedFrames;
|
static QHash<ThemePrivate *, QHash<uint, QWeakPointer<FrameData>> > s_sharedFrames;
|
||||||
|
|
||||||
bool cacheAll : 1;
|
bool cacheAll : 1;
|
||||||
bool repaintBlocked : 1;
|
bool repaintBlocked : 1;
|
||||||
|
@ -48,11 +48,24 @@ private:
|
|||||||
class SvgPrivate
|
class SvgPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct CacheId {
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
QString filePath;
|
||||||
|
QString elementName;
|
||||||
|
int status;
|
||||||
|
double devicePixelRatio;
|
||||||
|
double scaleFactor;
|
||||||
|
int colorGroup;
|
||||||
|
uint extraFlags; //Not used here, used for enabledborders in FrameSvg
|
||||||
|
uint lastModified;
|
||||||
|
};
|
||||||
|
|
||||||
SvgPrivate(Svg *svg);
|
SvgPrivate(Svg *svg);
|
||||||
~SvgPrivate();
|
~SvgPrivate();
|
||||||
|
|
||||||
//This function is meant for the rects cache
|
//This function is meant for the rects cache
|
||||||
QString cacheId(const QString &elementId) const;
|
CacheId cacheId(const QString &elementId) const;
|
||||||
|
|
||||||
//This function is meant for the pixmap cache
|
//This function is meant for the pixmap cache
|
||||||
QString cachePath(const QString &path, const QSize &size) const;
|
QString cachePath(const QString &path, const QSize &size) const;
|
||||||
@ -68,7 +81,7 @@ public:
|
|||||||
void eraseRenderer();
|
void eraseRenderer();
|
||||||
|
|
||||||
QRectF elementRect(const QString &elementId);
|
QRectF elementRect(const QString &elementId);
|
||||||
QRectF findAndCacheElementRect(const QString &elementId, const QString &cacheId);
|
QRectF findAndCacheElementRect(const QString &elementId);
|
||||||
|
|
||||||
void checkColorHints();
|
void checkColorHints();
|
||||||
|
|
||||||
@ -88,8 +101,6 @@ public:
|
|||||||
|
|
||||||
Svg *q;
|
Svg *q;
|
||||||
QPointer<Theme> theme;
|
QPointer<Theme> theme;
|
||||||
QHash<QString, QRectF> localRectCache;
|
|
||||||
QMultiHash<QString, QSize> elementsWithSizeHints;
|
|
||||||
SharedSvgRenderer::Ptr renderer;
|
SharedSvgRenderer::Ptr renderer;
|
||||||
QString themePath;
|
QString themePath;
|
||||||
QString path;
|
QString path;
|
||||||
@ -111,7 +122,56 @@ public:
|
|||||||
bool themeFailed : 1;
|
bool themeFailed : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class SvgRectsCache : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SvgRectsCache(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
static SvgRectsCache *instance();
|
||||||
|
|
||||||
|
void insert(SvgPrivate::CacheId cacheId, const QRectF &rect, unsigned int lastModified);
|
||||||
|
void insert(uint id, const QString &filePath, const QRectF &rect, unsigned int lastModified);
|
||||||
|
// Those 2 methods are the same, the second uses the integer id produced by hashed CacheId
|
||||||
|
bool findElementRect(SvgPrivate::CacheId cacheId, QRectF &rect);
|
||||||
|
bool findElementRect(uint id, const QString &filePath, QRectF &rect);
|
||||||
|
|
||||||
|
void loadImageFromCache(const QString &path, uint lastModified);
|
||||||
|
void dropImageFromCache(const QString &path);
|
||||||
|
void expireCache(const QString &path);
|
||||||
|
|
||||||
|
void setNaturalSize(const QString &path, qreal scaleFactor, const QSizeF &size);
|
||||||
|
QSizeF naturalSize(const QString &path, qreal scaleFactor);
|
||||||
|
|
||||||
|
QList<QSize> sizeHintsForId(const QString &path, const QString &id);
|
||||||
|
void insertSizeHintForId(const QString &path, const QString &id, const QSize &size);
|
||||||
|
|
||||||
|
QString iconThemePath();
|
||||||
|
void setIconThemePath(const QString &path);
|
||||||
|
|
||||||
|
QStringList cachedKeysForPath(const QString &path) const;
|
||||||
|
|
||||||
|
void updateLastModified(const QString &filePath, unsigned int lastModified);
|
||||||
|
|
||||||
|
static const uint s_seed;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTimer *m_configSyncTimer = nullptr;
|
||||||
|
QString m_iconThemePath;
|
||||||
|
KSharedConfigPtr m_svgElementsCache;
|
||||||
|
/*
|
||||||
|
* We are indexing in the hash cache ids by their "digested" uint out of qHash(CacheId)
|
||||||
|
* because we need to serialize it and unserialize it to a config file,
|
||||||
|
* which is more efficient to do that with the uint directly rather than a CacheId struct serialization
|
||||||
|
*/
|
||||||
|
QHash<uint, QRectF> m_localRectCache;
|
||||||
|
QHash<QString, QSet<unsigned int>> m_invalidElements;
|
||||||
|
QHash<QString, QList<QSize>> m_sizeHintsForId;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint qHash(const Plasma::SvgPrivate::CacheId &id, uint seed = 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "theme_p.h"
|
#include "theme_p.h"
|
||||||
#include "framesvg.h"
|
#include "framesvg.h"
|
||||||
#include "framesvg_p.h"
|
#include "framesvg_p.h"
|
||||||
|
#include "svg_p.h"
|
||||||
#include "debug_p.h"
|
#include "debug_p.h"
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
@ -75,12 +76,6 @@ ThemePrivate::ThemePrivate(QObject *parent)
|
|||||||
pixmapSaveTimer->setInterval(600);
|
pixmapSaveTimer->setInterval(600);
|
||||||
QObject::connect(pixmapSaveTimer, &QTimer::timeout, this, &ThemePrivate::scheduledCacheUpdate);
|
QObject::connect(pixmapSaveTimer, &QTimer::timeout, this, &ThemePrivate::scheduledCacheUpdate);
|
||||||
|
|
||||||
rectSaveTimer = new QTimer(this);
|
|
||||||
rectSaveTimer->setSingleShot(true);
|
|
||||||
//2 minutes
|
|
||||||
rectSaveTimer->setInterval(2 * 60 * 1000);
|
|
||||||
QObject::connect(rectSaveTimer, &QTimer::timeout, this, &ThemePrivate::saveSvgElementsCache);
|
|
||||||
|
|
||||||
updateNotificationTimer = new QTimer(this);
|
updateNotificationTimer = new QTimer(this);
|
||||||
updateNotificationTimer->setSingleShot(true);
|
updateNotificationTimer->setSingleShot(true);
|
||||||
updateNotificationTimer->setInterval(100);
|
updateNotificationTimer->setInterval(100);
|
||||||
@ -121,7 +116,6 @@ ThemePrivate::ThemePrivate(QObject *parent)
|
|||||||
|
|
||||||
ThemePrivate::~ThemePrivate()
|
ThemePrivate::~ThemePrivate()
|
||||||
{
|
{
|
||||||
saveSvgElementsCache();
|
|
||||||
FrameSvgPrivate::s_sharedFrames.remove(this);
|
FrameSvgPrivate::s_sharedFrames.remove(this);
|
||||||
delete pixmapCache;
|
delete pixmapCache;
|
||||||
}
|
}
|
||||||
@ -239,43 +233,24 @@ bool ThemePrivate::useCache()
|
|||||||
|
|
||||||
ThemeConfig config;
|
ThemeConfig config;
|
||||||
pixmapCache = new KImageCache(cacheFile, config.themeCacheKb() * 1024);
|
pixmapCache = new KImageCache(cacheFile, config.themeCacheKb() * 1024);
|
||||||
|
pixmapCache->setEvictionPolicy(KSharedDataCache::EvictLeastRecentlyUsed);
|
||||||
|
|
||||||
if (cachesTooOld) {
|
if (cachesTooOld) {
|
||||||
discardCache(PixmapCache | SvgElementsCache);
|
discardCache(PixmapCache | SvgElementsCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cacheTheme && !svgElementsCache) {
|
if (cacheTheme) {
|
||||||
const QString svgElementsFileNameBase = QLatin1String("plasma-svgelements-") + themeName;
|
|
||||||
QString svgElementsFileName = svgElementsFileNameBase;
|
|
||||||
if (!themeVersion.isEmpty()) {
|
|
||||||
svgElementsFileName += QLatin1String("_v") + themeVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now we check for (and remove) old caches
|
|
||||||
QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
|
|
||||||
cacheDir.setNameFilters(QStringList({svgElementsFileNameBase + QLatin1Char('*')}));
|
|
||||||
|
|
||||||
const auto files = cacheDir.entryInfoList();
|
|
||||||
for (const QFileInfo &file : files) {
|
|
||||||
if (!file.absoluteFilePath().endsWith(svgElementsFileName)) {
|
|
||||||
QFile::remove(file.absoluteFilePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString svgElementsFile = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1Char('/') + svgElementsFileName;
|
|
||||||
svgElementsCache = KSharedConfig::openConfig(svgElementsFile, KConfig::SimpleConfig);
|
|
||||||
QString currentIconThemePath;
|
QString currentIconThemePath;
|
||||||
const auto *iconTheme = KIconLoader::global()->theme();
|
const auto *iconTheme = KIconLoader::global()->theme();
|
||||||
if (iconTheme) {
|
if (iconTheme) {
|
||||||
currentIconThemePath = iconTheme->dir();
|
currentIconThemePath = iconTheme->dir();
|
||||||
}
|
}
|
||||||
KConfigGroup globalGroup(svgElementsCache, QLatin1String("Global"));
|
|
||||||
const QString oldIconThemePath = globalGroup.readEntry("currentIconThemePath", QString());
|
const QString oldIconThemePath = SvgRectsCache::instance()->iconThemePath();
|
||||||
if (oldIconThemePath != currentIconThemePath) {
|
if (oldIconThemePath != currentIconThemePath) {
|
||||||
discardCache(PixmapCache | SvgElementsCache);
|
discardCache(PixmapCache | SvgElementsCache);
|
||||||
globalGroup.writeEntry("currentIconThemePath", currentIconThemePath);
|
SvgRectsCache::instance()->setIconThemePath(currentIconThemePath);
|
||||||
svgElementsCache = KSharedConfig::openConfig(svgElementsFile, KConfig::SimpleConfig);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,9 +332,6 @@ void ThemePrivate::discardCache(CacheTypes caches)
|
|||||||
|
|
||||||
if (caches & SvgElementsCache) {
|
if (caches & SvgElementsCache) {
|
||||||
discoveries.clear();
|
discoveries.clear();
|
||||||
invalidElements.clear();
|
|
||||||
|
|
||||||
svgElementsCache = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,21 +629,6 @@ void ThemePrivate::settingsChanged(bool emitChanges)
|
|||||||
setThemeName(cg.readEntry("name", ThemePrivate::defaultTheme), false, emitChanges);
|
setThemeName(cg.readEntry("name", ThemePrivate::defaultTheme), false, emitChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemePrivate::saveSvgElementsCache()
|
|
||||||
{
|
|
||||||
if (svgElementsCache) {
|
|
||||||
QHashIterator<QString, QSet<QString> > it(invalidElements);
|
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
KConfigGroup imageGroup(svgElementsCache, it.key());
|
|
||||||
imageGroup.writeEntry("invalidElements", it.value().values()); //FIXME: add QSet support to KConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
//Pretty drastic, but this is executed only very rarely
|
|
||||||
svgElementsCache->sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor ThemePrivate::color(Theme::ColorRole role, Theme::ColorGroup group) const
|
QColor ThemePrivate::color(Theme::ColorRole role, Theme::ColorGroup group) const
|
||||||
{
|
{
|
||||||
const KColorScheme *scheme = nullptr;
|
const KColorScheme *scheme = nullptr;
|
||||||
|
@ -78,7 +78,6 @@ public Q_SLOTS:
|
|||||||
void onAppExitCleanup();
|
void onAppExitCleanup();
|
||||||
void notifyOfChanged();
|
void notifyOfChanged();
|
||||||
void settingsChanged(bool emitChanges);
|
void settingsChanged(bool emitChanges);
|
||||||
void saveSvgElementsCache();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void themeChanged();
|
void themeChanged();
|
||||||
@ -116,9 +115,7 @@ public:
|
|||||||
int defaultWallpaperWidth;
|
int defaultWallpaperWidth;
|
||||||
int defaultWallpaperHeight;
|
int defaultWallpaperHeight;
|
||||||
KImageCache *pixmapCache;
|
KImageCache *pixmapCache;
|
||||||
KSharedConfigPtr svgElementsCache;
|
|
||||||
QString cachedDefaultStyleSheet;
|
QString cachedDefaultStyleSheet;
|
||||||
QHash<QString, QSet<QString> > invalidElements;
|
|
||||||
QHash<QString, QPixmap> pixmapsToCache;
|
QHash<QString, QPixmap> pixmapsToCache;
|
||||||
QHash<QString, QString> keysToCache;
|
QHash<QString, QString> keysToCache;
|
||||||
QHash<QString, QString> idsToCache;
|
QHash<QString, QString> idsToCache;
|
||||||
@ -126,7 +123,6 @@ public:
|
|||||||
QHash<Theme::ColorGroup, QString> cachedSelectedSvgStyleSheets;
|
QHash<Theme::ColorGroup, QString> cachedSelectedSvgStyleSheets;
|
||||||
QHash<QString, QString> discoveries;
|
QHash<QString, QString> discoveries;
|
||||||
QTimer *pixmapSaveTimer;
|
QTimer *pixmapSaveTimer;
|
||||||
QTimer *rectSaveTimer;
|
|
||||||
QTimer *updateNotificationTimer;
|
QTimer *updateNotificationTimer;
|
||||||
unsigned cacheSize;
|
unsigned cacheSize;
|
||||||
CacheTypes cachesToDiscard;
|
CacheTypes cachesToDiscard;
|
||||||
|
@ -34,9 +34,36 @@
|
|||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "debug_p.h"
|
#include "debug_p.h"
|
||||||
|
|
||||||
|
uint qHash(const Plasma::SvgPrivate::CacheId &id, uint seed)
|
||||||
|
{
|
||||||
|
std::array<uint, 10> parts = {
|
||||||
|
::qHash(id.width),
|
||||||
|
::qHash(id.height),
|
||||||
|
::qHash(id.elementName),
|
||||||
|
::qHash(id.filePath),
|
||||||
|
::qHash(id.status),
|
||||||
|
::qHash(id.devicePixelRatio),
|
||||||
|
::qHash(id.scaleFactor),
|
||||||
|
::qHash(id.colorGroup),
|
||||||
|
::qHash(id.extraFlags),
|
||||||
|
::qHash(id.lastModified)
|
||||||
|
};
|
||||||
|
return qHashRange(parts.begin(), parts.end(), seed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Plasma
|
namespace Plasma
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class SvgRectsCacheSingleton
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SvgRectsCache self;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_GLOBAL_STATIC(SvgRectsCacheSingleton, privateSvgRectsCacheSelf)
|
||||||
|
|
||||||
|
const uint SvgRectsCache::s_seed = 0x9e3779b9;
|
||||||
|
|
||||||
SharedSvgRenderer::SharedSvgRenderer(QObject *parent)
|
SharedSvgRenderer::SharedSvgRenderer(QObject *parent)
|
||||||
: QSvgRenderer(parent)
|
: QSvgRenderer(parent)
|
||||||
@ -123,9 +150,217 @@ bool SharedSvgRenderer::load(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define QLSEP QLatin1Char('_')
|
SvgRectsCache::SvgRectsCache(QObject *parent)
|
||||||
#define CACHE_ID_WITH_SIZE(size, id, status, devicePixelRatio) QString::number(int(size.width())) % QLSEP % QString::number(int(size.height())) % QLSEP % id % QLSEP % QString::number(status) % QLSEP % QString::number(devicePixelRatio)
|
: QObject(parent)
|
||||||
#define CACHE_ID_NATURAL_SIZE(id, status, devicePixelRatio) QLatin1String("Natural") % QLSEP % id % QLSEP % QString::number(status) % QLSEP % QString::number(devicePixelRatio)
|
{
|
||||||
|
const QString svgElementsFile = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1Char('/') + QStringLiteral("plasma-svgelements");
|
||||||
|
m_svgElementsCache = KSharedConfig::openConfig(svgElementsFile, KConfig::SimpleConfig);
|
||||||
|
|
||||||
|
m_configSyncTimer = new QTimer(this);
|
||||||
|
m_configSyncTimer->setSingleShot(true);
|
||||||
|
m_configSyncTimer->setInterval(5000);
|
||||||
|
connect(m_configSyncTimer, &QTimer::timeout,
|
||||||
|
this, [this]() {
|
||||||
|
m_svgElementsCache->sync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SvgRectsCache *SvgRectsCache::instance()
|
||||||
|
{
|
||||||
|
return &privateSvgRectsCacheSelf()->self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::insert(Plasma::SvgPrivate::CacheId cacheId, const QRectF &rect, unsigned int lastModified)
|
||||||
|
{
|
||||||
|
insert(qHash(cacheId, SvgRectsCache::s_seed), cacheId.filePath, rect, lastModified);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::insert(uint id, const QString &filePath, const QRectF &rect, unsigned int lastModified)
|
||||||
|
{
|
||||||
|
if (m_localRectCache.contains(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_localRectCache.insert(id, rect);
|
||||||
|
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, filePath);
|
||||||
|
imageGroup.writeEntry("LastModified", lastModified);
|
||||||
|
if (rect.isValid()) {
|
||||||
|
imageGroup.writeEntry(QString::number(id), rect);
|
||||||
|
} else {
|
||||||
|
m_invalidElements[filePath] << id;
|
||||||
|
imageGroup.writeEntry("Invalidelements", m_invalidElements[filePath].values());
|
||||||
|
}
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SvgRectsCache::findElementRect(Plasma::SvgPrivate::CacheId cacheId, QRectF &rect)
|
||||||
|
{
|
||||||
|
return findElementRect(qHash(cacheId, SvgRectsCache::s_seed), cacheId.filePath, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SvgRectsCache::findElementRect(uint id, const QString &filePath, QRectF &rect)
|
||||||
|
{
|
||||||
|
auto it = m_localRectCache.find(id);
|
||||||
|
|
||||||
|
if (it == m_localRectCache.end()) {
|
||||||
|
if (m_invalidElements.contains(filePath) && m_invalidElements[filePath].contains(id)) {
|
||||||
|
rect = QRectF();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect = *it;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::loadImageFromCache(const QString &path, uint lastModified)
|
||||||
|
{
|
||||||
|
if (path.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
|
||||||
|
unsigned int savedTime = imageGroup.readEntry("LastModified", 0);
|
||||||
|
|
||||||
|
if (lastModified > savedTime) {
|
||||||
|
imageGroup.deleteGroup();
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto list = imageGroup.readEntry("Invalidelements", QList<unsigned int>());
|
||||||
|
m_invalidElements[path] = QSet<unsigned int>(list.begin(), list.end());
|
||||||
|
|
||||||
|
for (const auto &key : imageGroup.keyList()) {
|
||||||
|
bool ok = false;
|
||||||
|
if (ok) {
|
||||||
|
const QRectF rect = imageGroup.readEntry(key, QRectF());
|
||||||
|
m_localRectCache.insert(key.toUInt(), rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::dropImageFromCache(const QString &path)
|
||||||
|
{
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
imageGroup.deleteGroup();
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QSize> SvgRectsCache::sizeHintsForId(const QString &path, const QString &id)
|
||||||
|
{
|
||||||
|
const QString pathId = path % id;
|
||||||
|
|
||||||
|
if (!m_sizeHintsForId.contains(pathId)) {
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
const QStringList &encoded = imageGroup.readEntry(id, QStringList());
|
||||||
|
QList<QSize> sizes;
|
||||||
|
for (const auto &token : encoded) {
|
||||||
|
const auto &parts = token.split(QLatin1Char('x'));
|
||||||
|
if (parts.size() != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
QSize size = QSize(parts[0].toDouble(), parts[1].toDouble());
|
||||||
|
if (!size.isEmpty()) {
|
||||||
|
sizes << size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_sizeHintsForId[pathId] = sizes;
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_sizeHintsForId.value(pathId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::insertSizeHintForId(const QString &path, const QString &id, const QSize &size)
|
||||||
|
{
|
||||||
|
//TODO: need to make this more efficient
|
||||||
|
auto sizeListToString = [] (const QList<QSize> &list) {
|
||||||
|
QString ret;
|
||||||
|
for (const auto &s : list) {
|
||||||
|
ret += QString::number(s.width()) % QLatin1Char('x') % QString::number(s.height()) % QLatin1Char(',');
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
m_sizeHintsForId[path % id].append(size);
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
imageGroup.writeEntry(id, sizeListToString(m_sizeHintsForId[path % id]));
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SvgRectsCache::iconThemePath()
|
||||||
|
{
|
||||||
|
if (!m_iconThemePath.isEmpty()) {
|
||||||
|
return m_iconThemePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, QStringLiteral("General"));
|
||||||
|
m_iconThemePath = imageGroup.readEntry(QStringLiteral("IconThemePath"), QString());
|
||||||
|
|
||||||
|
return m_iconThemePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::setIconThemePath(const QString &path)
|
||||||
|
{
|
||||||
|
m_iconThemePath = path;
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, QStringLiteral("General"));
|
||||||
|
imageGroup.writeEntry(QStringLiteral("IconThemePath"), path);
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::expireCache(const QString &path)
|
||||||
|
{
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
|
||||||
|
unsigned int savedTime = imageGroup.readEntry("LastModified", QDateTime().toSecsSinceEpoch());
|
||||||
|
QFileInfo info(path);
|
||||||
|
if (info.exists()) {
|
||||||
|
unsigned int lastModified = info.lastModified().toSecsSinceEpoch();
|
||||||
|
if (lastModified <= savedTime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imageGroup.deleteGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::setNaturalSize(const QString &path, qreal scaleFactor, const QSizeF &size)
|
||||||
|
{
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
|
||||||
|
// FIXME: needs something faster, perhaps even sprintf
|
||||||
|
imageGroup.writeEntry(QStringLiteral("NaturalSize_") % QString::number(scaleFactor), size);
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF SvgRectsCache::naturalSize(const QString &path, qreal scaleFactor)
|
||||||
|
{
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
|
||||||
|
// FIXME: needs something faster, perhaps even sprintf
|
||||||
|
return imageGroup.readEntry(QStringLiteral("NaturalSize_") % QString::number(scaleFactor), QSizeF());
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList SvgRectsCache::cachedKeysForPath(const QString &path) const
|
||||||
|
{
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, path);
|
||||||
|
QStringList list = imageGroup.keyList();
|
||||||
|
QStringList filtered;
|
||||||
|
|
||||||
|
std::copy_if (list.begin(), list.end(), std::back_inserter(filtered), [](const QString element){bool ok; element.toLong(&ok); return ok;} );
|
||||||
|
return filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgRectsCache::updateLastModified(const QString &filePath, unsigned int lastModified)
|
||||||
|
{
|
||||||
|
KConfigGroup imageGroup(m_svgElementsCache, filePath);
|
||||||
|
imageGroup.writeEntry("LastModified", lastModified);
|
||||||
|
m_configSyncTimer->start();
|
||||||
|
}
|
||||||
|
|
||||||
SvgPrivate::SvgPrivate(Svg *svg)
|
SvgPrivate::SvgPrivate(Svg *svg)
|
||||||
: q(svg),
|
: q(svg),
|
||||||
@ -153,19 +388,17 @@ SvgPrivate::~SvgPrivate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//This function is meant for the rects cache
|
//This function is meant for the rects cache
|
||||||
QString SvgPrivate::cacheId(const QString &elementId) const
|
SvgPrivate::CacheId SvgPrivate::cacheId(const QString &elementId) const
|
||||||
{
|
{
|
||||||
if (size.isValid() && size != naturalSize) {
|
auto idSize = size.isValid() && size != naturalSize ? size : QSizeF{-1.0, -1.0};
|
||||||
return CACHE_ID_WITH_SIZE(size, elementId, status, devicePixelRatio);
|
return CacheId{idSize.width(), idSize.height(), path, elementId, status, devicePixelRatio, scaleFactor, -1, 0, lastModified};
|
||||||
} else {
|
|
||||||
return CACHE_ID_NATURAL_SIZE(elementId, status, devicePixelRatio);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function is meant for the pixmap cache
|
//This function is meant for the pixmap cache
|
||||||
QString SvgPrivate::cachePath(const QString &path, const QSize &size) const
|
QString SvgPrivate::cachePath(const QString &id, const QSize &size) const
|
||||||
{
|
{
|
||||||
return CACHE_ID_WITH_SIZE(size, path, status, devicePixelRatio) % QLSEP % QString::number(colorGroup);
|
auto cacheId = CacheId{double(size.width()), double(size.height()), path, id, status, devicePixelRatio, scaleFactor, colorGroup, 0, lastModified};
|
||||||
|
return QString::number(qHash(cacheId, SvgRectsCache::s_seed));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SvgPrivate::setImagePath(const QString &imagePath)
|
bool SvgPrivate::setImagePath(const QString &imagePath)
|
||||||
@ -207,8 +440,7 @@ bool SvgPrivate::setImagePath(const QString &imagePath)
|
|||||||
themed = isThemed;
|
themed = isThemed;
|
||||||
path.clear();
|
path.clear();
|
||||||
themePath.clear();
|
themePath.clear();
|
||||||
localRectCache.clear();
|
|
||||||
elementsWithSizeHints.clear();
|
|
||||||
bool oldFromCurrentTheme = fromCurrentTheme;
|
bool oldFromCurrentTheme = fromCurrentTheme;
|
||||||
fromCurrentTheme = !inIconTheme && isThemed && actualTheme()->currentThemeHasImage(imagePath);
|
fromCurrentTheme = !inIconTheme && isThemed && actualTheme()->currentThemeHasImage(imagePath);
|
||||||
|
|
||||||
@ -234,6 +466,12 @@ bool SvgPrivate::setImagePath(const QString &imagePath)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QFileInfo info(path);
|
||||||
|
|
||||||
|
lastModified = info.lastModified().toSecsSinceEpoch();
|
||||||
|
|
||||||
|
SvgRectsCache::instance()->loadImageFromCache(path, lastModified);
|
||||||
|
|
||||||
// check if svg wants colorscheme applied
|
// check if svg wants colorscheme applied
|
||||||
checkColorHints();
|
checkColorHints();
|
||||||
|
|
||||||
@ -242,20 +480,14 @@ bool SvgPrivate::setImagePath(const QString &imagePath)
|
|||||||
if ((themed && !path.isEmpty() && QFileInfo::exists(path)) || QFileInfo::exists(actualPath)) {
|
if ((themed && !path.isEmpty() && QFileInfo::exists(path)) || QFileInfo::exists(actualPath)) {
|
||||||
QRectF rect;
|
QRectF rect;
|
||||||
|
|
||||||
if (cacheAndColorsTheme()->findInRectsCache(path, QStringLiteral("_Natural_%1").arg(scaleFactor), rect)) {
|
naturalSize = SvgRectsCache::instance()->naturalSize(path, scaleFactor);
|
||||||
naturalSize = rect.size();
|
if (naturalSize.isEmpty()) {
|
||||||
} else {
|
|
||||||
createRenderer();
|
createRenderer();
|
||||||
naturalSize = renderer->defaultSize() * scaleFactor;
|
naturalSize = renderer->defaultSize() * scaleFactor;
|
||||||
//qCDebug(LOG_PLASMA) << "natural size for" << path << "from renderer is" << naturalSize;
|
SvgRectsCache::instance()->setNaturalSize(path, scaleFactor, naturalSize);
|
||||||
cacheAndColorsTheme()->insertIntoRectsCache(path, QStringLiteral("_Natural_%1").arg(scaleFactor), QRectF(QPointF(0, 0), naturalSize));
|
|
||||||
//qCDebug(LOG_PLASMA) << "natural size for" << path << "from cache is" << naturalSize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFileInfo info(path);
|
|
||||||
lastModified = info.lastModified().toSecsSinceEpoch();
|
|
||||||
|
|
||||||
q->resize();
|
q->resize();
|
||||||
emit q->imagePathChanged();
|
emit q->imagePathChanged();
|
||||||
|
|
||||||
@ -291,39 +523,15 @@ QPixmap SvgPrivate::findInCache(const QString &elementId, qreal ratio, const QSi
|
|||||||
QSize size;
|
QSize size;
|
||||||
QString actualElementId;
|
QString actualElementId;
|
||||||
|
|
||||||
if (elementsWithSizeHints.isEmpty()) {
|
|
||||||
// Fetch all size hinted element ids from the theme's rect cache
|
|
||||||
// and store them locally.
|
|
||||||
const QRegularExpression sizeHintedKeyExpr(QLatin1String("^") + CACHE_ID_NATURAL_SIZE(QStringLiteral("(\\d+)-(\\d+)-(.+)"), status, ratio) + QLatin1String("$"));
|
|
||||||
|
|
||||||
const auto lst = cacheAndColorsTheme()->listCachedRectKeys(path);
|
|
||||||
for (const QString &key : lst) {
|
|
||||||
const auto match = sizeHintedKeyExpr.match(key);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
QString baseElementId = match.captured(3);
|
|
||||||
QSize sizeHint(match.capturedRef(1).toInt(),
|
|
||||||
match.capturedRef(2).toInt());
|
|
||||||
if (sizeHint.isValid()) {
|
|
||||||
elementsWithSizeHints.insert(baseElementId, sizeHint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elementsWithSizeHints.isEmpty()) {
|
|
||||||
// Make sure we won't query the theme unnecessarily.
|
|
||||||
elementsWithSizeHints.insert(QString(), QSize());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look at the size hinted elements and try to find the smallest one with an
|
// Look at the size hinted elements and try to find the smallest one with an
|
||||||
// identical aspect ratio.
|
// identical aspect ratio.
|
||||||
if (s.isValid() && !elementId.isEmpty()) {
|
if (s.isValid() && !elementId.isEmpty()) {
|
||||||
const QList<QSize> elementSizeHints = elementsWithSizeHints.values(elementId);
|
const QList<QSize> elementSizeHints = SvgRectsCache::instance()->sizeHintsForId(path, elementId);
|
||||||
|
|
||||||
if (!elementSizeHints.isEmpty()) {
|
if (!elementSizeHints.isEmpty()) {
|
||||||
QSize bestFit(-1, -1);
|
QSizeF bestFit(-1, -1);
|
||||||
|
|
||||||
for (const QSize &hint : elementSizeHints) {
|
for (const auto &hint : elementSizeHints) {
|
||||||
|
|
||||||
if (hint.width() >= s.width() * ratio && hint.height() >= s.height() * ratio &&
|
if (hint.width() >= s.width() * ratio && hint.height() >= s.height() * ratio &&
|
||||||
(!bestFit.isValid() ||
|
(!bestFit.isValid() ||
|
||||||
@ -353,9 +561,7 @@ QPixmap SvgPrivate::findInCache(const QString &elementId, qreal ratio, const QSi
|
|||||||
return QPixmap();
|
return QPixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString id = cachePath(path, size) + actualElementId;
|
const QString id = cachePath(actualElementId, size);
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA) << "id is " << id;
|
|
||||||
|
|
||||||
QPixmap p;
|
QPixmap p;
|
||||||
if (cacheRendering && cacheAndColorsTheme()->findInCache(id, p, lastModified)) {
|
if (cacheRendering && cacheAndColorsTheme()->findInCache(id, p, lastModified)) {
|
||||||
@ -364,11 +570,6 @@ QPixmap SvgPrivate::findInCache(const QString &elementId, qreal ratio, const QSi
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA) << "didn't find cached version of " << id << ", so re-rendering";
|
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA) << "size for " << actualElementId << " is " << s;
|
|
||||||
// we have to re-render this puppy
|
|
||||||
|
|
||||||
createRenderer();
|
createRenderer();
|
||||||
|
|
||||||
QRectF finalRect = makeUniform(renderer->boundsOnElement(actualElementId), QRect(QPoint(0, 0), size));
|
QRectF finalRect = makeUniform(renderer->boundsOnElement(actualElementId), QRect(QPoint(0, 0), size));
|
||||||
@ -397,9 +598,11 @@ QPixmap SvgPrivate::findInCache(const QString &elementId, qreal ratio, const QSi
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cacheRendering) {
|
if (cacheRendering) {
|
||||||
cacheAndColorsTheme()->insertIntoCache(id, p, QString::number((qint64)q, 16) % QLSEP % actualElementId);
|
cacheAndColorsTheme()->insertIntoCache(id, p, QString::number((qint64)q, 16) % QLatin1Char('_') % actualElementId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SvgRectsCache::instance()->updateLastModified(path, lastModified);
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +612,6 @@ void SvgPrivate::createRenderer()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA) << kBacktrace();
|
|
||||||
if (themed && path.isEmpty() && !themeFailed) {
|
if (themed && path.isEmpty() && !themeFailed) {
|
||||||
Applet *applet = qobject_cast<Applet *>(q->parent());
|
Applet *applet = qobject_cast<Applet *>(q->parent());
|
||||||
//FIXME: this maybe could be more efficient if we knew if the package was empty, e.g. for
|
//FIXME: this maybe could be more efficient if we knew if the package was empty, e.g. for
|
||||||
@ -433,17 +635,12 @@ void SvgPrivate::createRenderer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA) << "********************************";
|
|
||||||
//qCDebug(LOG_PLASMA) << "FAIL! **************************";
|
|
||||||
//qCDebug(LOG_PLASMA) << path << "**";
|
|
||||||
|
|
||||||
QString styleSheet = cacheAndColorsTheme()->d->svgStyleSheet(colorGroup, status);
|
QString styleSheet = cacheAndColorsTheme()->d->svgStyleSheet(colorGroup, status);
|
||||||
styleCrc = qChecksum(styleSheet.toUtf8().constData(), styleSheet.size());
|
styleCrc = qChecksum(styleSheet.toUtf8().constData(), styleSheet.size());
|
||||||
|
|
||||||
QHash<QString, SharedSvgRenderer::Ptr>::const_iterator it = s_renderers.constFind(styleCrc + path);
|
QHash<QString, SharedSvgRenderer::Ptr>::const_iterator it = s_renderers.constFind(styleCrc + path);
|
||||||
|
|
||||||
if (it != s_renderers.constEnd()) {
|
if (it != s_renderers.constEnd()) {
|
||||||
//qCDebug(LOG_PLASMA) << "gots us an existing one!";
|
|
||||||
renderer = it.value();
|
renderer = it.value();
|
||||||
} else {
|
} else {
|
||||||
if (path.isEmpty()) {
|
if (path.isEmpty()) {
|
||||||
@ -455,14 +652,19 @@ void SvgPrivate::createRenderer()
|
|||||||
// Add interesting elements to the theme's rect cache.
|
// Add interesting elements to the theme's rect cache.
|
||||||
QHashIterator<QString, QRectF> i(interestingElements);
|
QHashIterator<QString, QRectF> i(interestingElements);
|
||||||
|
|
||||||
|
QRegularExpression sizeHintedKeyExpr(QStringLiteral("^(\\d+)-(\\d+)-(.+)$"));
|
||||||
|
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
const QString &elementId = i.key();
|
const QString &elementId = i.key();
|
||||||
|
QString originalId = i.key();
|
||||||
const QRectF &elementRect = i.value();
|
const QRectF &elementRect = i.value();
|
||||||
|
|
||||||
const QString cacheId = CACHE_ID_NATURAL_SIZE(elementId, status, devicePixelRatio);
|
originalId.replace(sizeHintedKeyExpr, QStringLiteral("\\3"));
|
||||||
localRectCache.insert(cacheId, elementRect);
|
SvgRectsCache::instance()->insertSizeHintForId(path, originalId, elementRect.size().toSize());
|
||||||
cacheAndColorsTheme()->insertIntoRectsCache(path, cacheId, elementRect);
|
|
||||||
|
const CacheId cacheId({-1.0, -1.0, path, elementId, status, devicePixelRatio, scaleFactor, -1, 0, lastModified});
|
||||||
|
SvgRectsCache::instance()->insert(cacheId, elementRect, lastModified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,16 +686,10 @@ void SvgPrivate::eraseRenderer()
|
|||||||
#endif
|
#endif
|
||||||
// this and the cache reference it
|
// this and the cache reference it
|
||||||
s_renderers.erase(s_renderers.find(styleCrc + path));
|
s_renderers.erase(s_renderers.find(styleCrc + path));
|
||||||
|
|
||||||
if (theme) {
|
|
||||||
theme.data()->releaseRectsCache(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer = nullptr;
|
renderer = nullptr;
|
||||||
styleCrc = 0;
|
styleCrc = 0;
|
||||||
localRectCache.clear();
|
|
||||||
elementsWithSizeHints.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF SvgPrivate::elementRect(const QString &elementId)
|
QRectF SvgPrivate::elementRect(const QString &elementId)
|
||||||
@ -515,35 +711,23 @@ QRectF SvgPrivate::elementRect(const QString &elementId)
|
|||||||
return QRectF();
|
return QRectF();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString id = cacheId(elementId);
|
|
||||||
const auto it = localRectCache.constFind(id);
|
|
||||||
if (it != localRectCache.constEnd()) {
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF rect;
|
QRectF rect;
|
||||||
bool found = cacheAndColorsTheme()->findInRectsCache(path, id, rect);
|
const CacheId cacheId = SvgPrivate::cacheId(elementId);
|
||||||
|
bool found = SvgRectsCache::instance()->findElementRect(cacheId, rect);
|
||||||
//This is a corner case where we are *sure* the element is not valid
|
//This is a corner case where we are *sure* the element is not valid
|
||||||
if (found && rect == QRectF()) {
|
if (!found) {
|
||||||
return rect;
|
rect = findAndCacheElementRect(elementId);
|
||||||
} else if (found) {
|
|
||||||
localRectCache.insert(id, rect);
|
|
||||||
} else {
|
|
||||||
rect = findAndCacheElementRect(elementId, id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF SvgPrivate::findAndCacheElementRect(const QString &elementId, const QString &id)
|
QRectF SvgPrivate::findAndCacheElementRect(const QString &elementId)
|
||||||
{
|
{
|
||||||
//we need to check the id before createRenderer(), otherwise it may generate a different id compared to the previous cacheId)( call
|
//we need to check the id before createRenderer(), otherwise it may generate a different id compared to the previous cacheId)( call
|
||||||
createRenderer();
|
const CacheId cacheId = SvgPrivate::cacheId(elementId);
|
||||||
|
|
||||||
const auto it = localRectCache.constFind(id);
|
createRenderer();
|
||||||
if (it != localRectCache.constEnd()) {
|
|
||||||
return *it;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This code will usually never be run because createRenderer already caches all the boundingRect in the elements in the svg
|
//This code will usually never be run because createRenderer already caches all the boundingRect in the elements in the svg
|
||||||
QRectF elementRect = renderer->elementExists(elementId) ?
|
QRectF elementRect = renderer->elementExists(elementId) ?
|
||||||
@ -560,9 +744,7 @@ QRectF SvgPrivate::findAndCacheElementRect(const QString &elementId, const QStri
|
|||||||
|
|
||||||
elementRect = QRectF(elementRect.x() * dx, elementRect.y() * dy,
|
elementRect = QRectF(elementRect.x() * dx, elementRect.y() * dy,
|
||||||
elementRect.width() * dx, elementRect.height() * dy);
|
elementRect.width() * dx, elementRect.height() * dy);
|
||||||
|
SvgRectsCache::instance()->insert(cacheId, elementRect, lastModified);
|
||||||
cacheAndColorsTheme()->insertIntoRectsCache(path, id, elementRect);
|
|
||||||
localRectCache.insert(id, elementRect);
|
|
||||||
|
|
||||||
return elementRect;
|
return elementRect;
|
||||||
}
|
}
|
||||||
@ -642,7 +824,6 @@ QRectF SvgPrivate::makeUniform(const QRectF &orig, const QRectF &dst)
|
|||||||
res.setHeight(res.height() + offset);
|
res.setHeight(res.height() + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
//qCDebug(LOG_PLASMA)<<"Aligning Rects, origin:"<<orig<<"destination:"<<dst<<"result:"<<res;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,9 +913,8 @@ void Svg::setScaleFactor(qreal ratio)
|
|||||||
//not resize() because we want to do it unconditionally
|
//not resize() because we want to do it unconditionally
|
||||||
QRectF rect;
|
QRectF rect;
|
||||||
|
|
||||||
if (d->cacheAndColorsTheme()->findInRectsCache(d->path, QStringLiteral("_Natural_%1").arg(d->scaleFactor), rect)) {
|
d->naturalSize = SvgRectsCache::instance()->naturalSize(d->path, d->scaleFactor);
|
||||||
d->naturalSize = rect.size();
|
if (d->naturalSize.isEmpty()) {
|
||||||
} else {
|
|
||||||
d->createRenderer();
|
d->createRenderer();
|
||||||
d->naturalSize = d->renderer->defaultSize() * d->scaleFactor;
|
d->naturalSize = d->renderer->defaultSize() * d->scaleFactor;
|
||||||
}
|
}
|
||||||
@ -840,7 +1020,6 @@ void Svg::resize(const QSizeF &size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->size = size;
|
d->size = size;
|
||||||
d->localRectCache.clear();
|
|
||||||
emit sizeChanged();
|
emit sizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,7 +1031,6 @@ void Svg::resize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
d->size = d->naturalSize;
|
d->size = d->naturalSize;
|
||||||
d->localRectCache.clear();
|
|
||||||
emit sizeChanged();
|
emit sizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -883,14 +1061,14 @@ bool Svg::isValid() const
|
|||||||
|
|
||||||
//try very hard to avoid creation of a parser
|
//try very hard to avoid creation of a parser
|
||||||
QRectF rect;
|
QRectF rect;
|
||||||
if (d->cacheAndColorsTheme()->findInRectsCache(d->path, QStringLiteral("_Natural_%1").arg(d->scaleFactor), rect)) {
|
QSizeF naturalSize = SvgRectsCache::instance()->naturalSize(d->path, d->scaleFactor);
|
||||||
|
if (!naturalSize.isEmpty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->path.isEmpty() || !QFileInfo::exists(d->path)) {
|
if (d->path.isEmpty() || !QFileInfo::exists(d->path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->createRenderer();
|
d->createRenderer();
|
||||||
return d->renderer->isValid();
|
return d->renderer->isValid();
|
||||||
}
|
}
|
||||||
@ -908,7 +1086,6 @@ bool Svg::containsMultipleImages() const
|
|||||||
void Svg::setImagePath(const QString &svgFilePath)
|
void Svg::setImagePath(const QString &svgFilePath)
|
||||||
{
|
{
|
||||||
if (d->setImagePath(svgFilePath)) {
|
if (d->setImagePath(svgFilePath)) {
|
||||||
//qCDebug(LOG_PLASMA) << "repaintNeeded";
|
|
||||||
emit repaintNeeded();
|
emit repaintNeeded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "private/theme_p.h"
|
#include "private/theme_p.h"
|
||||||
|
#include "private/svg_p.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
@ -38,11 +39,11 @@ Theme::Theme(QObject *parent)
|
|||||||
{
|
{
|
||||||
if (!ThemePrivate::globalTheme) {
|
if (!ThemePrivate::globalTheme) {
|
||||||
ThemePrivate::globalTheme = new ThemePrivate;
|
ThemePrivate::globalTheme = new ThemePrivate;
|
||||||
|
ThemePrivate::globalTheme->settingsChanged(false);
|
||||||
}
|
}
|
||||||
ThemePrivate::globalTheme->ref.ref();
|
ThemePrivate::globalTheme->ref.ref();
|
||||||
d = ThemePrivate::globalTheme;
|
d = ThemePrivate::globalTheme;
|
||||||
|
|
||||||
d->settingsChanged(false);
|
|
||||||
if (QCoreApplication::instance()) {
|
if (QCoreApplication::instance()) {
|
||||||
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||||
d, &ThemePrivate::onAppExitCleanup);
|
d, &ThemePrivate::onAppExitCleanup);
|
||||||
@ -335,36 +336,13 @@ bool Theme::findInRectsCache(const QString &image, const QString &element, QRect
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
KConfigGroup imageGroup(d->svgElementsCache, image);
|
bool ok = false;
|
||||||
rect = imageGroup.readEntry(element % QLatin1String("Size"), QRectF());
|
uint id = element.toLong(&ok);
|
||||||
|
if (!ok) {
|
||||||
if (rect.isValid()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Name starting by _ means the element is empty and we're asked for the size of
|
|
||||||
//the whole image, so the whole image is never invalid
|
|
||||||
if (element.indexOf(QLatin1Char('_')) <= 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool invalid = false;
|
return SvgRectsCache::instance()->findElementRect(id, image, rect);
|
||||||
|
|
||||||
QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
|
|
||||||
if (it == d->invalidElements.end()) {
|
|
||||||
const QStringList elementList = imageGroup.readEntry("invalidElements", QStringList());
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
|
||||||
const QSet<QString> elements(elementList.begin(), elementList.end());
|
|
||||||
#else
|
|
||||||
const QSet<QString> elements = elementList.toSet();
|
|
||||||
#endif
|
|
||||||
d->invalidElements.insert(image, elements);
|
|
||||||
invalid = elements.contains(element);
|
|
||||||
} else {
|
|
||||||
invalid = it.value().contains(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
return invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Theme::listCachedRectKeys(const QString &image) const
|
QStringList Theme::listCachedRectKeys(const QString &image) const
|
||||||
@ -373,21 +351,7 @@ QStringList Theme::listCachedRectKeys(const QString &image) const
|
|||||||
return QStringList();
|
return QStringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
KConfigGroup imageGroup(d->svgElementsCache, image);
|
return SvgRectsCache::instance()->cachedKeysForPath(image);
|
||||||
QStringList keys = imageGroup.keyList();
|
|
||||||
|
|
||||||
QMutableListIterator<QString> i(keys);
|
|
||||||
while (i.hasNext()) {
|
|
||||||
QString key = i.next();
|
|
||||||
if (key.endsWith(QLatin1String("Size"))) {
|
|
||||||
// The actual cache id used from outside doesn't end on "Size".
|
|
||||||
key.resize(key.size() - 4);
|
|
||||||
i.setValue(key);
|
|
||||||
} else {
|
|
||||||
i.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::insertIntoRectsCache(const QString &image, const QString &element, const QRectF &rect)
|
void Theme::insertIntoRectsCache(const QString &image, const QString &element, const QRectF &rect)
|
||||||
@ -396,46 +360,26 @@ void Theme::insertIntoRectsCache(const QString &image, const QString &element, c
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rect.isValid()) {
|
bool ok = false;
|
||||||
KConfigGroup imageGroup(d->svgElementsCache, image);
|
uint id = element.toLong(&ok);
|
||||||
imageGroup.writeEntry(element % QLatin1String("Size"), rect);
|
if (!ok) {
|
||||||
} else {
|
return;
|
||||||
QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
|
|
||||||
if (it == d->invalidElements.end()) {
|
|
||||||
d->invalidElements[image].insert(element);
|
|
||||||
} else if (!it.value().contains(element)) {
|
|
||||||
if (it.value().count() > 1000) {
|
|
||||||
it.value().erase(it.value().begin());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it.value().insert(element);
|
uint secs = QDateTime::currentSecsSinceEpoch();
|
||||||
}
|
SvgRectsCache::instance()->insert(id, image, rect, secs);
|
||||||
}
|
|
||||||
|
|
||||||
QMetaObject::invokeMethod(d->rectSaveTimer, "start");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::invalidateRectsCache(const QString &image)
|
void Theme::invalidateRectsCache(const QString &image)
|
||||||
{
|
{
|
||||||
if (d->useCache()) {
|
|
||||||
KConfigGroup imageGroup(d->svgElementsCache, image);
|
|
||||||
imageGroup.deleteGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
d->invalidElements.remove(image);
|
SvgRectsCache::instance()->dropImageFromCache(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::releaseRectsCache(const QString &image)
|
void Theme::releaseRectsCache(const QString &image)
|
||||||
{
|
{
|
||||||
QHash<QString, QSet<QString> >::iterator it = d->invalidElements.find(image);
|
Q_UNUSED(image);
|
||||||
if (it != d->invalidElements.end()) {
|
// No op: the internal svg cache always writes the invalid elements in the proper place
|
||||||
if (d->useCache()) {
|
|
||||||
KConfigGroup imageGroup(d->svgElementsCache, it.key());
|
|
||||||
imageGroup.writeEntry("invalidElements", it.value().values());
|
|
||||||
}
|
|
||||||
|
|
||||||
d->invalidElements.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Theme::setCacheLimit(int kbytes)
|
void Theme::setCacheLimit(int kbytes)
|
||||||
|
@ -270,6 +270,7 @@ public:
|
|||||||
**/
|
**/
|
||||||
void setCacheLimit(int kbytes);
|
void setCacheLimit(int kbytes);
|
||||||
|
|
||||||
|
#if PLASMA_ENABLE_DEPRECATED_SINCE(5, 78)
|
||||||
/**
|
/**
|
||||||
* Tries to load the rect of a sub element from a disk cache
|
* Tries to load the rect of a sub element from a disk cache
|
||||||
*
|
*
|
||||||
@ -279,6 +280,7 @@ public:
|
|||||||
* if not found or if we are sure it doesn't exist it will be QRect()
|
* if not found or if we are sure it doesn't exist it will be QRect()
|
||||||
* @return true if the element was found in cache or if we are sure the element doesn't exist
|
* @return true if the element was found in cache or if we are sure the element doesn't exist
|
||||||
**/
|
**/
|
||||||
|
PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
|
||||||
bool findInRectsCache(const QString &image, const QString &element, QRectF &rect) const;
|
bool findInRectsCache(const QString &image, const QString &element, QRectF &rect) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,6 +292,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @since 4.6
|
* @since 4.6
|
||||||
*/
|
*/
|
||||||
|
PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
|
||||||
QStringList listCachedRectKeys(const QString &image) const;
|
QStringList listCachedRectKeys(const QString &image) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -299,6 +302,7 @@ public:
|
|||||||
* @param element sub element we want insert the rect
|
* @param element sub element we want insert the rect
|
||||||
* @param rect element rectangle
|
* @param rect element rectangle
|
||||||
**/
|
**/
|
||||||
|
PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
|
||||||
void insertIntoRectsCache(const QString &image, const QString &element, const QRectF &rect);
|
void insertIntoRectsCache(const QString &image, const QString &element, const QRectF &rect);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -306,6 +310,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @param image the path to the image the cache is associated with
|
* @param image the path to the image the cache is associated with
|
||||||
**/
|
**/
|
||||||
|
PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
|
||||||
void invalidateRectsCache(const QString &image);
|
void invalidateRectsCache(const QString &image);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -315,7 +320,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param image the path to the image the cache is associated with
|
* @param image the path to the image the cache is associated with
|
||||||
*/
|
*/
|
||||||
|
PLASMA_DEPRECATED_VERSION(5, 78, "Rects Cache public API is deprecated")
|
||||||
void releaseRectsCache(const QString &image);
|
void releaseRectsCache(const QString &image);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if PLASMA_ENABLE_DEPRECATED_SINCE(5, 67)
|
#if PLASMA_ENABLE_DEPRECATED_SINCE(5, 67)
|
||||||
/**
|
/**
|
||||||
|
@ -46,6 +46,7 @@ target_link_libraries(KF5PlasmaQuick
|
|||||||
KF5::Plasma
|
KF5::Plasma
|
||||||
KF5::WindowSystem
|
KF5::WindowSystem
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
Qt5::Svg
|
||||||
KF5::KIOWidgets
|
KF5::KIOWidgets
|
||||||
KF5::I18n
|
KF5::I18n
|
||||||
KF5::IconThemes
|
KF5::IconThemes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user