Toggling visibility of floating docked windows protected against external hide/show cycle by QWebEngineView. (#821)

Co-authored-by: AlbertoM <ma-robox@users.noreply.github.com>
This commit is contained in:
ma-robox
2026-03-10 18:34:45 +01:00
committed by GitHub
parent ee3a526adb
commit bbde511603

View File

@@ -370,13 +370,14 @@ struct FloatingDockContainerPrivate
eDragState DraggingState = DraggingInactive; eDragState DraggingState = DraggingInactive;
QPoint DragStartMousePosition; QPoint DragStartMousePosition;
CDockContainerWidget *DropContainer = nullptr; CDockContainerWidget *DropContainer = nullptr;
CDockAreaWidget *SingleDockArea = nullptr; CDockAreaWidget *SingleDockArea = nullptr;
QPoint DragStartPos; QPoint DragStartPos;
bool Hiding = false; bool Hiding = false;
bool AutoHideChildren = true; bool AutoHideChildren = true;
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) bool HideContentOnNextHide = false;
QWidget* MouseEventHandler = nullptr; #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
CFloatingWidgetTitleBar* TitleBar = nullptr; QWidget* MouseEventHandler = nullptr;
CFloatingWidgetTitleBar* TitleBar = nullptr;
bool IsResizing = false; bool IsResizing = false;
bool MousePressed = false; bool MousePressed = false;
#endif #endif
@@ -927,11 +928,11 @@ bool CFloatingDockContainer::nativeEvent(const QByteArray &eventType, void *mess
//============================================================================ //============================================================================
void CFloatingDockContainer::closeEvent(QCloseEvent *event) void CFloatingDockContainer::closeEvent(QCloseEvent *event)
{ {
ADS_PRINT("CFloatingDockContainer closeEvent"); ADS_PRINT("CFloatingDockContainer closeEvent");
d->setState(DraggingInactive); d->setState(DraggingInactive);
event->ignore(); event->ignore();
if (!isClosable()) if (!isClosable())
{ {
return; return;
@@ -959,37 +960,55 @@ void CFloatingDockContainer::closeEvent(QCloseEvent *event)
return; 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
// to "disappear". We therefore arm HideContentOnNextHide only for the
// explicit close path.
d->HideContentOnNextHide = true;
// In Qt version after 5.9.2 there seems to be a bug that causes the // 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 // QWidget::event() function to not receive any NonClientArea mouse
// events anymore after a close/show cycle. The bug is reported here: // events anymore after a close/show cycle. The bug is reported here:
// https://bugreports.qt.io/browse/QTBUG-73295 // https://bugreports.qt.io/browse/QTBUG-73295
// The following code is a workaround for Qt versions > 5.9.2 that seems // The following code is a workaround for Qt versions > 5.9.2 that seems
// to work // to work
// Starting from Qt version 5.12.2 this seems to work again. But // Starting from Qt version 5.12.2 this seems to work again. But
// now the QEvent::NonClientAreaMouseButtonPress function returns always // now the QEvent::NonClientAreaMouseButtonPress function returns always
// Qt::RightButton even if the left button was pressed // Qt::RightButton even if the left button was pressed
this->hide(); this->hide();
} }
//============================================================================ //============================================================================
void CFloatingDockContainer::hideEvent(QHideEvent *event) void CFloatingDockContainer::hideEvent(QHideEvent *event)
{ {
Super::hideEvent(event); Super::hideEvent(event);
if (event->spontaneous()) if (event->spontaneous())
{ {
return; return;
} }
// Prevent toogleView() events during restore state // Prevent toogleView() events during restore state
if (d->DockManager->isRestoringState()) if (d->DockManager->isRestoringState())
{ {
return; return;
} }
if ( d->AutoHideChildren ) // Only a close operation should propagate hide->toggleView(false) to
{ // child dock widgets. Generic hide/show cycles (e.g. from platform or
d->Hiding = true; // embedded native content) must not change dock open/closed state.
for ( auto DockArea : d->DockContainer->openedDockAreas() ) if (!d->HideContentOnNextHide)
{
return;
}
d->HideContentOnNextHide = false;
if ( d->AutoHideChildren )
{
d->Hiding = true;
for ( auto DockArea : d->DockContainer->openedDockAreas() )
{ {
for ( auto DockWidget : DockArea->openedDockWidgets() ) for ( auto DockWidget : DockArea->openedDockWidgets() )
{ {