Fix crash when using MainWindow::layoutEqually()
When distributing space we should honour the other widgets min-size too, and not give too much Since the layouting code is complex, this won't be backported to 1.3
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
as TitleBarWidget already reimplements sizeHint. If you're inheriting directly from TitleBar then make
|
||||
sure to provide a sizeHint.
|
||||
- Added MainWindow::closeDockWidgets()
|
||||
- Fixed crash in MainWindow::layoutEqually()
|
||||
|
||||
* v1.3.1 (unreleased)
|
||||
- Improve restoring layout when RestoreOption_RelativeToMainWindow is used (#171)
|
||||
|
||||
@@ -2384,8 +2384,9 @@ void ItemBoxContainer::layoutEqually(SizingInfo::List &sizes)
|
||||
auto lengthToGive = length() - (d->m_separators.size() * Item::separatorThickness);
|
||||
|
||||
// clear the sizes before we start distributing
|
||||
for (SizingInfo &size : sizes)
|
||||
size.setLength(0, d->m_orientation);
|
||||
for (SizingInfo &size : sizes) {
|
||||
size.setLength(0, d->m_orientation);
|
||||
}
|
||||
|
||||
while (satisfiedIndexes.count() < sizes.count()) {
|
||||
const auto remainingItems = sizes.count() - satisfiedIndexes.count();
|
||||
@@ -2403,9 +2404,25 @@ void ItemBoxContainer::layoutEqually(SizingInfo::List &sizes)
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto newItemLenght = qBound(size.minLength(d->m_orientation),
|
||||
size.length(d->m_orientation) + suggestedToGive,
|
||||
size.maxLengthHint(d->m_orientation));
|
||||
// Bound the max length. Our max can't be bigger than the remaining space.
|
||||
// The layout's min length minus our own min length is the amount of space that we
|
||||
// need to guarantee. We can't go larger and overwrite that
|
||||
|
||||
const auto othersMissing = // The size that the others are missing to satisfy their
|
||||
// minimum length
|
||||
std::accumulate(sizes.constBegin(), sizes.constEnd(), 0,
|
||||
[this](size_t sum, const SizingInfo &sz) {
|
||||
return sum + sz.missingLength(d->m_orientation);
|
||||
})
|
||||
- size.missingLength(d->m_orientation);
|
||||
|
||||
const auto maxLength =
|
||||
qMin(size.length(d->m_orientation) + lengthToGive - othersMissing,
|
||||
size.maxLengthHint(d->m_orientation));
|
||||
|
||||
const auto newItemLenght =
|
||||
qBound(size.minLength(d->m_orientation),
|
||||
size.length(d->m_orientation) + suggestedToGive, maxLength);
|
||||
const auto toGive = newItemLenght - size.length(d->m_orientation);
|
||||
|
||||
if (toGive == 0) {
|
||||
|
||||
279
tests/layouts/layoutEquallyCrash.json
Normal file
279
tests/layouts/layoutEquallyCrash.json
Normal file
@@ -0,0 +1,279 @@
|
||||
{
|
||||
"allDockWidgets": [
|
||||
{
|
||||
"affinities": [
|
||||
"{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
],
|
||||
"lastPosition": {
|
||||
"lastFloatingGeometry": {
|
||||
"height": 0,
|
||||
"width": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"placeholders": [
|
||||
{
|
||||
"isFloatingWindow": false,
|
||||
"itemIndex": 2,
|
||||
"mainWindowUniqueName": "{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
}
|
||||
],
|
||||
"tabIndex": 0,
|
||||
"wasFloating": false
|
||||
},
|
||||
"uniqueName": "Favorite-481"
|
||||
},
|
||||
{
|
||||
"affinities": [
|
||||
"{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
],
|
||||
"lastPosition": {
|
||||
"lastFloatingGeometry": {
|
||||
"height": 0,
|
||||
"width": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"placeholders": [
|
||||
{
|
||||
"isFloatingWindow": false,
|
||||
"itemIndex": 0,
|
||||
"mainWindowUniqueName": "{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
}
|
||||
],
|
||||
"tabIndex": 0,
|
||||
"wasFloating": false
|
||||
},
|
||||
"uniqueName": "Favorite-482"
|
||||
},
|
||||
{
|
||||
"affinities": [
|
||||
"{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
],
|
||||
"lastPosition": {
|
||||
"lastFloatingGeometry": {
|
||||
"height": 0,
|
||||
"width": 0,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"placeholders": [
|
||||
{
|
||||
"isFloatingWindow": false,
|
||||
"itemIndex": 1,
|
||||
"mainWindowUniqueName": "{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
}
|
||||
],
|
||||
"tabIndex": 0,
|
||||
"wasFloating": false
|
||||
},
|
||||
"uniqueName": "Favorite-483"
|
||||
}
|
||||
],
|
||||
"closedDockWidgets": [
|
||||
],
|
||||
"floatingWindows": [
|
||||
],
|
||||
"mainWindows": [
|
||||
{
|
||||
"affinities": [
|
||||
"{7829427d-88e3-402e-9120-50c628dfd0bc}"
|
||||
],
|
||||
"geometry": {
|
||||
"height": 1228,
|
||||
"width": 1644,
|
||||
"x": 501,
|
||||
"y": 110
|
||||
},
|
||||
"isVisible": true,
|
||||
"multiSplitterLayout": {
|
||||
"frames": {
|
||||
"10": {
|
||||
"currentTabIndex": 0,
|
||||
"dockWidgets": [
|
||||
"Favorite-483"
|
||||
],
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 536,
|
||||
"x": 541,
|
||||
"y": 0
|
||||
},
|
||||
"id": "10",
|
||||
"isNull": false,
|
||||
"objectName": "Favorite-483",
|
||||
"options": 0
|
||||
},
|
||||
"12": {
|
||||
"currentTabIndex": 0,
|
||||
"dockWidgets": [
|
||||
"Favorite-481"
|
||||
],
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 540,
|
||||
"x": 1082,
|
||||
"y": 0
|
||||
},
|
||||
"id": "12",
|
||||
"isNull": false,
|
||||
"objectName": "Favorite-481",
|
||||
"options": 0
|
||||
},
|
||||
"9": {
|
||||
"currentTabIndex": 0,
|
||||
"dockWidgets": [
|
||||
"Favorite-482"
|
||||
],
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 536,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": "9",
|
||||
"isNull": false,
|
||||
"objectName": "Favorite-482",
|
||||
"options": 0
|
||||
}
|
||||
},
|
||||
"layout": {
|
||||
"children": [
|
||||
{
|
||||
"children": [
|
||||
{
|
||||
"guestId": "9",
|
||||
"isContainer": false,
|
||||
"isVisible": true,
|
||||
"objectName": "Favorite-482",
|
||||
"sizingInfo": {
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 536,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"maxSize": {
|
||||
"height": 524315,
|
||||
"width": 524432
|
||||
},
|
||||
"minSize": {
|
||||
"height": 118,
|
||||
"width": 233
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"guestId": "10",
|
||||
"isContainer": false,
|
||||
"isVisible": true,
|
||||
"objectName": "Favorite-483",
|
||||
"sizingInfo": {
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 536,
|
||||
"x": 541,
|
||||
"y": 0
|
||||
},
|
||||
"maxSize": {
|
||||
"height": 524287,
|
||||
"width": 524291
|
||||
},
|
||||
"minSize": {
|
||||
"height": 90,
|
||||
"width": 360
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"guestId": "12",
|
||||
"isContainer": false,
|
||||
"isVisible": true,
|
||||
"objectName": "Favorite-481",
|
||||
"sizingInfo": {
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 540,
|
||||
"x": 1082,
|
||||
"y": 0
|
||||
},
|
||||
"maxSize": {
|
||||
"height": 524317,
|
||||
"width": 524291
|
||||
},
|
||||
"minSize": {
|
||||
"height": 438,
|
||||
"width": 540
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"isContainer": true,
|
||||
"isVisible": false,
|
||||
"objectName": "",
|
||||
"orientation": 1,
|
||||
"sizingInfo": {
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 1622,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"maxSize": {
|
||||
"height": 524287,
|
||||
"width": 1048728
|
||||
},
|
||||
"minSize": {
|
||||
"height": 118,
|
||||
"width": 598
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"isContainer": true,
|
||||
"isVisible": false,
|
||||
"objectName": "",
|
||||
"orientation": 2,
|
||||
"sizingInfo": {
|
||||
"geometry": {
|
||||
"height": 1206,
|
||||
"width": 1622,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"maxSize": {
|
||||
"height": 16777215,
|
||||
"width": 16777215
|
||||
},
|
||||
"minSize": {
|
||||
"height": 90,
|
||||
"width": 80
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": 0,
|
||||
"screenIndex": 0,
|
||||
"screenSize": {
|
||||
"height": 1440,
|
||||
"width": 2560
|
||||
},
|
||||
"uniqueName": "{7829427d-88e3-402e-9120-50c628dfd0bc}",
|
||||
"windowState": 0
|
||||
}
|
||||
],
|
||||
"screenInfo": [
|
||||
{
|
||||
"devicePixelRatio": 1.5,
|
||||
"geometry": {
|
||||
"height": 1440,
|
||||
"width": 2560,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"index": 0,
|
||||
"name": "DP-2"
|
||||
}
|
||||
],
|
||||
"serializationVersion": 3
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
<file>layouts/overlapping-item.json</file>
|
||||
<file>layouts/unsupported-serialization-version.json</file>
|
||||
<file>layouts/stuck-separator.json</file>
|
||||
<file>layouts/layoutEquallyCrash.json</file>
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -118,6 +118,7 @@ private Q_SLOTS:
|
||||
void tst_restoreMaximizedState();
|
||||
void tst_shutdown();
|
||||
void tst_closeDockWidgets();
|
||||
void tst_layoutEqually();
|
||||
void tst_doubleClose();
|
||||
void tst_dockInternal();
|
||||
void tst_maximizeAndRestore();
|
||||
@@ -936,6 +937,30 @@ void TestDocks::tst_closeDockWidgets()
|
||||
QCOMPARE(m->layoutWidget()->visibleCount(), 0);
|
||||
}
|
||||
|
||||
void TestDocks::tst_layoutEqually()
|
||||
{
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
const QString mainWindowId = "{7829427d-88e3-402e-9120-50c628dfd0bc}";
|
||||
auto m = createMainWindow(QSize(800, 500), MainWindowOption_None, mainWindowId);
|
||||
m->setAffinities({ mainWindowId });
|
||||
|
||||
auto dock1 = createDockWidget("Favorite-481", new MyWidget2(QSize(536, 438)));
|
||||
auto dock2 = createDockWidget("Favorite-482", new MyWidget2(QSize(229, 118)));
|
||||
auto dock3 = createDockWidget("Favorite-483", new MyWidget2(QSize(356, 90)));
|
||||
|
||||
m->setContentsMargins(10, 0, 10, 0);
|
||||
|
||||
dock1->setAffinities({ mainWindowId });
|
||||
dock2->setAffinities({ mainWindowId });
|
||||
dock3->setAffinities({ mainWindowId });
|
||||
|
||||
LayoutSaver restorer;
|
||||
restorer.restoreFromFile(":/layouts/layoutEquallyCrash.json");
|
||||
|
||||
m->layoutEqually();
|
||||
}
|
||||
|
||||
void TestDocks::tst_doubleClose()
|
||||
{
|
||||
EnsureTopLevelsDeleted e;
|
||||
|
||||
Reference in New Issue
Block a user