From 189ae68d2a93358efa48b65bb798aa2ae2b25b59 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 14 Feb 2020 16:16:37 +0100 Subject: Try to stabilize tst_qwidget_qwindow::tst_resize_count on X11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test fails sporadically on OpenSUSE, with the widget receiving multiple resize events. Assuming that window management kicks in at unpredictable moments and changes the geometry of the managed widget possibly in several steps, we try to turn off all window management on X11. Change-Id: I7d2120c02eb870040b2ee94986a2ac5608d5a423 Fixes: QTBUG-66345 Reviewed-by: Tor Arne Vestbø Reviewed-by: Qt CI Bot --- tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tests/auto/widgets/kernel') diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index dd3e2f844b..f42e2d777b 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -968,6 +968,7 @@ void tst_QWidget_window::tst_resize_count() { { ResizeWidget resize; + resize.setWindowFlags(Qt::X11BypassWindowManagerHint); resize.show(); QVERIFY(QTest::qWaitForWindowExposed(&resize)); #ifdef Q_OS_WINRT @@ -1000,6 +1001,7 @@ void tst_QWidget_window::tst_resize_count() } { ResizeWidget parent; + parent.setWindowFlag(Qt::X11BypassWindowManagerHint); ResizeWidget child(&parent); child.resize(m_testWidgetSize); child.winId(); -- cgit v1.2.3 From 9029c5586460950b4fa6773a5d08c67e5ba16e8a Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 13 Feb 2020 15:33:00 +0100 Subject: Send the LanguageChange event to all top level windows, not just widgets By sending it to all top level windows it will make it possible for non widget based controls to listen for this event if it cares about it so it can handle translation updates as appropriate. Task-number: QTBUG-78141 Task-number: QTBUG-82020 Change-Id: I8f35cdcccd81a199ff780c3f4f3d2c663480d638 Reviewed-by: Mitch Curtis --- tests/auto/widgets/kernel/qwidget/hellotr_la.qm | Bin 0 -> 237 bytes tests/auto/widgets/kernel/qwidget/qwidget.qrc | 1 + tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 51 ++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 tests/auto/widgets/kernel/qwidget/hellotr_la.qm (limited to 'tests/auto/widgets/kernel') diff --git a/tests/auto/widgets/kernel/qwidget/hellotr_la.qm b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm new file mode 100644 index 0000000000..25c0aad583 Binary files /dev/null and b/tests/auto/widgets/kernel/qwidget/hellotr_la.qm differ diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.qrc b/tests/auto/widgets/kernel/qwidget/qwidget.qrc index 1399c4c9db..597ea872a5 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.qrc +++ b/tests/auto/widgets/kernel/qwidget/qwidget.qrc @@ -3,5 +3,6 @@ geometry.dat geometry-maximized.dat geometry-fullscreen.dat + hellotr_la.qm diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 9c16b1a00a..d8f4881ffa 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -410,6 +410,7 @@ private slots: void closeWithChildWindow(); void winIdAfterClose(); + void receivesLanguageChangeEvent(); private: bool ensureScreenSize(int width, int height); @@ -11360,5 +11361,55 @@ void tst_QWidget::winIdAfterClose() delete spy; } +class LanguageChangeEventWidget : public QWidget +{ +public: + LanguageChangeEventWidget(QWidget *parent = nullptr) : QWidget(parent) {} + int languageChangeCount = 0; +protected: + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeCount++; + return QWidget::event(e); + } +}; + +class LanguageChangeEventWindow : public QWindow +{ +public: + LanguageChangeEventWindow(QWindow *parent = nullptr) : QWindow(parent) {} + int languageChangeCount = 0; +protected: + bool event(QEvent *e) override + { + if (e->type() == QEvent::LanguageChange) + languageChangeCount++; + return QWindow::event(e); + } +}; + +void tst_QWidget::receivesLanguageChangeEvent() +{ + // Confirm that any QWindow or QWidget only gets a single + // LanguageChange event when a translator is installed + LanguageChangeEventWidget topLevel; + auto childWidget = new LanguageChangeEventWidget(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + LanguageChangeEventWindow ww; + ww.show(); + QVERIFY(QTest::qWaitForWindowExposed(&ww)); + LanguageChangeEventWidget topLevelNotShown; + QTranslator t; + QVERIFY(t.load("hellotr_la.qm", ":/")); + QVERIFY(qApp->installTranslator(&t)); + QCoreApplication::sendPostedEvents(0, QEvent::LanguageChange); + QCOMPARE(topLevel.languageChangeCount, 1); + QCOMPARE(topLevelNotShown.languageChangeCount, 1); + QCOMPARE(childWidget->languageChangeCount, 1); + QCOMPARE(ww.languageChangeCount, 1); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v1.2.3 From 8c3cc07bf5254cb91b37a0000191871e9e32014e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 17 Feb 2020 15:08:58 +0100 Subject: widgets: Translate QWindow move events into widget relative position MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a widget backed by a QWindow is moved we need to translate the window geometry into a position relative to the parent widget. In most cases this was incidentally working due to widgets backed by QWindows always having QWindow parents too, so the QWindow position was applicable to the widget as well. But when Qt::WA_DontCreateNativeAncestors is used this is no longer the case, and we would end up with a widget geometry that included the parent positions all the way up to the next native widget. The updatePos() function has been squashed into handleMoveEvent(), since we need to ensure the position in the move event sent to the widget is correct as well. Change-Id: I55894ad7ab42a6d4d65e446a332ecdd7dcdcc263 Reviewed-by: Tor Arne Vestbø --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'tests/auto/widgets/kernel') diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index d8f4881ffa..31e77b2a62 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -310,6 +310,8 @@ private slots: void hideOpaqueChildWhileHidden(); void updateWhileMinimized(); void alienWidgets(); + void nativeWindowPosition_data(); + void nativeWindowPosition(); void adjustSize(); void adjustSize_data(); void updateGeometry(); @@ -8211,6 +8213,40 @@ void tst_QWidget::alienWidgets() } } +using WidgetAttributes = QVector; + +void tst_QWidget::nativeWindowPosition_data() +{ + QTest::addColumn("attributes"); + + QTest::newRow("non-native all the way") + << WidgetAttributes{}; + QTest::newRow("native all the way") + << WidgetAttributes{ Qt::WA_NativeWindow }; + QTest::newRow("native with non-native ancestor") + << WidgetAttributes{ Qt::WA_NativeWindow, Qt::WA_DontCreateNativeAncestors }; +} + +void tst_QWidget::nativeWindowPosition() +{ + QWidget topLevel; + QWidget child(&topLevel); + child.move(5, 5); + + QWidget grandChild(&child); + grandChild.move(10, 10); + + QFETCH(WidgetAttributes, attributes); + for (auto attribute : attributes) + grandChild.setAttribute(attribute); + + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + + QCOMPARE(child.pos(), QPoint(5, 5)); + QCOMPARE(grandChild.pos(), QPoint(10, 10)); +} + class ASWidget : public QWidget { public: -- cgit v1.2.3 From 1821f5163d160ccd5faf9c4b995e72a7ed762c9a Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Wed, 19 Feb 2020 14:11:12 +0100 Subject: Fix font and palette propagation for themed children created at runtime Widgets have a default palette and font that is influenced by several factors: theme, style, QApplication-wide overrides, and the parent's. If an application sets a font or palette on a parent, then widgets inherit those settings, no matter when they are added to the parent. The bug is that this is not true for widgets that have an application- wide override defined by the platform theme. For those, we need to merge parent palette and font attributes with the theme, and this is currently not done correctly, as the respective masks are not merged and inherited. This change fixes this for fonts and palettes. Children are inheriting their parent's inheritance masks, combined with the mask for the attributes set explicitly on the parent. This makes the font and palette resolving code correctly adopt those attributes that are set explicily, while leaving everything else as per the theme override. The test verifies that this works for children and grand children added to a widget that has a palette or font set, both when themed and unthemed. Children with own entries don't inherit from parent. The QFont::resetFont test had to be changed, as it was testing the wrong behavior. If the child would be added to the parent before the font property was set, then the test would have failed. Since this change makes sure that children inherit fonts in the same way, no matter on when they are added to their parent, the test is now modified to cover both cases, and ensures that they return identical results. [ChangeLog][QtWidgets][QWidget] Fonts and palette settings are inherited by children from their parents even if the children have application- wide platform theme overrides. Change-Id: I179a652b735e85bba3fafc30098d08d61684f488 Fixes: QTBUG-82125 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Qt CI Bot Reviewed-by: Vitaly Fanaskov --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 128 +++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) (limited to 'tests/auto/widgets/kernel') 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 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 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 testWidget(new QWidget); -- cgit v1.2.3