diff --git a/src/private/multisplitter/Item.cpp b/src/private/multisplitter/Item.cpp index 931fe459..4123a03e 100644 --- a/src/private/multisplitter/Item.cpp +++ b/src/private/multisplitter/Item.cpp @@ -918,6 +918,12 @@ struct ItemContainer::Private (void) Config::self(); // Ensure Config ctor runs, as it registers qml types } + ~Private() + { + qDeleteAll(m_separators); + m_separators.clear(); + } + int defaultLengthFor(Item *item, DefaultSizeMode) const; bool isOverflowing() const; void relayoutIfNeeded(); diff --git a/src/private/multisplitter/Separator.cpp b/src/private/multisplitter/Separator.cpp index 05fa6347..b2bf6cae 100644 --- a/src/private/multisplitter/Separator.cpp +++ b/src/private/multisplitter/Separator.cpp @@ -25,6 +25,9 @@ using namespace Layouting; Separator* Separator::s_separatorBeingDragged = nullptr; +/// @brief internal counter just for unit-tests +static int s_numSeparators = 0; + struct Separator::Private { // Only set when anchor is moved through mouse. Side1 if going towards left or top, Side2 otherwise. @@ -46,10 +49,12 @@ struct Separator::Private Separator::Separator(Widget *hostWidget) : d(new Private(hostWidget)) { + s_numSeparators++; } Separator::~Separator() { + s_numSeparators--; delete d; if (isBeingDragged()) s_separatorBeingDragged = nullptr; @@ -216,6 +221,11 @@ bool Separator::isResizing() return s_separatorBeingDragged != nullptr; } +int Separator::numSeparators() +{ + return s_numSeparators; +} + void Separator::setLazyPosition(int pos) { if (d->lazyPosition != pos) { diff --git a/src/private/multisplitter/Separator_p.h b/src/private/multisplitter/Separator_p.h index a799cdac..8a408624 100644 --- a/src/private/multisplitter/Separator_p.h +++ b/src/private/multisplitter/Separator_p.h @@ -47,6 +47,10 @@ public: static bool isResizing(); virtual Widget* asWidget() = 0; + /// @internal Just for the unit-tests. + /// Returns the total amount of Separator() instances currently alive. + static int numSeparators(); + protected: explicit Separator(Widget *hostWidget); virtual Widget* createRubberBand(Widget *parent) { Q_UNUSED(parent); return nullptr; } diff --git a/tests/tst_common.cpp b/tests/tst_common.cpp index 281cc512..3411b5b1 100644 --- a/tests/tst_common.cpp +++ b/tests/tst_common.cpp @@ -62,6 +62,7 @@ private Q_SLOTS: void tst_doesntHaveNativeTitleBar(); void tst_resizeWindow2(); void tst_hasLastDockedLocation(); + void tst_ghostSeparator(); }; void TestCommon::tst_simple1() @@ -142,6 +143,36 @@ void TestCommon::tst_hasLastDockedLocation() delete window1; } +void TestCommon::tst_ghostSeparator() +{ + // Tests a situation where a separator wouldn't be removed after a widget had been removed + EnsureTopLevelsDeleted e; + auto m = createMainWindow(QSize(501, 500), MainWindowOption_None); + auto dock1 = createDockWidget("1"); + auto dock2 = createDockWidget("2"); + auto dock3 = createDockWidget("3"); + + QPointer fw1 = dock1->floatingWindow(); + QPointer fw2 = dock2->floatingWindow(); + QPointer fw3 = dock3->floatingWindow(); + + dock1->addDockWidgetToContainingWindow(dock2, Location_OnRight); + QCOMPARE(fw1->multiSplitter()->separators().size(), 1); + QCOMPARE(Layouting::Separator::numSeparators(), 1); + + m->addDockWidget(dock3, Location_OnBottom); + QCOMPARE(m->multiSplitter()->separators().size(), 0); + QCOMPARE(Layouting::Separator::numSeparators(), 1); + + m->multiSplitter()->addMultiSplitter(fw1->multiSplitter(), Location_OnRight); + QCOMPARE(m->multiSplitter()->separators().size(), 2); + QCOMPARE(Layouting::Separator::numSeparators(), 2); + + delete fw1; + delete fw2; + delete fw3; +} + int main(int argc, char *argv[]) { if (!qpaPassedAsArgument(argc, argv)) {