diff options
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 11 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | tests/auto/gui/text/qfont/tst_qfont.cpp | 20 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 128 |
4 files changed, 150 insertions, 10 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 4ca2e996ad..2da967485b 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -150,6 +150,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #endif , directFontResolveMask(0) , inheritedFontResolveMask(0) + , directPaletteResolveMask(0) , inheritedPaletteResolveMask(0) , leftmargin(0) , topmargin(0) @@ -1845,7 +1846,9 @@ void QWidgetPrivate::propagatePaletteChange() if (q->isWindow() && !q->testAttribute(Qt::WA_WindowPropagation)) { inheritedPaletteResolveMask = 0; } - int mask = data.pal.resolve() | inheritedPaletteResolveMask; + + directPaletteResolveMask = data.pal.resolve(); + auto mask = directPaletteResolveMask | inheritedPaletteResolveMask; const bool useStyleSheetPropagationInWidgetStyles = QCoreApplication::testAttribute(Qt::AA_UseStyleSheetPropagationInWidgetStyles); @@ -10452,6 +10455,12 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) if (!useStyleSheetPropagationInWidgetStyles && !testAttribute(Qt::WA_StyleSheet) && (!parent || !parent->testAttribute(Qt::WA_StyleSheet))) { + // if the parent has a font set or inherited, then propagate the mask to the new child + if (parent) { + const auto pd = parent->d_func(); + d->inheritedFontResolveMask = pd->directFontResolveMask | pd->inheritedFontResolveMask; + d->inheritedPaletteResolveMask = pd->directPaletteResolveMask | pd->inheritedPaletteResolveMask; + } d->resolveFont(); d->resolvePalette(); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index 6915782cb3..2597017318 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -672,6 +672,7 @@ public: // Other variables. uint directFontResolveMask; uint inheritedFontResolveMask; + decltype(std::declval<QPalette>().resolve()) directPaletteResolveMask; uint inheritedPaletteResolveMask; short leftmargin; short topmargin; diff --git a/tests/auto/gui/text/qfont/tst_qfont.cpp b/tests/auto/gui/text/qfont/tst_qfont.cpp index 9487436336..2d72eef459 100644 --- a/tests/auto/gui/text/qfont/tst_qfont.cpp +++ b/tests/auto/gui/text/qfont/tst_qfont.cpp @@ -314,27 +314,33 @@ void tst_QFont::resolve() void tst_QFont::resetFont() { QWidget parent; + QWidget firstChild(&parent); QFont parentFont = parent.font(); parentFont.setPointSize(parentFont.pointSize() + 2); parent.setFont(parentFont); - QWidget *child = new QWidget(&parent); - - QFont childFont = child->font(); + QFont childFont = firstChild.font(); childFont.setBold(!childFont.bold()); - child->setFont(childFont); + firstChild.setFont(childFont); + + QWidget secondChild(&parent); + secondChild.setFont(childFont); QVERIFY(parentFont.resolve() != 0); QVERIFY(childFont.resolve() != 0); QVERIFY(childFont != parentFont); - child->setFont(QFont()); // reset font + // reset font on both children + firstChild.setFont(QFont()); + secondChild.setFont(QFont()); - QCOMPARE(child->font().resolve(), uint(0)); + QCOMPARE(firstChild.font().resolve(), QFont::SizeResolved); + QCOMPARE(secondChild.font().resolve(), QFont::SizeResolved); #ifdef Q_OS_ANDROID QEXPECT_FAIL("", "QTBUG-69214", Continue); #endif - QCOMPARE(child->font().pointSize(), parent.font().pointSize()); + QCOMPARE(firstChild.font().pointSize(), parent.font().pointSize()); + QCOMPARE(secondChild.font().pointSize(), parent.font().pointSize()); QVERIFY(parent.font().resolve() != 0); } #endif diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 31e77b2a62..f0c490b598 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -162,8 +162,10 @@ private slots: void fontPropagation(); void fontPropagation2(); void fontPropagation3(); + void fontPropagationDynamic(); void palettePropagation(); void palettePropagation2(); + void palettePropagationDynamic(); void enabledPropagation(); void ignoreKeyEventsWhenDisabled_QTBUG27417(); void properTabHandlingWhenDisabled_QTBUG27417(); @@ -831,6 +833,66 @@ void tst_QWidget::fontPropagation3() QCOMPARE(p.font().pointSize(), child->font().pointSize()); } +/*! + This tests that children that are added to a widget with an explicitly + defined font inherit that font correctly, merging (and overriding) + with the font that might be defined by the platform theme. +*/ +void tst_QWidget::fontPropagationDynamic() +{ + // override side effects from previous tests + QFont themedFont; + themedFont.setBold(true); + themedFont.setPointSize(42); + QApplication::setFont(themedFont, "QPropagationTestWidget"); + + QWidget parent; + QWidget firstChild(&parent); + + const QFont defaultFont = parent.font(); + QFont appFont = defaultFont; + appFont.setPointSize(72); + + // sanity check + QVERIFY(themedFont != defaultFont); + QVERIFY(themedFont != appFont); + + // palette propagates to existing children + parent.setFont(appFont); + QCOMPARE(firstChild.font().pointSize(), appFont.pointSize()); + + // palatte propagates to children added later + QWidget secondChild(&parent); + QCOMPARE(secondChild.font().pointSize(), appFont.pointSize()); + QWidget thirdChild; + QCOMPARE(thirdChild.font().pointSize(), defaultFont.pointSize()); + thirdChild.setParent(&parent); + QCOMPARE(thirdChild.font().pointSize(), appFont.pointSize()); + + // even if the child has an override in QApplication::font + QPropagationTestWidget themedChild; + themedChild.ensurePolished(); // needed for default font to be set up + QCOMPARE(themedChild.font().pointSize(), themedFont.pointSize()); + QCOMPARE(themedChild.font().bold(), themedFont.bold()); + themedChild.setParent(&parent); + QCOMPARE(themedChild.font().pointSize(), appFont.pointSize()); + QCOMPARE(themedChild.font().bold(), themedFont.bold()); + + // grand children as well + QPropagationTestWidget themedGrandChild; + themedGrandChild.setParent(&themedChild); + QCOMPARE(themedGrandChild.font().pointSize(), appFont.pointSize()); + QCOMPARE(themedGrandChild.font().bold(), themedFont.bold()); + + // child with own font attribute does not inherit from parent + QFont childFont = defaultFont; + childFont.setPointSize(9); + QWidget modifiedChild; + modifiedChild.setFont(childFont); + modifiedChild.setParent(&parent); + QCOMPARE(modifiedChild.font().pointSize(), childFont.pointSize()); +} + void tst_QWidget::palettePropagation() { QScopedPointer<QWidget> testWidget(new QWidget); @@ -875,8 +937,8 @@ void tst_QWidget::palettePropagation2() // ! Note, the code below is executed in tst_QWidget's constructor. // QPalette palette; - // font.setColor(QPalette::ToolTipBase, QColor(12, 13, 14)); - // font.setColor(QPalette::Text, QColor(21, 22, 23)); + // palette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14)); + // palette.setColor(QPalette::Text, QColor(21, 22, 23)); // qApp->setPalette(palette, "QPropagationTestWidget"); QScopedPointer<QWidget> root(new QWidget); @@ -975,6 +1037,68 @@ void tst_QWidget::palettePropagation2() QCOMPARE(child5->palette().color(QPalette::ToolTipText), sysPalButton); } +/*! + This tests that children that are added to a widget with an explicitly + defined palette inherit that palette correctly, merging (and overriding) + with the palette that might be defined by the platform theme. +*/ +void tst_QWidget::palettePropagationDynamic() +{ + // override side effects from previous tests + QPalette themedPalette; + themedPalette.setColor(QPalette::ToolTipBase, QColor(12, 13, 14)); + themedPalette.setColor(QPalette::Text, QColor(21, 22, 23)); + QApplication::setPalette(themedPalette, "QPropagationTestWidget"); + + QWidget parent; + QWidget firstChild(&parent); + + const QPalette defaultPalette = parent.palette(); + QPalette appPalette = defaultPalette; + const QColor appColor(1, 2, 3); + appPalette.setColor(QPalette::Text, appColor); + + // sanity check + QVERIFY(themedPalette != defaultPalette); + QVERIFY(themedPalette != appPalette); + + // palette propagates to existing children + parent.setPalette(appPalette); + QCOMPARE(firstChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + + // palatte propagates to children added later + QWidget secondChild(&parent); + QCOMPARE(secondChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + QWidget thirdChild; + QCOMPARE(thirdChild.palette().color(QPalette::Text), defaultPalette.color(QPalette::Text)); + thirdChild.setParent(&parent); + QCOMPARE(thirdChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + + // even if the child has an override in QApplication::palette + QPropagationTestWidget themedChild; + themedChild.ensurePolished(); // needed for default palette to be set up + QCOMPARE(themedChild.palette().color(QPalette::Text), themedPalette.color(QPalette::Text)); + QCOMPARE(themedChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase)); + themedChild.setParent(&parent); + QCOMPARE(themedChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + QCOMPARE(themedChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase)); + + // grand children as well + QPropagationTestWidget themedGrandChild; + themedGrandChild.setParent(&themedChild); + QCOMPARE(themedGrandChild.palette().color(QPalette::Text), appPalette.color(QPalette::Text)); + QCOMPARE(themedGrandChild.palette().color(QPalette::ToolTipBase), themedPalette.color(QPalette::ToolTipBase)); + + // child with own color does not inherit from parent + QPalette childPalette = defaultPalette; + childPalette.setColor(QPalette::Text, Qt::red); + QWidget modifiedChild; + modifiedChild.setPalette(childPalette); + modifiedChild.setParent(&parent); + QCOMPARE(modifiedChild.palette().color(QPalette::Text), childPalette.color(QPalette::Text)); + +} + void tst_QWidget::enabledPropagation() { QScopedPointer<QWidget> testWidget(new QWidget); |