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.
This commit is contained in:
outfoxxed 2024-11-29 00:11:56 -08:00
parent 59298f6507
commit 8882f7ca50
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
4 changed files with 32 additions and 0 deletions

View file

@ -131,6 +131,8 @@ void ProxyWindowBase::connectWindow() {
generation->registerIncubationController(this->window->incubationController()); generation->registerIncubationController(this->window->incubationController());
} }
this->window->setProxy(this);
// clang-format off // clang-format off
QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged); QObject::connect(this->window, &QWindow::visibilityChanged, this, &ProxyWindowBase::visibleChanged);
QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged); QObject::connect(this->window, &QWindow::xChanged, this, &ProxyWindowBase::xChanged);

View file

@ -168,6 +168,7 @@ public:
, mProxy(proxy) {} , mProxy(proxy) {}
[[nodiscard]] ProxyWindowBase* proxy() const { return this->mProxy; } [[nodiscard]] ProxyWindowBase* proxy() const { return this->mProxy; }
void setProxy(ProxyWindowBase* proxy) { this->mProxy = proxy; }
signals: signals:
void exposed(); void exposed();

View file

@ -2,6 +2,7 @@
#include <qobject.h> #include <qobject.h>
#include <qquickitem.h> #include <qquickitem.h>
#include <qscopedpointer.h>
#include <qsignalspy.h> #include <qsignalspy.h>
#include <qtest.h> #include <qtest.h>
#include <qtestcase.h> #include <qtestcase.h>
@ -36,6 +37,33 @@ void TestWindowAttachment::attachedBeforeReload() {
QCOMPARE(spy.length(), 1); 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() { void TestWindowAttachment::owningWindowChanged() {
auto window1 = ProxyWindowBase(); auto window1 = ProxyWindowBase();
auto window2 = ProxyWindowBase(); auto window2 = ProxyWindowBase();

View file

@ -9,6 +9,7 @@ class TestWindowAttachment: public QObject {
private slots: private slots:
static void attachedAfterReload(); static void attachedAfterReload();
static void attachedBeforeReload(); static void attachedBeforeReload();
static void earlyAttachReloaded();
static void owningWindowChanged(); static void owningWindowChanged();
static void nonItemParents(); static void nonItemParents();
}; };