Unbind containers from DockManager to prevent accidental reuse before deletion (#823)
This commit is contained in:
committed by
GitHub
parent
bbde511603
commit
544c624f07
@@ -609,8 +609,7 @@ void CDockAreaWidget::removeDockWidget(CDockWidget* DockWidget)
|
||||
{
|
||||
if(CFloatingDockContainer* FloatingDockContainer = DockContainer->floatingWidget())
|
||||
{
|
||||
FloatingDockContainer->hide();
|
||||
FloatingDockContainer->deleteLater();
|
||||
FloatingDockContainer->finishDropOperation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2217,6 +2217,17 @@ CDockManager* CDockContainerWidget::dockManager() const
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockContainerWidget::removeFromDockManager()
|
||||
{
|
||||
if (d->DockManager)
|
||||
{
|
||||
d->DockManager->removeDockContainer(this);
|
||||
d->DockManager.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
void CDockContainerWidget::handleAutoHideWidgetEvent(QEvent* e, QWidget* w)
|
||||
{
|
||||
|
||||
@@ -86,6 +86,9 @@ private:
|
||||
friend AutoHideDockContainerPrivate;
|
||||
friend CAutoHideSideBar;
|
||||
|
||||
private Q_SLOTS:
|
||||
void removeFromDockManager();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Handles activation events to update zOrderIndex
|
||||
|
||||
@@ -768,7 +768,8 @@ void CDockManager::registerFloatingWidget(CFloatingDockContainer* FloatingWidget
|
||||
//============================================================================
|
||||
void CDockManager::removeFloatingWidget(CFloatingDockContainer* FloatingWidget)
|
||||
{
|
||||
d->FloatingWidgets.removeAll(FloatingWidget);
|
||||
int removed = d->FloatingWidgets.removeAll(FloatingWidget);
|
||||
Q_ASSERT(removed == 1);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
@@ -783,7 +784,8 @@ void CDockManager::removeDockContainer(CDockContainerWidget* DockContainer)
|
||||
{
|
||||
if (this != DockContainer)
|
||||
{
|
||||
d->Containers.removeAll(DockContainer);
|
||||
int removed = d->Containers.removeAll(DockContainer);
|
||||
Q_ASSERT(removed == 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -370,14 +370,14 @@ struct FloatingDockContainerPrivate
|
||||
eDragState DraggingState = DraggingInactive;
|
||||
QPoint DragStartMousePosition;
|
||||
CDockContainerWidget *DropContainer = nullptr;
|
||||
CDockAreaWidget *SingleDockArea = nullptr;
|
||||
QPoint DragStartPos;
|
||||
bool Hiding = false;
|
||||
bool AutoHideChildren = true;
|
||||
bool HideContentOnNextHide = false;
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
QWidget* MouseEventHandler = nullptr;
|
||||
CFloatingWidgetTitleBar* TitleBar = nullptr;
|
||||
CDockAreaWidget *SingleDockArea = nullptr;
|
||||
QPoint DragStartPos;
|
||||
bool Hiding = false;
|
||||
bool AutoHideChildren = true;
|
||||
bool HideContentOnNextHide = false;
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
|
||||
QWidget* MouseEventHandler = nullptr;
|
||||
CFloatingWidgetTitleBar* TitleBar = nullptr;
|
||||
bool IsResizing = false;
|
||||
bool MousePressed = false;
|
||||
#endif
|
||||
@@ -500,6 +500,9 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
return;
|
||||
}
|
||||
|
||||
// DockManager will be unlinked from this within DropContainer->dropFloatingWidget
|
||||
const auto OriginalDockManager = this->DockManager.data();
|
||||
|
||||
if (DockManager->dockAreaOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea
|
||||
|| DockManager->containerOverlay()->dropAreaUnderCursor() != InvalidDockWidgetArea)
|
||||
{
|
||||
@@ -533,8 +536,8 @@ void FloatingDockContainerPrivate::titleMouseReleaseEvent()
|
||||
DropContainer->dropFloatingWidget(_this, QCursor::pos());
|
||||
}
|
||||
|
||||
DockManager->containerOverlay()->hideOverlay();
|
||||
DockManager->dockAreaOverlay()->hideOverlay();
|
||||
OriginalDockManager->containerOverlay()->hideOverlay();
|
||||
OriginalDockManager->dockAreaOverlay()->hideOverlay();
|
||||
}
|
||||
|
||||
|
||||
@@ -928,11 +931,11 @@ bool CFloatingDockContainer::nativeEvent(const QByteArray &eventType, void *mess
|
||||
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
ADS_PRINT("CFloatingDockContainer closeEvent");
|
||||
d->setState(DraggingInactive);
|
||||
event->ignore();
|
||||
void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
ADS_PRINT("CFloatingDockContainer closeEvent");
|
||||
d->setState(DraggingInactive);
|
||||
event->ignore();
|
||||
if (!isClosable())
|
||||
{
|
||||
return;
|
||||
@@ -960,14 +963,14 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||
return;
|
||||
}
|
||||
|
||||
// New bug (QWebEngineView reload side effect):
|
||||
// when a WebEngine-based dock is tabified into a floating container, the
|
||||
// embedded native/web process can trigger delayed hide/show cycles on the
|
||||
// floating window. If every non-spontaneous hide propagates to
|
||||
// DockWidget->toggleView(false), unrelated tabs are marked closed and seem
|
||||
// New bug (QWebEngineView reload side effect):
|
||||
// when a WebEngine-based dock is tabified into a floating container, the
|
||||
// embedded native/web process can trigger delayed hide/show cycles on the
|
||||
// floating window. If every non-spontaneous hide propagates to
|
||||
// DockWidget->toggleView(false), unrelated tabs are marked closed and seem
|
||||
// to "disappear". We therefore arm HideContentOnNextHide only for the
|
||||
// explicit close path.
|
||||
d->HideContentOnNextHide = true;
|
||||
// explicit close path.
|
||||
d->HideContentOnNextHide = true;
|
||||
|
||||
// In Qt version after 5.9.2 there seems to be a bug that causes the
|
||||
// QWidget::event() function to not receive any NonClientArea mouse
|
||||
@@ -975,40 +978,40 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
|
||||
// https://bugreports.qt.io/browse/QTBUG-73295
|
||||
// The following code is a workaround for Qt versions > 5.9.2 that seems
|
||||
// to work
|
||||
// Starting from Qt version 5.12.2 this seems to work again. But
|
||||
// now the QEvent::NonClientAreaMouseButtonPress function returns always
|
||||
// Qt::RightButton even if the left button was pressed
|
||||
this->hide();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::hideEvent(QHideEvent *event)
|
||||
{
|
||||
Super::hideEvent(event);
|
||||
if (event->spontaneous())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Starting from Qt version 5.12.2 this seems to work again. But
|
||||
// now the QEvent::NonClientAreaMouseButtonPress function returns always
|
||||
// Qt::RightButton even if the left button was pressed
|
||||
this->hide();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
void CFloatingDockContainer::hideEvent(QHideEvent *event)
|
||||
{
|
||||
Super::hideEvent(event);
|
||||
if (event->spontaneous())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent toogleView() events during restore state
|
||||
if (d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only a close operation should propagate hide->toggleView(false) to
|
||||
// child dock widgets. Generic hide/show cycles (e.g. from platform or
|
||||
// embedded native content) must not change dock open/closed state.
|
||||
if (!d->HideContentOnNextHide)
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->HideContentOnNextHide = false;
|
||||
|
||||
if ( d->AutoHideChildren )
|
||||
{
|
||||
d->Hiding = true;
|
||||
for ( auto DockArea : d->DockContainer->openedDockAreas() )
|
||||
if (d->DockManager->isRestoringState())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Only a close operation should propagate hide->toggleView(false) to
|
||||
// child dock widgets. Generic hide/show cycles (e.g. from platform or
|
||||
// embedded native content) must not change dock open/closed state.
|
||||
if (!d->HideContentOnNextHide)
|
||||
{
|
||||
return;
|
||||
}
|
||||
d->HideContentOnNextHide = false;
|
||||
|
||||
if ( d->AutoHideChildren )
|
||||
{
|
||||
d->Hiding = true;
|
||||
for ( auto DockArea : d->DockContainer->openedDockAreas() )
|
||||
{
|
||||
for ( auto DockWidget : DockArea->openedDockWidgets() )
|
||||
{
|
||||
@@ -1220,8 +1223,9 @@ void CFloatingDockContainer::finishDropOperation()
|
||||
if (d->DockManager)
|
||||
{
|
||||
d->DockManager->removeFloatingWidget(this);
|
||||
d->DockManager->removeDockContainer(this->dockContainer());
|
||||
d->DockManager.clear();
|
||||
}
|
||||
this->dockContainer()->removeFromDockManager();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
Reference in New Issue
Block a user