Fixed issue #597 - Crashes when the floating widget moves to the dock manager and then tries to drag it back

This commit is contained in:
Uwe Kindler 2024-01-16 14:03:53 +01:00
parent 8fd691968c
commit 9bdefd6055
4 changed files with 24 additions and 5 deletions

View File

@ -1643,6 +1643,15 @@ emitAndExit:
} }
//============================================================================
QList<QPointer<CDockAreaWidget>> CDockContainerWidget::removeAllDockAreas()
{
auto Result = d->DockAreas;
d->DockAreas.clear();
return Result;
}
//============================================================================ //============================================================================
CDockAreaWidget* CDockContainerWidget::dockAreaAt(const QPoint& GlobalPos) const CDockAreaWidget* CDockContainerWidget::dockAreaAt(const QPoint& GlobalPos) const
{ {
@ -1756,7 +1765,7 @@ void CDockContainerWidget::dropFloatingWidget(CFloatingDockContainer* FloatingWi
if (Dropped) if (Dropped)
{ {
// Fix https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351 // 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 // 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 // drop a top level widget that changes from floating to docked now

View File

@ -139,6 +139,11 @@ protected:
*/ */
void removeDockArea(CDockAreaWidget* area); void removeDockArea(CDockAreaWidget* area);
/**
* Remove all dock areas and returns the list of removed dock areas
*/
QList<QPointer<CDockAreaWidget>> removeAllDockAreas();
/** /**
* Saves the state into the given stream * Saves the state into the given stream
*/ */

View File

@ -776,7 +776,7 @@ CFloatingDockContainer::~CFloatingDockContainer()
continue; 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. // deletes another related/twin or child dock widget.
std::vector<QPointer<QWidget>> deleteWidgets; std::vector<QPointer<QWidget>> deleteWidgets;
for (auto widget : area->dockWidgets()) for (auto widget : area->dockWidgets())
@ -1167,7 +1167,7 @@ QList<CDockWidget*> CFloatingDockContainer::dockWidgets() const
} }
//============================================================================ //============================================================================
void CFloatingDockContainer::hideAndDeleteLater() void CFloatingDockContainer::finishDropOperation()
{ {
// Widget has been redocked, so it must be hidden right way (see // Widget has been redocked, so it must be hidden right way (see
// https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System/issues/351) // 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. // dock widgets that shall not be toggled hidden.
d->AutoHideChildren = false; d->AutoHideChildren = false;
hide(); 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(); deleteLater();
if (d->DockManager) if (d->DockManager)
{ {

View File

@ -258,9 +258,9 @@ public:
QList<CDockWidget*> dockWidgets() const; QList<CDockWidget*> 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) #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
/** /**