[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [plasma-framework/mart/FrameSvgTransactions] src: transactions for setting multiple properties
From: Marco Martin <null () kde ! org>
Date: 2017-01-31 19:38:20
Message-ID: E1cYeFw-0000ai-EI () code ! kde ! org
[Download RAW message or body]
Git commit 49d930e79324729f208b8ed0c6d32d0cdbd71808 by Marco Martin.
Committed on 31/01/2017 at 19:36.
Pushed by mart into branch 'mart/FrameSvgTransactions'.
transactions for setting multiple properties
when setting multiple properties in a framesvg, make possible to
block any repaint and creation/destruction of FrameData objects
Change-Id: I1f88404e0560e900693ed3aae5f7bad1e6678289
M +7 -0 src/declarativeimports/core/framesvgitem.cpp
M +3 -0 src/declarativeimports/core/framesvgitem.h
M +96 -146 src/plasma/framesvg.cpp
M +2 -0 src/plasma/framesvg.h
M +14 -2 src/plasma/private/framesvg_p.h
https://commits.kde.org/plasma-framework/49d930e79324729f208b8ed0c6d32d0cdbd71808
diff --git a/src/declarativeimports/core/framesvgitem.cpp \
b/src/declarativeimports/core/framesvgitem.cpp index 966f5b609..e61d51ed1 100644
--- a/src/declarativeimports/core/framesvgitem.cpp
+++ b/src/declarativeimports/core/framesvgitem.cpp
@@ -516,10 +516,17 @@ QSGNode *FrameSvgItem::updatePaintNode(QSGNode *oldNode, \
QQuickItem::UpdatePaint return oldNode;
}
+void FrameSvgItem::classBegin()
+{
+ QQuickItem::classBegin();
+ m_frameSvg->setRepaintBlocked(true);
+}
+
void FrameSvgItem::componentComplete()
{
QQuickItem::componentComplete();
m_frameSvg->resizeFrame(QSize(width(), height()));
+ m_frameSvg->setRepaintBlocked(false);
m_textureChanged = true;
}
diff --git a/src/declarativeimports/core/framesvgitem.h \
b/src/declarativeimports/core/framesvgitem.h index e2a48e8e7..b32432364 100644
--- a/src/declarativeimports/core/framesvgitem.h
+++ b/src/declarativeimports/core/framesvgitem.h
@@ -22,6 +22,7 @@
#define FRAMESVGITEM_P
#include <QQuickItem>
+#include <QQmlParserStatus>
#include <Plasma/FrameSvg>
@@ -107,6 +108,7 @@ private:
class FrameSvgItem : public QQuickItem
{
Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
/**
* Theme relative path of the svg, like "widgets/background"
@@ -213,6 +215,7 @@ public:
protected:
+ void classBegin() Q_DECL_OVERRIDE;
void componentComplete() Q_DECL_OVERRIDE;
/// @endcond
diff --git a/src/plasma/framesvg.cpp b/src/plasma/framesvg.cpp
index f75252835..11c3f09d4 100644
--- a/src/plasma/framesvg.cpp
+++ b/src/plasma/framesvg.cpp
@@ -45,9 +45,11 @@ QHash<ThemePrivate *, QHash<QString, FrameData *> > \
FrameSvgPrivate::s_sharedFra // Any attempt to generate a frame whose width or \
height is larger than this // will be rejected
static const int MAX_FRAME_SIZE = 100000;
-
+static int destcount = 0;
FrameData::~FrameData()
{
+ ++destcount;
+ qWarning()<<"AAA"<<destcount;
for (auto it = references.constBegin(), end = references.constEnd(); it != end; \
++it) { it.key()->d->frames.remove(prefix);
}
@@ -131,48 +133,11 @@ void FrameSvg::setEnabledBorders(const EnabledBorders borders)
return;
}
- FrameData *fd = d->frames[d->prefix];
-
- const QString oldKey = d->cacheId(fd, d->prefix);
- const EnabledBorders oldBorders = fd->enabledBorders;
- fd->enabledBorders = borders;
- const QString newKey = d->cacheId(fd, d->prefix);
- fd->enabledBorders = oldBorders;
-
- //qCDebug(LOG_PLASMA) << "looking for" << newKey;
- FrameData *newFd = FrameSvgPrivate::s_sharedFrames[theme()->d].value(newKey);
- if (newFd) {
- //qCDebug(LOG_PLASMA) << "FOUND IT!" << newFd->refcount;
- // we've found a math, so insert that new one and ref it ..
- newFd->ref(this);
- d->frames.insert(d->prefix, newFd);
-
- //.. then deref the old one and if it's no longer used, get rid of it
- if (fd->deref(this)) {
- //const QString oldKey = d->cacheId(fd, d->prefix);
- //qCDebug(LOG_PLASMA) << "1. Removing it" << oldKey << fd->refcount;
- FrameSvgPrivate::s_sharedFrames[fd->theme].remove(oldKey);
- delete fd;
- }
+ d->pendingEnabledBorders = borders;
- return;
+ if (!d->repaintBlocked) {
+ d->updateFrameData();
}
-
- if (fd->refcount() == 1) {
- // we're the only user of it, let's remove it from the shared keys
- // we don't want to deref it, however, as we'll still be using it
- FrameSvgPrivate::s_sharedFrames[fd->theme].remove(oldKey);
- } else {
- // others are using it, but we wish to change its size. so deref it,
- // then create a copy of it (we're automatically ref'd via the ctor),
- // then insert it into our frames.
- fd->deref(this);
- fd = new FrameData(*fd, this);
- d->frames.insert(d->prefix, fd);
- }
-
- fd->enabledBorders = borders;
- d->updateAndSignalSizes();
}
FrameSvg::EnabledBorders FrameSvg::enabledBorders() const
@@ -215,76 +180,21 @@ void FrameSvg::setElementPrefix(Plasma::Types::Location \
location)
void FrameSvg::setElementPrefix(const QString &prefix)
{
- const QString oldPrefix(d->prefix);
-
if (!hasElement(prefix % QLatin1String("-center"))) {
- d->prefix.clear();
+ d->pendingPrefix.clear();
} else {
- d->prefix = prefix;
- if (!d->prefix.isEmpty()) {
- d->prefix += '-';
+ d->pendingPrefix = prefix;
+ if (!d->pendingPrefix.isEmpty()) {
+ d->pendingPrefix += '-';
}
}
d->requestedPrefix = prefix;
- FrameData *oldFrameData = d->frames.value(oldPrefix);
- if (oldPrefix == d->prefix && oldFrameData) {
- return;
- }
-
- if (!d->frames.contains(d->prefix)) {
- if (oldFrameData) {
- FrameData *newFd = 0;
- if (!oldFrameData->frameSize.isEmpty()) {
- const QString key = d->cacheId(oldFrameData, d->prefix);
- newFd = FrameSvgPrivate::s_sharedFrames[theme()->d].value(key);
- if (newFd && newFd->devicePixelRatio != devicePixelRatio()) {
- newFd = 0;
- }
- }
-
- // we need to put this in the cache if we didn't find it in the shared \
frames
- // and we have a size; if we don't have a size, we'll catch it later
- const bool cache = !newFd && !oldFrameData->frameSize.isEmpty();
- if (newFd) {
- newFd->ref(this);
- } else {
- newFd = new FrameData(*oldFrameData, this);
- }
-
- d->frames.insert(d->prefix, newFd);
-
- if (cache) {
- // we have to cache after inserting the frame since the cacheId \
requires the
- // frame to be in the frames collection already
- const QString key = d->cacheId(oldFrameData, d->prefix);
- //qCDebug(LOG_PLASMA) << this << " 1. inserting as" << key;
-
- FrameSvgPrivate::s_sharedFrames[theme()->d].insert(key, newFd);
- newFd->theme = theme()->d;
- }
- } else {
- // couldn't find anything useful, so we just create something here
- // we don't have a size for it yet, so don't bother trying to share it \
just yet
- FrameData *newFd = new FrameData(this, d->prefix);
- d->frames.insert(d->prefix, newFd);
- }
-
- d->updateSizes();
- }
+ d->location = Types::Floating;
- if (!d->cacheAll) {
- d->frames.remove(oldPrefix);
- if (oldFrameData) {
- if (oldFrameData->deref(this)) {
- const QString oldKey = d->cacheId(oldFrameData, oldPrefix);
- FrameSvgPrivate::s_sharedFrames[oldFrameData->theme].remove(oldKey);
- delete oldFrameData;
- }
- }
+ if (!d->repaintBlocked) {
+ d->updateFrameData();
}
-
- d->location = Types::Floating;
}
bool FrameSvg::hasElementPrefix(const QString &prefix) const
@@ -338,53 +248,14 @@ void FrameSvg::resizeFrame(const QSizeF &size)
}
FrameData *fd = d->frames[d->prefix];
- if (size == fd->frameSize) {
- return;
- }
-
- const QString oldKey = d->cacheId(fd, d->prefix);
- const QSize currentSize = fd->frameSize;
- fd->frameSize = size.toSize();
- const QString newKey = d->cacheId(fd, d->prefix);
- fd->frameSize = currentSize;
-
- //qCDebug(LOG_PLASMA) << "looking for" << newKey;
- FrameData *newFd = FrameSvgPrivate::s_sharedFrames[theme()->d].value(newKey);
- if (newFd) {
- //qCDebug(LOG_PLASMA) << "FOUND IT!" << newFd->refcount;
- // we've found a math, so insert that new one and ref it ..
- newFd->ref(this);
- d->frames.insert(d->prefix, newFd);
-
- //.. then deref the old one and if it's no longer used, get rid of it
- if (fd->deref(this)) {
- //const QString oldKey = d->cacheId(fd, d->prefix);
- //qCDebug(LOG_PLASMA) << "1. Removing it" << oldKey << fd->refcount;
- FrameSvgPrivate::s_sharedFrames[fd->theme].remove(oldKey);
- delete fd;
- }
-
+ if (size.toSize() == fd->frameSize) {
return;
}
+ d->pendingFrameSize = size.toSize();
- if (fd->refcount() == 1) {
- // we're the only user of it, let's remove it from the shared keys
- // we don't want to deref it, however, as we'll still be using it
- FrameSvgPrivate::s_sharedFrames[fd->theme].remove(oldKey);
- } else {
- // others are using it, but we wish to change its size. so deref it,
- // then create a copy of it (we're automatically ref'd via the ctor),
- // then insert it into our frames.
- fd->deref(this);
- fd = new FrameData(*fd, this);
- d->frames.insert(d->prefix, fd);
+ if (!d->repaintBlocked) {
+ d->updateFrameData();
}
-
- d->updateSizes();
- fd->frameSize = size.toSize();
- // we know it isn't in s_sharedFrames due to the check above, so insert it now
- FrameSvgPrivate::s_sharedFrames[theme()->d].insert(newKey, fd);
- fd->theme = theme()->d;
}
QSizeF FrameSvg::frameSize() const
@@ -860,6 +731,76 @@ QRect FrameSvgPrivate::contentGeometry(FrameData* frame, const \
QSize& size) cons return contentRect;
}
+void FrameSvgPrivate::updateFrameData()
+{
+ FrameData *fd = frames[prefix];
+
+ const QString oldKey = cacheId(fd, fd->prefix);
+
+ const FrameSvg::EnabledBorders oldBorders = fd->enabledBorders;
+ const QSize currentSize = fd->frameSize;
+
+ fd->enabledBorders = pendingEnabledBorders;
+ fd->frameSize = pendingFrameSize;
+
+ const QString newKey = cacheId(fd, pendingPrefix);
+
+ //reset frame to old values
+ fd->enabledBorders = oldBorders;
+ fd->frameSize = currentSize;
+ if (oldKey == newKey) return;
+
+ //qCDebug(LOG_PLASMA) << "looking for" << newKey;
+ FrameData *newFd = FrameSvgPrivate::s_sharedFrames[q->theme()->d].value(newKey);
+ if (newFd) {
+ //qCDebug(LOG_PLASMA) << "FOUND IT!" << newFd->refcount;
+ // we've found a math, so insert that new one and ref it ..
+ newFd->ref(q);
+ frames.insert(pendingPrefix, newFd);
+
+ //.. then deref the old one and if it's no longer used, get rid of it
+ if (fd->deref(q)) {
+ //const QString oldKey = cacheId(fd, prefix);
+ //qCDebug(LOG_PLASMA) << "1. Removing it" << oldKey << fd->refcount;
+ FrameSvgPrivate::s_sharedFrames[fd->theme].remove(oldKey);
+
+ if (prefix != pendingPrefix) {
+ frames.remove(fd->prefix);
+ }
+
+ delete fd;
+ }
+
+ prefix = pendingPrefix;
+ return;
+ }
+
+ if (fd->refcount() == 1) {
+ // we're the only user of it, let's remove it from the shared keys
+ // we don't want to deref it, however, as we'll still be using it
+ FrameSvgPrivate::s_sharedFrames[fd->theme].remove(oldKey);
+ frames.remove(fd->prefix);
+ } else {
+ // others are using it, but we wish to change its size. so deref it,
+ // then create a copy of it (we're automatically ref'd via the ctor),
+ // then insert it into our frames.
+ fd->deref(q);
+ fd = new FrameData(*fd, q);
+ }
+
+ frames.insert(pendingPrefix, fd);
+ prefix = pendingPrefix;
+ fd->prefix = pendingPrefix;
+ //updateSizes();
+ fd->enabledBorders = pendingEnabledBorders;
+ fd->frameSize = pendingFrameSize;
+
+ // we know it isn't in s_sharedFrames due to the check above, so insert it now
+ FrameSvgPrivate::s_sharedFrames[q->theme()->d].insert(newKey, fd);
+ fd->theme = q->theme()->d;
+ updateAndSignalSizes();
+}
+
void FrameSvgPrivate::paintCenter(QPainter& p, FrameData* frame, const QRect& \
contentRect, const QSize& fullSize) {
if (!contentRect.isEmpty()) {
@@ -1118,6 +1059,15 @@ QString FrameSvg::actualPrefix() const
return d->prefix;
}
+void FrameSvg::setRepaintBlocked(bool blocked)
+{
+ d->repaintBlocked = blocked;
+
+ if (!blocked) {
+ d->updateFrameData();
+ }
+}
+
} // Plasma namespace
#include "moc_framesvg.cpp"
diff --git a/src/plasma/framesvg.h b/src/plasma/framesvg.h
index 139482acb..c9c6ea3db 100644
--- a/src/plasma/framesvg.h
+++ b/src/plasma/framesvg.h
@@ -292,6 +292,8 @@ public:
*/
QString actualPrefix() const;
+ void setRepaintBlocked(bool blocked);
+
private:
FrameSvgPrivate *const d;
friend class FrameData;
diff --git a/src/plasma/private/framesvg_p.h b/src/plasma/private/framesvg_p.h
index e48bc56fa..9956b3b80 100644
--- a/src/plasma/private/framesvg_p.h
+++ b/src/plasma/private/framesvg_p.h
@@ -137,8 +137,10 @@ class FrameSvgPrivate
public:
FrameSvgPrivate(FrameSvg *psvg)
: q(psvg),
+ overlayPos(0, 0),
+ pendingEnabledBorders(FrameSvg::AllBorders),
cacheAll(false),
- overlayPos(0, 0)
+ repaintBlocked(false)
{
}
@@ -158,8 +160,10 @@ public:
void paintCorner(QPainter& p, FrameData* frame, Plasma::FrameSvg::EnabledBorders \
border, const QRect& output) const;
void paintCenter(QPainter& p, FrameData* frame, const QRect& contentRect, const \
QSize& fullSize); QRect contentGeometry(FrameData* frame, const QSize& size) const;
+ void updateFrameData();
Types::Location location;
+ QString pendingPrefix;
QString prefix;
//sometimes the prefix we requested is not available, so prefix will be emoty
//keep track of the requested one anyways, we'll try again when the theme \
changes @@ -167,12 +171,20 @@ public:
FrameSvg *q;
- bool cacheAll : 1;
QPoint overlayPos;
QHash<QString, FrameData *> frames;
+ //FrameData *frame;
+
+ //those can differ from frame->enabledBorders if we are in a transition
+ FrameSvg::EnabledBorders pendingEnabledBorders;
+ //this can differ from frame->frameSize if we are in a transition
+ QSize pendingFrameSize;
static QHash<ThemePrivate *, QHash<QString, FrameData *> > s_sharedFrames;
+
+ bool cacheAll : 1;
+ bool repaintBlocked : 1;
};
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic