aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2023-08-22 18:17:50 +0800
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-08-28 11:47:49 +0000
commite0e618bc36400ba230efdf17cee81d4eb3732b9d (patch)
tree3de3b1d510766e2cf763f0941d8b1fee1855be9f
parent742c8bd1291040b23a1eecd3257a05686023e009 (diff)
Fix child popup palette inheritance
Qt Quick Controls Popups are always top-level popups, even if declared as a child of another popup. Therefore, e.g. a font set on a parent popup should not propagate to a child popup. The same behavior applies to palettes, but we regressed with this in 1875ad7f92cad270cc5857d71096a4b46c27c562 and/or 31f5c21ddb571d744efd1885c0687816b3a12225. This patch fixes the regression by returning the window's palette in QQuickPaletteProviderPrivateBase<I, Impl>::parentPalette() if I is a QQuickPopup. Fixes: QTBUG-115707 Change-Id: Ib89852787dd45e3edc9e846b6c182340c052f0fd Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 950cd5888e3098bc4c04fc0af4beabe265c78a6e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/quick/items/qquickpaletteproviderprivatebase_p.h21
-rw-r--r--tests/auto/quickcontrols/palette/data/childPopupInheritance.qml40
-rw-r--r--tests/auto/quickcontrols/palette/tst_palette.cpp38
3 files changed, 89 insertions, 10 deletions
diff --git a/src/quick/items/qquickpaletteproviderprivatebase_p.h b/src/quick/items/qquickpaletteproviderprivatebase_p.h
index a0e0302ea9..f374b64e30 100644
--- a/src/quick/items/qquickpaletteproviderprivatebase_p.h
+++ b/src/quick/items/qquickpaletteproviderprivatebase_p.h
@@ -230,9 +230,9 @@ template<class Impl, class I> decltype(auto) getPrivateImpl(I &t) { return Impl:
template <class T>
decltype(auto) getPrivate(T &item)
{
- if constexpr (std::is_same_v<T, QQuickWindow>) {
+ if constexpr (std::is_base_of_v<T, QQuickWindow>) {
return getPrivateImpl<QQuickWindowPrivate>(item);
- } else if constexpr (std::is_same_v<T, QQuickItem>) {
+ } else if constexpr (std::is_base_of_v<T, QQuickItem>) {
return getPrivateImpl<QQuickItemPrivate>(item);
} else {
static_assert (dependent_false<T>::value, "Extend please.");
@@ -257,12 +257,15 @@ template<class I, class Impl>
QPalette QQuickPaletteProviderPrivateBase<I, Impl>::parentPalette(const QPalette &fallbackPalette) const
{
if constexpr (!isRootWindow<I>()) {
- for (auto parentItem = itemWithPalette()->parentItem(); parentItem;
- parentItem = parentItem->parentItem()) {
-
- // Don't allocate a new palette here. Use only if it's already pre allocated
- if (parentItem && getPrivate(*parentItem)->providesPalette()) {
- return getPrivate(*parentItem)->palette()->toQPalette();
+ // Popups should always inherit from their window, even child popups: QTBUG-115707.
+ if (!std::is_base_of_v<QQuickPopup, I>) {
+ for (auto parentItem = itemWithPalette()->parentItem(); parentItem;
+ parentItem = parentItem->parentItem()) {
+
+ // Don't allocate a new palette here. Use only if it's already pre allocated
+ if (parentItem && getPrivate(*parentItem)->providesPalette()) {
+ return getPrivate(*parentItem)->palette()->toQPalette();
+ }
}
}
@@ -279,7 +282,7 @@ const QQuickItem* rootItem(const I &item)
{
if constexpr (isRootWindow<I>()) {
return item.contentItem();
- } else if constexpr (std::is_same_v<QQuickPopup, I>) {
+ } else if constexpr (std::is_base_of_v<QQuickPopup, I>) {
return nullptr;
} else {
return &item;
diff --git a/tests/auto/quickcontrols/palette/data/childPopupInheritance.qml b/tests/auto/quickcontrols/palette/data/childPopupInheritance.qml
new file mode 100644
index 0000000000..4c160db092
--- /dev/null
+++ b/tests/auto/quickcontrols/palette/data/childPopupInheritance.qml
@@ -0,0 +1,40 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls
+
+ApplicationWindow {
+ id: window
+
+ Popup {
+ id: parentPopup
+ objectName: "parentPopup"
+ palette.windowText: "#ffdead"
+
+ Label {
+ text: "parentPopupLabel"
+ objectName: text
+ }
+
+ Popup {
+ id: childPopup
+ objectName: "childPopup"
+
+ Label {
+ text: "childPopupLabel"
+ objectName: text
+ }
+
+ Popup {
+ id: grandchildPopup
+ objectName: "grandchildPopup"
+
+ Label {
+ text: "grandchildPopupLabel"
+ objectName: text
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quickcontrols/palette/tst_palette.cpp b/tests/auto/quickcontrols/palette/tst_palette.cpp
index e3a53f0c21..52f2502bf0 100644
--- a/tests/auto/quickcontrols/palette/tst_palette.cpp
+++ b/tests/auto/quickcontrols/palette/tst_palette.cpp
@@ -7,6 +7,7 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickControlsTestUtils/private/controlstestutils_p.h>
#include <QtQuick/private/qquickitem_p.h>
#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
#include <QtQuickTemplates2/private/qquickcontrol_p.h>
@@ -17,7 +18,7 @@
#include <QtQuickTemplates2/private/qquickbutton_p.h>
#include <QtQuickControls2/qquickstyle.h>
-//using namespace QQuickVisualTestUtils;
+using namespace QQuickControlsTestUtils;
// Need a more descriptive failure message: QTBUG-87039
#define COMPARE_PALETTES(actualPalette, expectedPalette) \
@@ -40,6 +41,7 @@ private slots:
void inheritance_data();
void inheritance();
+ void childPopupInheritance();
void defaultPalette_data();
void defaultPalette();
@@ -203,6 +205,40 @@ void tst_palette::inheritance()
QCOMPARE(grandChildPalette->window(), windowPalette->window());
}
+// The child popups in inheritance() don't test actual nested child popups,
+// only popups that are children of items and the items within those popups.
+// We need to specifically test this to prevent QTBUG-115707 from happening again.
+void tst_palette::childPopupInheritance()
+{
+ QQuickControlsApplicationHelper helper(this, QLatin1String("childPopupInheritance.qml"));
+ QVERIFY2(helper.ready, helper.failureMessage());
+
+ const auto *windowPrivate = QQuickWindowPrivate::get(helper.window);
+ const auto windowsWindowTextColor = windowPrivate->palette()->toQPalette().color(QPalette::WindowText);
+
+ // parentPopup sets windowText explicitly, so its label should use that color.
+ auto *parentPopup = helper.appWindow->findChild<QQuickPopup *>("parentPopup");
+ QVERIFY(parentPopup);
+ parentPopup->open();
+ QTRY_VERIFY(parentPopup->isOpened());
+ auto *parentPopupLabel = helper.appWindow->findChild<QObject *>("parentPopupLabel");
+ QVERIFY(parentPopupLabel);
+ QCOMPARE(parentPopupLabel->property("color").value<QColor>(), "#ffdead");
+
+ // All other child popups don't set anything explicitly, and should inherit from their window.
+ auto *childPopup = helper.appWindow->findChild<QQuickPopup *>("childPopup");
+ QVERIFY(childPopup);
+ auto *childPopupLabel = helper.appWindow->findChild<QObject *>("childPopupLabel");
+ QVERIFY(childPopupLabel);
+ QCOMPARE(childPopupLabel->property("color").value<QColor>(), windowsWindowTextColor);
+
+ auto *grandchildPopup = helper.appWindow->findChild<QQuickPopup *>("grandchildPopup");
+ QVERIFY(grandchildPopup);
+ auto *grandchildPopupLabel = helper.appWindow->findChild<QObject *>("grandchildPopupLabel");
+ QVERIFY(grandchildPopupLabel);
+ QCOMPARE(grandchildPopupLabel->property("color").value<QColor>(), windowsWindowTextColor);
+}
+
class TestTheme : public QQuickTheme
{
public: