Fix binding loop regression in FrameSVGItem

Summary:
d8a1a9eb084b19e552c789244267f7346e1b27a8 introduces an unintended code
change, resizeFrame() updates the margins and in turns calls
repaintNeeded. This isn't needed and is a binding loop if we ever have a
frameSVGItem whose size depends on it's own margins.

resizeFrame is different from setEnabledBorders / setElementPrefix /
theme changes because even though we need to create a new FrameData we
know any hints and margins won't change. FrameSvgItem::updateSizes
doesn't depend on the size in any way, so always gives the same result
as before. We still, however, need to call updateSizes to populate our
FrameData structure even if the results will be the same as the previous
FrameData.

This patch that introduces a flag to updateFrameData to determine if we
should emit that size hints may have changed or not.

Test Plan:
GDB showed where the loop was.

Read the old code, and looked for differences

Ran plasmashell, checked I had no binding loop, frames including button
which have
composeOverBorder which need the new FrameData all rendered correctly.

Reviewers: #plasma, #frameworks, mart

Subscribers: mart, broulik, plasma-devel

Tags: #plasma, #frameworks

Differential Revision: https://phabricator.kde.org/D4713
This commit is contained in:
David Edmundson 2017-02-22 12:26:01 +00:00
parent 408b311662
commit e301b63685
2 changed files with 13 additions and 4 deletions

View File

@ -243,7 +243,7 @@ void FrameSvg::resizeFrame(const QSizeF &size)
d->pendingFrameSize = size.toSize();
if (!d->repaintBlocked) {
d->updateFrameData();
d->updateFrameData(FrameSvgPrivate::UpdateFrame);
}
}
@ -689,7 +689,7 @@ QRect FrameSvgPrivate::contentGeometry(FrameData* frame, const QSize& size) cons
return contentRect;
}
void FrameSvgPrivate::updateFrameData()
void FrameSvgPrivate::updateFrameData(UpdateType updateType)
{
FrameData *fd = frame;
@ -754,7 +754,11 @@ void FrameSvgPrivate::updateFrameData()
// 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();
if (updateType == UpdateFrameAndMargins) {
updateAndSignalSizes();
} else {
updateSizes(frame);
}
}
void FrameSvgPrivate::paintCenter(QPainter& p, FrameData* frame, const QRect& contentRect, const QSize& fullSize)

View File

@ -151,6 +151,11 @@ public:
QPixmap alphaMask();
enum UpdateType {
UpdateFrame,
UpdateFrameAndMargins
};
void generateBackground(FrameData *frame);
void generateFrameBackground(FrameData *frame);
QString cacheId(FrameData *frame, const QString &prefixToUse) const;
@ -163,7 +168,7 @@ 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();
void updateFrameData(UpdateType updateType = UpdateFrameAndMargins);
Types::Location location;
QString prefix;