summaryrefslogtreecommitdiffstats
path: root/src/widgets/styles/qstylehelper.cpp
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-06-30 21:36:22 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-07-11 14:31:12 +0200
commit813bbc515bdd8af843ef56115711691e926d0bcb (patch)
tree0cfe74766e9cfef3cdd5a3bdace381b2088e251e /src/widgets/styles/qstylehelper.cpp
parenta11ee31883c4c682a833822880309a1c0b9dfe9b (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.cpp10
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)