From 8882f7ca5037d6b8f36735c620648ab0efdd4d81 Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Fri, 29 Nov 2024 00:11:56 -0800 Subject: [PATCH] core/proxywindow: fix ProxiedWindow proxy pointer after reload Previously was not updated after reload, causing QsWindowAttached to use the old window pointer after it had been freed. --- src/window/proxywindow.cpp | 2 ++ src/window/proxywindow.hpp | 1 + src/window/test/windowattached.cpp | 28 ++++++++++++++++++++++++++++ src/window/test/windowattached.hpp | 1 + 4 files changed, 32 insertions(+) diff --git a/src/window/proxywindow.cpp b/src/window/proxywindow.cpp index e73a1ae1..707a05e1 100644 --- a/src/window/proxywindow.cpp +++ b/src/window/proxywindow.cpp @@ -131,6 +131,8 @@ void ProxyWindowBase::connectWindow() { generation->registerIncubationController(this->window->incubationController()); } + this->window->setProxy(this); + // clang-format off QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged); QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged); diff --git a/src/window/proxywindow.hpp b/src/window/proxywindow.hpp index 737e2ea6..14c90339 100644 --- a/src/window/proxywindow.hpp +++ b/src/window/proxywindow.hpp @@ -168,6 +168,7 @@ public: , mProxy(proxy) {} [[nodiscard]] ProxyWindowBase* proxy() const { return this->mProxy; } + void setProxy(ProxyWindowBase* proxy) { this->mProxy = proxy; } signals: void exposed(); diff --git a/src/window/test/windowattached.cpp b/src/window/test/windowattached.cpp index 112c2ba9..ef2d47e4 100644 --- a/src/window/test/windowattached.cpp +++ b/src/window/test/windowattached.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,33 @@ void TestWindowAttachment::attachedBeforeReload() { QCOMPARE(spy.length(), 1); } +void TestWindowAttachment::earlyAttachReloaded() { + auto window1 = QScopedPointer(new ProxyWindowBase()); + auto item1 = QScopedPointer(new QQuickItem()); + item1->setParentItem(window1->contentItem()); + window1->reload(nullptr); + + auto window2 = ProxyWindowBase(); + auto item2 = QQuickItem(); + item2.setParentItem(window2.contentItem()); + + auto* attached = WindowInterface::qmlAttachedProperties(&item2); + QCOMPARE_NE(attached, nullptr); + QCOMPARE(attached->window(), nullptr); + + auto spy = QSignalSpy(attached, &QsWindowAttached::windowChanged); + window2.reload(window1.get()); + + QCOMPARE(attached->window(), &window2); + QCOMPARE(spy.length(), 1); + + item1.reset(); + window1.reset(); + + QCOMPARE(attached->window(), &window2); + QCOMPARE(spy.length(), 1); +} + void TestWindowAttachment::owningWindowChanged() { auto window1 = ProxyWindowBase(); auto window2 = ProxyWindowBase(); diff --git a/src/window/test/windowattached.hpp b/src/window/test/windowattached.hpp index 1b15261e..89b3bf76 100644 --- a/src/window/test/windowattached.hpp +++ b/src/window/test/windowattached.hpp @@ -9,6 +9,7 @@ class TestWindowAttachment: public QObject { private slots: static void attachedAfterReload(); static void attachedBeforeReload(); + static void earlyAttachReloaded(); static void owningWindowChanged(); static void nonItemParents(); };