diff --git a/src/DockManager.cpp b/src/DockManager.cpp index a7c639e57..0719e702a 100644 --- a/src/DockManager.cpp +++ b/src/DockManager.cpp @@ -548,16 +548,16 @@ CDockManager::CDockManager(QWidget *parent) : return; } - // If the user clicks the main window or drags a floating widget or works with a - // modal dialog, then raise the main window, all floating widgets and the focus window - // itself to bring it into foreground of any other application. - bool raise = qobject_cast(widget) - || qobject_cast(widget); - if (auto dialog = qobject_cast(widget)) - { - raise |= dialog->isModal(); - } - if (!raise) + // Only restack windows while a floating dock widget is actively being dragged. + // Reacting to ordinary focus changes makes this handler raise() multiple + // top-level windows, which can transfer focus and re-emit focusWindowChanged, + // re-entering this handler in a self-sustaining loop that never settles - + // visible as constant flicker on Linux/X11. Gating on an + // active drag breaks that loop: outside a drag we do nothing. + const bool draggingActive = std::any_of( + d->FloatingWidgets.begin(), d->FloatingWidgets.end(), + [](CFloatingDockContainer* fw){ return fw && fw->isDraggingActive(); }); + if (!draggingActive) { return; } diff --git a/src/FloatingDockContainer.cpp b/src/FloatingDockContainer.cpp index 257974caa..408bbbf0a 100644 --- a/src/FloatingDockContainer.cpp +++ b/src/FloatingDockContainer.cpp @@ -817,6 +817,12 @@ CDockContainerWidget* CFloatingDockContainer::dockContainer() const return d->DockContainer; } +//============================================================================ +bool CFloatingDockContainer::isDraggingActive() const +{ + return d->isState(DraggingFloatingWidget); +} + //============================================================================ void CFloatingDockContainer::changeEvent(QEvent *event) { diff --git a/src/FloatingDockContainer.h b/src/FloatingDockContainer.h index 284e30ad5..52991cc29 100644 --- a/src/FloatingDockContainer.h +++ b/src/FloatingDockContainer.h @@ -269,6 +269,11 @@ private Q_SLOTS: */ void finishDropOperation(); + /** + * Returns true while this floating widget is actively being dragged. + */ + bool isDraggingActive() const; + #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) /** * This is a function that responds to FloatingWidgetTitleBar::maximizeRequest()