Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
6.0.0, 6.1.0, 6.2.0
-
None
-
-
56bd1b76d2e81c58a80bf6b5d74219c6b1ab8499 (qt/qtbase/dev) 3bf23b71188e719b1eee4408b8d2a354901dbeae (qt/qtbase/6.2) 9334e06bdf (qt/qtbase/6.3) 9334e06bdf (qt/tqtc-qtbase/6.3) bd27707c20 (qt/tqtc-qtbase/6.2)
Description
Calling Palette::setBrush() with a brush for a role that is identical to the existing brush, will not detach the QPalettePrivate but it will change the resolve mask. Since QPalettePrivate is shared, this affects the resolve mask of all QPalette instances - in particular QGuiApplicationPrivate::app_pal.
Check out the following patch to the calculator:
diff --git a/examples/widgets/widgets/calculator/calculator.cpp b/examples/widgets/widgets/calculator/calculator.cpp index 2c3669b7a8..691a4771ff 100644 --- a/examples/widgets/widgets/calculator/calculator.cpp +++ b/examples/widgets/widgets/calculator/calculator.cpp @@ -54,6 +54,7 @@ #include <QGridLayout> #include <QLineEdit> #include <QtMath> +#include <QEvent> //! [0] Calculator::Calculator(QWidget *parent) @@ -140,6 +141,14 @@ Calculator::Calculator(QWidget *parent) } //! [6] +bool Calculator::event(QEvent *e) +{ + if (e->type() == QEvent::PaletteChange) { + qDebug() << "palette changed. background" << palette().brush(QPalette::Window).color().rgba(); + } + QWidget::event(e); +} + //! [7] void Calculator::digitClicked() { diff --git a/examples/widgets/widgets/calculator/calculator.h b/examples/widgets/widgets/calculator/calculator.h index 937de185e7..5082b32ef7 100644 --- a/examples/widgets/widgets/calculator/calculator.h +++ b/examples/widgets/widgets/calculator/calculator.h @@ -66,6 +66,7 @@ class Calculator : public QWidget public: Calculator(QWidget *parent = nullptr); + bool event(QEvent *) override; private slots: void digitClicked(); void unaryOperatorClicked(); diff --git a/examples/widgets/widgets/calculator/main.cpp b/examples/widgets/widgets/calculator/main.cpp index a034bb262e..cbfad39331 100644 --- a/examples/widgets/widgets/calculator/main.cpp +++ b/examples/widgets/widgets/calculator/main.cpp @@ -56,6 +56,12 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); Calculator calc; + QPalette p = calc.palette(); + auto foo = p.brush(QPalette::Window); + // This changes QGuiApplication::app_pal because + // setBrush() does not detach (brush is the same as set), + // BUT it changes the resolve mask. + p.setBrush(QPalette::Window, foo); calc.show(); return app.exec(); }
If you run this for example on macOS and change the system appearance from dark to light (or vice-versa), you'll notice that the debug output does not show the new value.
This used to work in Qt 5 because the resolve mask was part of QPalette itself, not the shared private. But commit 556511f9f39ddc887481e0cd5a877134ceb0da6b regressed this - there is a detach() call missing in setBrush() IMO.
Attachments
Issue Links
- is duplicated by
-
PYSIDE-1822 Colors set on QGuiApplication's palette do not get set on empty palette
- Closed
-
QTBUG-99672 QPalette + resolve mask issue under Qt6
- Closed
- relates to
-
PYSIDE-2032 Apply a different palette object to the application instance breaks the colors
- Closed
-
QTBUG-110963 Q Designer: inactive QPalette color values not stored correctly
- Closed
- resulted in
-
QTBUG-104563 Setting palette values doesn't work when they equal app palette values
- Closed