From d44eb69a9221bfa1556955ad694a6dbc5bd0784e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 30 May 2026 13:40:20 +0000 Subject: [PATCH] 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 --- bec_widgets/utils/bec_widget.py | 2 +- .../widgets/containers/dock_area/basic_dock_area.py | 10 ++++++++++ bec_widgets/widgets/editors/bec_console/bec_console.py | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/bec_widgets/utils/bec_widget.py b/bec_widgets/utils/bec_widget.py index d1d99656..0d45dd9e 100644 --- a/bec_widgets/utils/bec_widget.py +++ b/bec_widgets/utils/bec_widget.py @@ -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 diff --git a/bec_widgets/widgets/containers/dock_area/basic_dock_area.py b/bec_widgets/widgets/containers/dock_area/basic_dock_area.py index 088050ae..81fff415 100644 --- a/bec_widgets/widgets/containers/dock_area/basic_dock_area.py +++ b/bec_widgets/widgets/containers/dock_area/basic_dock_area.py @@ -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 diff --git a/bec_widgets/widgets/editors/bec_console/bec_console.py b/bec_widgets/widgets/editors/bec_console/bec_console.py index 87f3ff81..df14c2b6 100644 --- a/bec_widgets/widgets/editors/bec_console/bec_console.py +++ b/bec_widgets/widgets/editors/bec_console/bec_console.py @@ -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: