fix: prevent segfault and CDockManager teardown crashes with PySide6 6.11.0

- bec_widget.py: set _destroyed=True BEFORE calling cleanup() so the flag
  is available throughout the entire teardown phase
- bec_console.py: in _parking_parent, skip console.window() as parking
  target when the window is marked as _destroyed, preventing setParent()
  into a widget mid-destruction (segfault in PySide6 6.11.0)
- basic_dock_area.py: add DockAreaWidget.cleanup() that calls delete_all()
  first to release CDockWidgets via the Qt ADS API before BECWidget.cleanup()
  runs, fixing teardown crashes with PySide6-QtAds 4.5.x
This commit is contained in:
copilot-swe-agent[bot]
2026-05-30 13:40:20 +00:00
committed by GitHub
parent f4d51b6287
commit d44eb69a92
3 changed files with 17 additions and 2 deletions
+1 -1
View File
@@ -362,7 +362,7 @@ class BECWidget(BECConnector):
"""Wrap the close even to ensure the rpc_register is cleaned up."""
try:
if not self._destroyed:
self.cleanup()
self._destroyed = True
self.cleanup()
finally:
super().closeEvent(event) # pylint: disable=no-member
@@ -1465,6 +1465,16 @@ class DockAreaWidget(BECWidget, QWidget):
for dock in self.dock_list():
self._delete_dock(dock)
def cleanup(self):
"""Tear down all docks via the Qt ADS API before the base BECWidget cleanup runs.
Explicitly releasing dock widgets through the CDockManager API first prevents crashes
in PySide6 6.11.0 / PySide6-QtAds 4.5.x where the CDockManager destructor interacts
badly with dock widgets that are deleted outside of it.
"""
self.delete_all()
super().cleanup()
if __name__ == "__main__": # pragma: no cover
import sys
@@ -120,7 +120,12 @@ class BecConsoleRegistry:
return None
window = console.window()
if window is not None and window is not console and self._is_valid_qobject(window):
if (
window is not None
and window is not console
and self._is_valid_qobject(window)
and not getattr(window, "_destroyed", False)
):
return window
if not avoid_console: