diff --git a/src/controllers/DockWidget.cpp b/src/controllers/DockWidget.cpp index 975f7d2e..fed62e8b 100644 --- a/src/controllers/DockWidget.cpp +++ b/src/controllers/DockWidget.cpp @@ -680,6 +680,9 @@ void DockWidget::Private::updateToggleAction() void DockWidget::Private::updateFloatAction() { + if (m_willUpdateActions) + return; + QScopedValueRollback recursionGuard(m_updatingFloatAction, true); // Guard against recursiveness if (q->isFloating()) { diff --git a/src/controllers/DockWidget_p.h b/src/controllers/DockWidget_p.h index ce71ca29..87e14832 100644 --- a/src/controllers/DockWidget_p.h +++ b/src/controllers/DockWidget_p.h @@ -36,6 +36,27 @@ class SideBar; class DOCKS_EXPORT_FOR_UNIT_TESTS DockWidget::Private : public QObject /// clazy:exclude=missing-qobject-macro { public: + /// RAII class to help updating actions exactly once, otherwise they can be triggered in the middle + /// of operations during reparenting + struct UpdateActions + { + explicit UpdateActions(Controllers::DockWidget *dw) + : dw(dw) + { + dw->d->m_willUpdateActions = true; + } + + ~UpdateActions() + { + dw->d->m_willUpdateActions = false; + dw->d->updateFloatAction(); + } + + private: + Q_DISABLE_COPY(UpdateActions) + Controllers::DockWidget *const dw; + }; + Private(const QString &dockName, DockWidget::Options options_, LayoutSaverOptions layoutSaverOptions_, DockWidget *qq); @@ -175,7 +196,9 @@ public: bool m_isMovingToSideBar = false; QSize m_lastOverlayedSize = QSize(0, 0); int m_userType = 0; + bool m_willUpdateActions = false; }; + } } diff --git a/src/controllers/DropArea.cpp b/src/controllers/DropArea.cpp index fc928440..d0a885e4 100644 --- a/src/controllers/DropArea.cpp +++ b/src/controllers/DropArea.cpp @@ -169,6 +169,8 @@ void DropArea::addDockWidget(Controllers::DockWidget *dw, Location location, if (!validateAffinity(dw)) return; + Controllers::DockWidget::Private::UpdateActions actionsUpdater(dw); + Controllers::Frame *frame = nullptr; Controllers::Frame *relativeToFrame = relativeTo ? relativeTo->d->frame() : nullptr;