diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-06-30 21:36:22 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-07-11 14:31:12 +0200 |
commit | 813bbc515bdd8af843ef56115711691e926d0bcb (patch) | |
tree | 0cfe74766e9cfef3cdd5a3bdace381b2088e251e /src/widgets/styles/qstylehelper.cpp | |
parent | a11ee31883c4c682a833822880309a1c0b9dfe9b (diff) |
QStyle: don't use the QPixmapCache when a style sheet is set
If a style sheet is active, then the palette in the QStyleOption might
be a generated, short-lived, temporary QPalette instance. As QPalette's
cacheKey is based on instance-counters of the private data structures,
it will always be unique for such a QPalette, even if the brushes are
the same as in a previous instance.
(QPalette::cacheKey is just a 64bit integer, we cannot possibly encode
the entire QPalette data in it in a collision-free way, and since a
brush in the palette might contain a pixmap or a gradient we couldn't
even generate an efficient string representation for it. We could at
most cache and reuse QPalette instances based on the attributes in the
style sheet rule and in the base palette of the widget. However, this
seems fragile; it might be an opportunity for future optimization.)
Some styles use the QPixmapCache, with a key that includes the
palette's cache key. The key will always be unique if the palette is
based on style sheet rules, and then we fill pixmap cache with pixmaps
that can never be reused, making the cache both useless and wasteful.
To solve this, generate an empty key if we detect that it is for a style
object that is the target of a style sheet. Return an empty cache key
string from QStyleHelper::uniqueName, which will make QPixmapCache
return immediatey when trying to insert or find an object.
This is not pretty, but it makes the change minimal and low-risk.
Refactoring the respective code paths to e.g. consistently use the
BEGIN_STYLE_PIXMAPCACHE helper macro requires larger changes that
can only be verified visually, and so are out of scope for a bug fix.
This requires changes to code that uses QStyleHelper::uniqueName, as we
need to avoid that other key elements are appended to the generated (and
maybe empty) key. As a side effect, this ends up with code that makes
better use of QStringBuilder.
Pick-to: 6.6
Fixes: QTBUG-114473
Change-Id: I011aed0885f105cbf1e8c0bc6b94c46df47761a3
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/widgets/styles/qstylehelper.cpp')
-rw-r--r-- | src/widgets/styles/qstylehelper.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp index f79e83be61..1084761d30 100644 --- a/src/widgets/styles/qstylehelper.cpp +++ b/src/widgets/styles/qstylehelper.cpp @@ -25,8 +25,18 @@ Q_GUI_EXPORT int qt_defaultDpiX(); namespace QStyleHelper { +static inline bool usePixmapCache(const QStyleOption *opt) +{ + if (QWidget *widget = qobject_cast<QWidget *>(opt->styleObject)) + return !widget->testAttribute(Qt::WA_StyleSheetTarget); + return true; +} + QString uniqueName(const QString &key, const QStyleOption *option, const QSize &size) { + if (!usePixmapCache(option)) + return {}; + const QStyleOptionComplex *complexOption = qstyleoption_cast<const QStyleOptionComplex *>(option); QString tmp = key % HexString<uint>(option->state) % HexString<uint>(option->direction) |