From 9bdefd60550e08893f3620c2ef76e26bb43989e0 Mon Sep 17 00:00:00 2001 From: Uwe Kindler Date: Tue, 16 Jan 2024 14:03:53 +0100 Subject: [PATCH] Fixed issue #597 - Crashes when the floating widget moves to the dock manager and then tries to drag it back --- src/DockContainerWidget.cpp | 11 ++++++++++- src/DockContainerWidget.h | 5 +++++ src/FloatingDockContainer.cpp | 9 +++++++-- src/FloatingDockContainer.h | 4 ++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/DockContainerWidget.cpp b/src/DockContainerWidget.cpp index 66218ba..0a4deaf 100644 --- a/src/DockContainerWidget.cpp +++ b/src/DockContainerWidget.cpp @@ -1643,6 +1643,15 @@ emitAndExit: } +//============================================================================ +QList> CDockContainerWidget::removeAllDockAreas() +{ + auto Result = d->DockAreas; + d->DockAreas.clear(); + return Result; +} + + //============================================================================ CDockAreaWidget* CDockContainerWidget::dockAreaAt(const QPoint& GlobalPos) const { @@ -1756,7 +1765,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi if (Dropped) { // Fix https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351 - FloatingWidget->hideAndDeleteLater(); + FloatingWidget->finishDropOperation(); // If we dropped a floating widget with only one single dock widget, then we // drop a top level widget that changes from floating to docked now diff --git a/src/DockContainerWidget.h b/src/DockContainerWidget.h index 3dd5243..4825f29 100644 --- a/src/DockContainerWidget.h +++ b/src/DockContainerWidget.h @@ -139,6 +139,11 @@ protected: */ void removeDockArea(CDockAreaWidget* area); + /** + * Remove all dock areas and returns the list of removed dock areas + */ + QList> removeAllDockAreas(); + /** * Saves the state into the given stream */ diff --git a/src/FloatingDockContainer.cpp b/src/FloatingDockContainer.cpp index 87f4053..f228476 100644 --- a/src/FloatingDockContainer.cpp +++ b/src/FloatingDockContainer.cpp @@ -776,7 +776,7 @@ CFloatingDockContainer::~CFloatingDockContainer() continue; } - // QPointer delete safety - just in case some dock wigdet in destruction + // QPointer delete safety - just in case some dock widget in destruction // deletes another related/twin or child dock widget. std::vector> deleteWidgets; for (auto widget : area->dockWidgets()) @@ -1167,7 +1167,7 @@ QList CFloatingDockContainer::dockWidgets() const } //============================================================================ -void CFloatingDockContainer::hideAndDeleteLater() +void CFloatingDockContainer::finishDropOperation() { // Widget has been redocked, so it must be hidden right way (see // https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351) @@ -1175,6 +1175,11 @@ void CFloatingDockContainer::hideAndDeleteLater() // dock widgets that shall not be toggled hidden. d->AutoHideChildren = false; hide(); + // The floating widget will be deleted now. Ensure, that the destructor + // of the floating widget does not delete any dock areas that have been + // moved to a new container - simply remove all dock areas before deleting + // the floating widget + d->DockContainer->removeAllDockAreas(); deleteLater(); if (d->DockManager) { diff --git a/src/FloatingDockContainer.h b/src/FloatingDockContainer.h index 333915f..2622767 100644 --- a/src/FloatingDockContainer.h +++ b/src/FloatingDockContainer.h @@ -258,9 +258,9 @@ public: QList dockWidgets() const; /** - * This function hides the floating bar instantely and delete it later. + * This function hides the floating widget instantly and delete it later. */ - void hideAndDeleteLater(); + void finishDropOperation(); #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) /**