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:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -473,6 +473,8 @@ private:
|
||||
const Item *relativeToItem);
|
||||
|
||||
|
||||
void ensureAnchorsBounded();
|
||||
|
||||
void insertAnchor(Anchor *);
|
||||
void removeAnchor(Anchor *);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user