From f4d51b628744d317ca2791f3bfdcb9fe2c0ce7e3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 12:19:12 +0000 Subject: [PATCH 1/2] feat: update PySide6 to 6.11.0 and PySide6-QtAds to 4.5.0.4 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 499fa7765..7767d77de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,8 +10,8 @@ classifiers = [ ] dependencies = [ "PyJWT~=2.9", - "PySide6==6.9.0", - "PySide6-QtAds==4.4.0", + "PySide6==6.11.0", + "PySide6-QtAds==4.5.0.4", "bec_ipython_client~=3.107,>=3.107.2", # needed for jupyter console "bec_lib~=3.107,>=3.107.2", "bec_qthemes~=1.0, >=1.3.4", 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 2/2] 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 d1d996560..0d45dd9e3 100644 --- a/bec_widgets/utils/bec_widget.py +++ b/bec_widgets/utils/bec_widget.py @@ -362,7 +362,7 @@ def closeEvent(self, event): """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 088050ae9..81fff4154 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 @@ def delete_all(self): 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 87f3ff81b..df14c2b6e 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 @@ def _parking_parent( 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: