forked from quickshell/quickshell
core/transformwatcher: fix crash when a or b is destroyed
Usually happens during reload.
This commit is contained in:
parent
b5b9c1f6c3
commit
67783ec24c
|
@ -82,7 +82,10 @@ void TransformWatcher::linkItem(QQuickItem* item) const {
|
||||||
|
|
||||||
QObject::connect(item, &QQuickItem::parentChanged, this, &TransformWatcher::recalcChains);
|
QObject::connect(item, &QQuickItem::parentChanged, this, &TransformWatcher::recalcChains);
|
||||||
QObject::connect(item, &QQuickItem::windowChanged, this, &TransformWatcher::recalcChains);
|
QObject::connect(item, &QQuickItem::windowChanged, this, &TransformWatcher::recalcChains);
|
||||||
QObject::connect(item, &QObject::destroyed, this, &TransformWatcher::recalcChains);
|
|
||||||
|
if (item != this->mA && item != this->mB) {
|
||||||
|
QObject::connect(item, &QObject::destroyed, this, &TransformWatcher::itemDestroyed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformWatcher::linkChains() {
|
void TransformWatcher::linkChains() {
|
||||||
|
@ -103,6 +106,18 @@ void TransformWatcher::unlinkChains() {
|
||||||
for (auto* item: this->childChain) {
|
for (auto* item: this->childChain) {
|
||||||
QObject::disconnect(item, nullptr, this, nullptr);
|
QObject::disconnect(item, nullptr, this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// relink a and b destruction notifications
|
||||||
|
if (this->mA != nullptr) {
|
||||||
|
QObject::connect(this->mA, &QObject::destroyed, this, &TransformWatcher::aDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->mB != nullptr) {
|
||||||
|
QObject::connect(this->mB, &QObject::destroyed, this, &TransformWatcher::bDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->parentChain.clear();
|
||||||
|
this->childChain.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TransformWatcher::recalcChains() {
|
void TransformWatcher::recalcChains() {
|
||||||
|
@ -111,26 +126,57 @@ void TransformWatcher::recalcChains() {
|
||||||
this->linkChains();
|
this->linkChains();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransformWatcher::itemDestroyed() {
|
||||||
|
auto destroyed =
|
||||||
|
this->parentChain.removeOne(this->sender()) || this->childChain.removeOne(this->sender());
|
||||||
|
|
||||||
|
if (destroyed) this->recalcChains();
|
||||||
|
}
|
||||||
|
|
||||||
QQuickItem* TransformWatcher::a() const { return this->mA; }
|
QQuickItem* TransformWatcher::a() const { return this->mA; }
|
||||||
|
|
||||||
void TransformWatcher::setA(QQuickItem* a) {
|
void TransformWatcher::setA(QQuickItem* a) {
|
||||||
if (this->mA == a) return;
|
if (this->mA == a) return;
|
||||||
|
if (this->mA != nullptr) QObject::disconnect(this->mA, nullptr, this, nullptr);
|
||||||
this->mA = a;
|
this->mA = a;
|
||||||
|
|
||||||
|
if (this->mA != nullptr) {
|
||||||
|
QObject::connect(this->mA, &QObject::destroyed, this, &TransformWatcher::aDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
this->recalcChains();
|
this->recalcChains();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransformWatcher::aDestroyed() {
|
||||||
|
this->mA = nullptr;
|
||||||
|
this->unlinkChains();
|
||||||
|
emit this->aChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QQuickItem* TransformWatcher::b() const { return this->mB; }
|
QQuickItem* TransformWatcher::b() const { return this->mB; }
|
||||||
|
|
||||||
void TransformWatcher::setB(QQuickItem* b) {
|
void TransformWatcher::setB(QQuickItem* b) {
|
||||||
if (this->mB == b) return;
|
if (this->mB == b) return;
|
||||||
|
if (this->mB != nullptr) QObject::disconnect(this->mB, nullptr, this, nullptr);
|
||||||
this->mB = b;
|
this->mB = b;
|
||||||
|
|
||||||
|
if (this->mB != nullptr) {
|
||||||
|
QObject::connect(this->mB, &QObject::destroyed, this, &TransformWatcher::bDestroyed);
|
||||||
|
}
|
||||||
|
|
||||||
this->recalcChains();
|
this->recalcChains();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TransformWatcher::bDestroyed() {
|
||||||
|
this->mB = nullptr;
|
||||||
|
this->unlinkChains();
|
||||||
|
emit this->bChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QQuickItem* TransformWatcher::commonParent() const { return this->mCommonParent; }
|
QQuickItem* TransformWatcher::commonParent() const { return this->mCommonParent; }
|
||||||
|
|
||||||
void TransformWatcher::setCommonParent(QQuickItem* commonParent) {
|
void TransformWatcher::setCommonParent(QQuickItem* commonParent) {
|
||||||
if (this->mCommonParent == commonParent) return;
|
if (this->mCommonParent == commonParent) return;
|
||||||
this->mCommonParent = commonParent;
|
this->mCommonParent = commonParent;
|
||||||
this->resolveChains();
|
this->recalcChains();
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,9 @@ signals:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void recalcChains();
|
void recalcChains();
|
||||||
|
void itemDestroyed();
|
||||||
|
void aDestroyed();
|
||||||
|
void bDestroyed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void resolveChains(QQuickItem* a, QQuickItem* b, QQuickItem* commonParent);
|
void resolveChains(QQuickItem* a, QQuickItem* b, QQuickItem* commonParent);
|
||||||
|
|
Loading…
Reference in a new issue