diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 45df47730d..c6facb8ceb 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1900,10 +1900,11 @@ bool QGuiApplication::event(QEvent *e) if (topLevelWindow->flags() != Qt::Desktop) postEvent(topLevelWindow, new QEvent(QEvent::LanguageChange)); } - } else if (e->type() == QEvent::ApplicationFontChange) { + } else if (e->type() == QEvent::ApplicationFontChange || + e->type() == QEvent::ApplicationPaletteChange) { for (auto *topLevelWindow : QGuiApplication::topLevelWindows()) { if (topLevelWindow->flags() != Qt::Desktop) - postEvent(topLevelWindow, new QEvent(QEvent::ApplicationFontChange)); + postEvent(topLevelWindow, new QEvent(e->type())); } } else if (e->type() == QEvent::Quit) { // Close open windows. This is done in order to deliver de-expose @@ -3271,8 +3272,10 @@ QClipboard * QGuiApplication::clipboard() /*! \since 5.4 \fn void QGuiApplication::paletteChanged(const QPalette &palette) + \obsolete - This signal is emitted when the \a palette of the application changes. + This signal is emitted when the \a palette of the application changes. Use + QEvent::ApplicationPaletteChanged instead. \sa palette() */ diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h index 0c642d8ff5..6017cf513f 100644 --- a/src/gui/kernel/qguiapplication.h +++ b/src/gui/kernel/qguiapplication.h @@ -188,9 +188,9 @@ Q_SIGNALS: void commitDataRequest(QSessionManager &sessionManager); void saveStateRequest(QSessionManager &sessionManager); #endif - void paletteChanged(const QPalette &pal); void applicationDisplayNameChanged(); #if QT_DEPRECATED_SINCE(6, 0) + void paletteChanged(const QPalette &pal); void fontChanged(const QFont &font); #endif protected: diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index f5d857b623..d7919c9414 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1211,18 +1211,15 @@ void QApplicationPrivate::handlePaletteChanged(const char *className) // Setting the global application palette is documented to // reset any previously set class specific widget palettes. - bool sendPaletteChangeToAllWidgets = false; - if (!className && !widgetPalettes.isEmpty()) { - sendPaletteChangeToAllWidgets = true; + if (!className && !widgetPalettes.isEmpty()) widgetPalettes.clear(); - } QGuiApplicationPrivate::handlePaletteChanged(className); QEvent event(QEvent::ApplicationPaletteChange); const QWidgetList widgets = QApplication::allWidgets(); for (auto widget : widgets) { - if (sendPaletteChangeToAllWidgets || (!className && widget->isWindow()) || (className && widget->inherits(className))) + if (!widget->isWindow() && widget->inherits(className)) QCoreApplication::sendEvent(widget, &event); } @@ -1734,7 +1731,8 @@ bool QApplication::event(QEvent *e) #endif } - if (e->type() == QEvent::LanguageChange || e->type() == QEvent::ApplicationFontChange) { + if (e->type() == QEvent::LanguageChange || e->type() == QEvent::ApplicationFontChange || + e->type() == QEvent::ApplicationPaletteChange) { // QGuiApplication::event does not account for the cases where // there is a top level widget without a window handle. So they // need to have the event posted here diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 54ca37e638..991211062f 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -418,6 +418,7 @@ private slots: void winIdAfterClose(); void receivesLanguageChangeEvent(); void receivesApplicationFontChangeEvent(); + void receivesApplicationPaletteChangeEvent(); private: bool ensureScreenSize(int width, int height); @@ -4988,6 +4989,7 @@ void tst_QWidget::isOpaque() QVERIFY(!::isOpaque(&widget)); QApplication::setPalette(old); + QApplication::sendPostedEvents(&widget, QEvent::ApplicationPaletteChange); QCOMPARE(::isOpaque(&widget), old.color(QPalette::Window).alpha() == 255); } #endif @@ -11662,6 +11664,7 @@ public: ChangeEventWidget(QWidget *parent = nullptr) : QWidget(parent) {} int languageChangeCount = 0; int applicationFontChangeCount = 0; + int applicationPaletteChangeCount = 0; protected: bool event(QEvent *e) override { @@ -11669,6 +11672,8 @@ protected: languageChangeCount++; else if (e->type() == QEvent::ApplicationFontChange) applicationFontChangeCount++; + else if (e->type() == QEvent::ApplicationPaletteChange) + applicationPaletteChangeCount++; return QWidget::event(e); } }; @@ -11679,6 +11684,7 @@ public: ChangeEventWindow(QWindow *parent = nullptr) : QWindow(parent) {} int languageChangeCount = 0; int applicationFontChangeCount = 0; + int applicationPaletteChangeCount = 0; protected: bool event(QEvent *e) override { @@ -11686,6 +11692,8 @@ protected: languageChangeCount++; else if (e->type() == QEvent::ApplicationFontChange) applicationFontChangeCount++; + else if (e->type() == QEvent::ApplicationPaletteChange) + applicationPaletteChangeCount++; return QWindow::event(e); } }; @@ -11739,5 +11747,32 @@ void tst_QWidget::receivesApplicationFontChangeEvent() QApplication::setFont(origFont); } +void tst_QWidget::receivesApplicationPaletteChangeEvent() +{ + // Confirm that any QWindow or top level QWidget only gets a single + // ApplicationPaletteChange event when the font is changed + const QPalette origPalette = QApplication::palette(); + + ChangeEventWidget topLevel; + auto childWidget = new ChangeEventWidget(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + ChangeEventWindow ww; + ww.show(); + QVERIFY(QTest::qWaitForWindowExposed(&ww)); + ChangeEventWidget topLevelNotShown; + QPalette changedPalette = origPalette; + changedPalette.setColor(QPalette::Base, Qt::red); + QApplication::setPalette(changedPalette); + QCoreApplication::sendPostedEvents(0, QEvent::ApplicationPaletteChange); + QCOMPARE(topLevel.applicationPaletteChangeCount, 1); + QCOMPARE(topLevelNotShown.applicationPaletteChangeCount, 1); + // QWidget should not be passing the event on automatically + QCOMPARE(childWidget->applicationPaletteChangeCount, 0); + QCOMPARE(ww.applicationPaletteChangeCount, 1); + + QApplication::setPalette(origPalette); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc"