mirror of
https://github.com/quickshell-mirror/quickshell.git
synced 2026-10-27 02:54:36 +00:00
core/scriptmodel: handle reentrancy in ScriptModel::setValues
This commit is contained in:
3 files changed
+18
-4
No files matched your search
@@ -20,3 +20,4 @@
|
||||
- Fixed `PwNodePeakMonitor` crashing when sampling a stream with mismatched channels from the node.
|
||||
- Fixed unsetting `PopupAnchor.item` causing a crash.
|
||||
- Fixed hiding the last `PanelWindow` on screen causing a crash under X11.
|
||||
- Fixed crashes when `ScriptModel.values` is set while processing previously set values.
|
||||
@@ -16,7 +16,7 @@
|
||||
bool ScriptModel::updateValuesUnique(const QList<QJSValue>& newValues) {
|
||||
auto anyChanges = false;
|
||||
|
||||
this->hasActiveIterators = true;
|
||||
this->isModifying = true;
|
||||
this->mValues.reserve(newValues.size());
|
||||
|
||||
auto iter = this->mValues.begin();
|
||||
@@ -158,12 +158,24 @@ bool ScriptModel::updateValuesUnique(const QList<QJSValue>& newValues) {
|
||||
}
|
||||
}
|
||||
|
||||
this->hasActiveIterators = false;
|
||||
this->isModifying = false;
|
||||
|
||||
if (this->stagedValues.has_value()) {
|
||||
auto values = *this->stagedValues;
|
||||
this->stagedValues.reset();
|
||||
anyChanges |= this->updateValuesUnique(values);
|
||||
}
|
||||
|
||||
return anyChanges;
|
||||
}
|
||||
|
||||
void ScriptModel::setValues(const QList<QJSValue>& newValues) {
|
||||
// Re-entrant modification waits for the original modification to complete to avoid mishandled duplicates.
|
||||
if (this->isModifying) {
|
||||
this->stagedValues = newValues;
|
||||
return;
|
||||
}
|
||||
|
||||
auto changed = this->updateValuesUnique(newValues);
|
||||
if (changed) emit this->valuesChanged();
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
[[nodiscard]] QList<QJSValue> values() const {
|
||||
auto values = this->mValues;
|
||||
// If not detached, the QML engine will invalidate iterators in updateValuesUnique.
|
||||
if (this->hasActiveIterators) values.detach();
|
||||
if (this->isModifying) values.detach();
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,8 @@ signals:
|
||||
private:
|
||||
QList<QJSValue> mValues;
|
||||
QString cmpKey;
|
||||
bool hasActiveIterators = false;
|
||||
bool isModifying = false;
|
||||
std::optional<QList<QJSValue>> stagedValues;
|
||||
|
||||
bool updateValuesUnique(const QList<QJSValue>& newValues);
|
||||
};
|
||||
Reference in new issue
Block a user