After restoring a placeholder we need to ensure all anchors are bounded

We only ensure the ones next to our item are bounded, but there can be
indirect ones that were holding items that now must shrink
This commit is contained in:
Sergio Martins
2019-08-12 11:29:45 +01:00
parent 47ff3869f1
commit 3385b6c15c
5 changed files with 65 additions and 0 deletions

View File

@@ -281,6 +281,22 @@ int Anchor::smallestAvailableItemSqueeze(Anchor::Side side) const
return smallest;
}
void Anchor::ensureBounded()
{
if (!isStatic()) {
const QPair<int,int> bounds = m_layout->boundPositionsForAnchor(this);
if (position() < bounds.first) {
setPosition(bounds.first);
} else if (position() > bounds.second) {
setPosition(bounds.second);
}
}
for (Item *item : items(Side2)) {
item->anchorAtSide(Side2, orientation())->ensureBounded();
}
}
int Anchor::length() const
{
Q_ASSERT(m_to);

View File

@@ -143,6 +143,8 @@ public:
void setVisible(bool);
qreal positionPercentage() const { return m_positionPercentage; }
void ensureBounded();
/**
* @brief Sets the new layout. Called when we're dropping a source layout into a target one.
* The target one will steal the separators of the source one.

View File

@@ -422,6 +422,13 @@ void MultiSplitterLayout::ensureEnoughContentsSize(const QWidgetOrQuick *widget,
}
}
void MultiSplitterLayout::ensureAnchorsBounded()
{
// Recursive, goes all the way to right/bottom
m_leftAnchor->ensureBounded();
m_topAnchor->ensureBounded();
}
static Anchor::List removeSmallestPath(QVector<Anchor::List> &paths)
{
// Removes and returns the smallest list
@@ -1576,6 +1583,7 @@ void MultiSplitterLayout::restorePlaceholder(Item *item)
}
item->endBlockPropagateGeo();
ensureAnchorsBounded();
updateAnchorFollowing();
}

View File

@@ -473,6 +473,8 @@ private:
const Item *relativeToItem);
void ensureAnchorsBounded();
void insertAnchor(Anchor *);
void removeAnchor(Anchor *);

View File

@@ -306,6 +306,7 @@ private Q_SLOTS:
void tst_rectForDropMath_data();
void tst_rectForDropMath();
void tst_crash(); // tests some crash I got
void tst_crash2();
void tst_setFloatingWhenWasTabbed();
void tst_setFloatingWhenSideBySide();
void tst_setFloatingAfterDraggedFromTabToSideBySide();
@@ -2492,6 +2493,41 @@ void TestDocks::tst_crash()
}
}
void TestDocks::tst_crash2()
{
EnsureTopLevelsDeleted e;
auto m = new MainWindow("m1");
auto layout = m->multiSplitterLayout();
m->show();
DockWidget::List docks;
for (int i = 0; i < 3; ++i)
docks << new DockWidget(QString::number(i));
QVector<KDDockWidgets::Location> locations = {Location_OnLeft, Location_OnLeft,
Location_OnRight};
QVector<KDDockWidgets::AddingOption> options = { AddingOption_None, AddingOption_None,
AddingOption_StartHidden};
QVector<bool> floatings = {true, false, false};
for (int i = 0; i < 3; ++i) {
m->addDockWidget(docks[i], locations[i], nullptr, options[i]);
layout->checkSanity();
QCOMPARE(layout->m_leftAnchor->cumulativeMinLength(Anchor::Side2), layout->minimumSize().width());
QCOMPARE(layout->m_topAnchor->cumulativeMinLength(Anchor::Side2), layout->minimumSize().height());
docks[i]->setFloating(floatings[i]);
}
qDeleteAll(docks);
qDeleteAll(DockRegistry::self()->frames());
delete m;
}
void TestDocks::tst_setFloatingWhenWasTabbed()
{
// Tests DockWidget::isTabbed() and DockWidget::setFloating(false|true) when tabbed (it should redock)
@@ -3966,6 +4002,7 @@ void TestDocks::tst_addToHiddenMainWindow()
QVERIFY(!m->isVisible());
d1->setFloating(true);
d2->setFloating(false);
delete m;
}