aboutsummaryrefslogtreecommitdiffstats
path: root/sb_builder
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-20 12:35:36 +0200
committerDanilo M. <danix@danix.xyz>2026-10-20 12:35:36 +0200
commit77ac3ea8c1f365cf7d4691c7580d64d0e7c7c720 (patch)
treebbc601911aa009a1331ff74183e891527ca9df5c /sb_builder
parentf2bc23df84907a361e7d9fa20bf1bc8f7a916037 (diff)
downloadsb-builder-77ac3ea8c1f365cf7d4691c7580d64d0e7c7c720.tar.gz
sb-builder-77ac3ea8c1f365cf7d4691c7580d64d0e7c7c720.zip
Packages: fix segfault on Clear / Select visible behind a filter
Both emitted layoutChanged without layoutAboutToBeChanged; with a filter on and a current row, the proxy kept stale persistent indexes and Qt crashed (Ctrl+Shift+A with orphaned + cat:games closed the app). Only check states change, so the model now emits dataChanged on the box column. The new test segfaults on the old code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'sb_builder')
-rw-r--r--sb_builder/packages.py16
1 files changed, 12 insertions, 4 deletions
diff --git a/sb_builder/packages.py b/sb_builder/packages.py
index ab6f3ce..68de7c2 100644
--- a/sb_builder/packages.py
+++ b/sb_builder/packages.py
@@ -112,6 +112,16 @@ class Model(QAbstractTableModel):
self.checked &= names
self.endResetModel()
+ def boxes_changed(self):
+ """Only check states changed: dataChanged on the box column (count follows).
+
+ Not layoutChanged: emitted without layoutAboutToBeChanged it leaves the
+ filtering proxy with stale persistent indexes, and Qt segfaults.
+ """
+ if self.rows:
+ self.dataChanged.emit(self.index(0, 0), self.index(len(self.rows) - 1, 0),
+ [Qt.ItemDataRole.CheckStateRole])
+
def rowCount(self, parent=QModelIndex()):
return 0 if parent.isValid() else len(self.rows)
@@ -337,13 +347,11 @@ class PackagesTab(QWidget):
def select_visible(self):
for i in range(self.proxy.rowCount()):
self.model.checked.add(self.proxy.index(i, 0).data(Qt.ItemDataRole.UserRole)["name"])
- self.model.layoutChanged.emit()
- self.update_count()
+ self.model.boxes_changed()
def clear(self):
self.model.checked.clear()
- self.model.layoutChanged.emit()
- self.update_count()
+ self.model.boxes_changed()
def targets(self):
"""Ticked packages, sorted; the highlighted row alone is not a target."""