From 86bceb4c48a5e995cc6b8449f73926c085aa9381 Mon Sep 17 00:00:00 2001 From: Sergio Martins Date: Fri, 14 Jan 2022 22:25:32 +0000 Subject: [PATCH] nested mdi: Fix detaching inner dock widgets Only the outter-most MDI frame is dragged in MDI mode. The inner ones are dragged in normal docking mode, they become real floating windows. --- src/private/TitleBar.cpp | 21 ++++++++++++++++++++- tests/tst_docks.cpp | 17 ++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/private/TitleBar.cpp b/src/private/TitleBar.cpp index 43fdf87c..e7c053d5 100644 --- a/src/private/TitleBar.cpp +++ b/src/private/TitleBar.cpp @@ -101,7 +101,26 @@ MainWindowBase *TitleBar::mainWindow() const bool TitleBar::isMDI() const { - return firstParentOfType(this) != nullptr; + QObject *p = const_cast(this); + while (p) { + if (qobject_cast(p)) { + // Ignore QObject hierarchies spanning though multiple windows + return false; + } + + if (qobject_cast(p)) + return true; + + if (qobject_cast(p)) { + // Note that the TitleBar can be inside a DropArea that's inside a MDIArea + // so we need this additional check + return false; + } + + p = p->parent(); + } + + return false; } void TitleBar::updateButtons() diff --git a/tests/tst_docks.cpp b/tests/tst_docks.cpp index 2e34002e..760d92b3 100644 --- a/tests/tst_docks.cpp +++ b/tests/tst_docks.cpp @@ -5095,12 +5095,12 @@ void TestDocks::tst_mdi_mixed_with_docking2() Frame *frame1 = mdiWidget1->d->frame(); Frame *mdiFrame1 = frame1->mdiFrame(); - QPointer dropArea1 = frame1->mdiDropAreaWrapper(); QPointer frame2 = mdiWidget2->d->frame(); QPointer mdiFrame2 = frame2->mdiFrame(); QPointer dropArea2 = frame2->mdiDropAreaWrapper(); + QPointer dropArea1 = frame1->mdiDropAreaWrapper(); dropArea1->addDockWidget(mdiWidget3, Location_OnLeft, nullptr); QVERIFY(!frame1->isMDI()); @@ -5191,6 +5191,21 @@ void TestDocks::tst_mdi_mixed_with_docking2() QVERIFY(Testing::waitForDeleted(mdiFrame1)); QCOMPARE(mdiArea->frames().size(), 0); + + // Dock again: + mdiArea->addDockWidget(mdiWidget1, QPoint(10, 10)); + mdiArea->addDockWidget(mdiWidget2, QPoint(50, 50)); + + frame1 = mdiWidget1->d->frame(); + dropArea1 = frame1->mdiDropAreaWrapper(); + dropArea1->addDockWidget(mdiWidget3, Location_OnLeft, nullptr); + + + // Detach an internal dock widget by dragging + const QPoint globalSrc = mdiWidget1->mapToGlobal(QPoint(5, 5)); + const QPoint globalDest = globalSrc + QPoint(10, 0); + drag(mdiWidget1, globalDest); + // QTest::qWait(100000); }