Skip to content

Commit 32b0e02

Browse files
committed
Fixed case of corrupt layout when using setDockWidgetFactoryFunc()
If the factory returned null for some dock widget, then the layout would have holes. They need to be turned into placeholders, which will be invisible. Move the test into the QtWidgets guard. There's no point in making it agnostic, since the bug is in the layouting.
1 parent 392504e commit 32b0e02

File tree

4 files changed

+33
-26
lines changed

4 files changed

+33
-26
lines changed

src/LayoutSaver.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,16 @@ void LayoutSaver::Private::deleteEmptyFrames()
411411
// Delete their frame now.
412412

413413
for (auto frame : m_dockRegistry->frames()) {
414-
if (!frame->beingDeletedLater() && frame->isEmpty() && !frame->isCentralFrame())
414+
if (!frame->beingDeletedLater() && frame->isEmpty() && !frame->isCentralFrame()) {
415+
if (auto item = frame->layoutItem()) {
416+
item->turnIntoPlaceholder();
417+
} else {
418+
// This doesn't happen. But the warning will make the tests fail if there's a regression.
419+
qWarning() << Q_FUNC_INFO << "Expected item for frame";
420+
}
421+
415422
delete frame;
423+
}
416424
}
417425
}
418426

src/private/multisplitter/Item_p.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ class DOCKS_EXPORT_FOR_UNIT_TESTS Item : public QObject
306306
void ref();
307307
void unref();
308308
int refCount() const;
309+
void turnIntoPlaceholder();
309310

310311
int minLength(Qt::Orientation) const;
311312
int maxLengthHint(Qt::Orientation) const;
@@ -374,7 +375,6 @@ private Q_SLOTS:
374375
friend class ItemContainer;
375376
friend class ItemBoxContainer;
376377
friend class ItemFreeContainer;
377-
void turnIntoPlaceholder();
378378
bool eventFilter(QObject *o, QEvent *event) override;
379379
int m_refCount = 0;
380380
void updateObjectName();

tests/tst_docks.cpp

+22-23
Original file line numberDiff line numberDiff line change
@@ -5720,6 +5720,28 @@ void TestDocks::tst_overlayCrash()
57205720
pressOn(tb->mapToGlobal(QPoint(5, 5)), tb);
57215721
}
57225722

5723+
void TestDocks::tst_restoreWithIncompleteFactory()
5724+
{
5725+
EnsureTopLevelsDeleted e;
5726+
SetExpectedWarning ignoreWarning("Couldn't find dock widget");
5727+
KDDockWidgets::Config::self().setDockWidgetFactoryFunc([](const QString &name) -> KDDockWidgets::DockWidgetBase * {
5728+
if (name.contains(QStringLiteral("centralDockWidget")))
5729+
return nullptr;
5730+
5731+
auto w = createDockWidget(name, new QPushButton("1"), {}, {}, false);
5732+
w->setWidget(new QWidget());
5733+
return w;
5734+
});
5735+
5736+
auto m = createMainWindow(QSize(500, 500), MainWindowOption_None, "MainWindow1");
5737+
5738+
LayoutSaver saver;
5739+
saver.restoreFromFile(":/layouts/restoreWithIncompleteFactory.json");
5740+
5741+
auto layout = m->multiSplitter();
5742+
QCOMPARE(layout->separators().size(), 0);
5743+
}
5744+
57235745
void TestDocks::tst_embeddedMainWindow()
57245746
{
57255747
EnsureTopLevelsDeleted e;
@@ -7933,26 +7955,3 @@ void TestDocks::tst_crash326()
79337955
QEXPECT_FAIL("", "Bug #326, to be fixed", Continue);
79347956
QVERIFY(originalFrame != dock1->d->frame());
79357957
}
7936-
7937-
void TestDocks::tst_restoreWithIncompleteFactory()
7938-
{
7939-
EnsureTopLevelsDeleted e;
7940-
SetExpectedWarning ignoreWarning("Couldn't find dock widget");
7941-
KDDockWidgets::Config::self().setDockWidgetFactoryFunc([](const QString &name) -> KDDockWidgets::DockWidgetBase * {
7942-
if (name.contains(QStringLiteral("centralDockWidget")))
7943-
return nullptr;
7944-
7945-
auto w = new KDDockWidgets::DockWidget(name);
7946-
w->setWidget(new QWidget());
7947-
return w;
7948-
});
7949-
7950-
auto m = createMainWindow(QSize(500, 500), MainWindowOption_None, "MainWindow1");
7951-
7952-
LayoutSaver saver;
7953-
saver.restoreFromFile(":/layouts/restoreWithIncompleteFactory.json");
7954-
7955-
auto layout = m->multiSplitter();
7956-
QEXPECT_FAIL("", "To be fixed", Continue);
7957-
QCOMPARE(layout->separators().size(), 0);
7958-
}

tests/tst_docks.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ private Q_SLOTS:
248248
void tst_persistentCentralWidget();
249249
void tst_setFloatingWindowFlags();
250250
void tst_crash326();
251-
void tst_restoreWithIncompleteFactory();
252251

253252
#ifdef KDDOCKWIDGETS_QTWIDGETS
254253
// TODO: Port these to QtQuick
@@ -276,6 +275,7 @@ private Q_SLOTS:
276275
void tst_floatRemovesFromSideBar();
277276
void tst_overlayedGeometryIsSaved();
278277
void tst_overlayCrash();
278+
void tst_restoreWithIncompleteFactory();
279279

280280
// And fix these
281281
void tst_floatingWindowDeleted();

0 commit comments

Comments
 (0)