diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-11-13 10:54:11 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-11-17 11:39:18 +0100 |
commit | e0810d8052741f49d269514d40d683c45edfd975 (patch) | |
tree | d65d98dce58d665ee61cf91016230e978cb495f7 /src | |
parent | ca8b48ed6279fbfcc4a13c65cfe4baa9b70327f0 (diff) |
Avoid calling QQuickItemPrivate's methods if QQIP is incomplete
In QQuickWindow, we instantiate QQuickPaletteProviderPrivateBase, which
in turn instantiates its updateChildrenPalettes method, which then calls
QQuickItemPrivate::inheritPalette. However, QQIP is an incomplete type
at this point. Including qquickitemprivate_p.h would currently create a
cyclic dependency, and breaking that dependency might mean outlining
performance sensitive code.
Thus we instead (ab)use the fact that updateChildrenPalettes is virtual,
do nothing in the specialization for QQuickWindow and instead implement
the method in the same way as an override in QQuickWindowPrivate.
Task-number: QTBUG-88457
Change-Id: I49b357d7a67f1945a4d3c25e8cabd428d1454aa7
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickpaletteproviderprivatebase_p.h | 19 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquickwindow_p.h | 2 |
3 files changed, 27 insertions, 4 deletions
diff --git a/src/quick/items/qquickpaletteproviderprivatebase_p.h b/src/quick/items/qquickpaletteproviderprivatebase_p.h index 8f8251f251..a600a23ce6 100644 --- a/src/quick/items/qquickpaletteproviderprivatebase_p.h +++ b/src/quick/items/qquickpaletteproviderprivatebase_p.h @@ -344,10 +344,21 @@ void QQuickPaletteProviderPrivateBase<I, Impl>::setCurrentColorGroup() template<class I, class Impl> void QQuickPaletteProviderPrivateBase<I, Impl>::updateChildrenPalettes(const QPalette &parentPalette) { - if (auto root = rootItem(*itemWithPalette())) { - for (auto &&child : root->childItems()) { - if (Q_LIKELY(child)) { - getPrivate(*child)->inheritPalette(parentPalette); + if constexpr (std::is_same_v<QQuickWindow, I> && std::is_same_v<QQuickWindowPrivate, Impl>) { + /* QQuickWindowPrivate instantiates this template, but does not include QQuickItemPrivate + * This causes an error with the QQuickItemPrivate::inheritPalette call below on MSVC in + * static builds, as QQuickItemPrivate is incomplete. To work around this situation, we do + * nothing in this instantiation of updateChildrenPalettes and instead add an override in + * QQuickWindowPrivate, which does the correct thing. + */ + Q_UNREACHABLE(); // You are not supposed to call this function + return; + } else { + if (auto root = rootItem(*itemWithPalette())) { + for (auto &&child : root->childItems()) { + if (Q_LIKELY(child)) { + getPrivate(*child)->inheritPalette(parentPalette); + } } } } diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 0a23fa126a..d613b7e4f5 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -772,6 +772,16 @@ QQuickWindowPrivate::~QQuickWindowPrivate() service->removeWindow(q_func()); } +void QQuickWindowPrivate::updateChildrenPalettes(const QPalette &parentPalette) +{ + Q_Q(QQuickWindow); + if (auto root = q->contentItem()) { + for (auto &&child: root->childItems()) { + QQuickItemPrivate::get(child)->inheritPalette(parentPalette); + } + } +} + void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) { q_ptr = c; diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index 2928c99023..3be6f5cd8c 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -134,6 +134,8 @@ public: QQuickWindowPrivate(); ~QQuickWindowPrivate() override; + void updateChildrenPalettes(const QPalette &parentPalette) override; + void init(QQuickWindow *, QQuickRenderControl *control = nullptr); QQuickRootItem *contentItem; |