Fix assert when resizing text table with percentage widths

Since Qt 6.3.x, qBound() has started asserting that max > min.
This caused a crash in the QTextDocumentLayout code for assigning
widths to table columns that were sized using percentages, which
depended on previous qBound() behavior of just snapping to the
minimum size if max < min.

There are some specific conditions for this to happen: First
of all, the available width in the table must be too small to
fit all minimum widths (which is calculated based on content).
In addition, the requested widths have to be given as
percentages of the table width, and these have to add to
something lower than 100%. With these conditions, you may get
a case where the calculated percentage width of a column is
larger than the minimum width, but lower than the remaining
width in the table, causing the assert in qBound().

We simply accept the minimum width as the rule in these cases,
which matches behavior without the assert and which looks
correct when resizing the window to be smaller than the table.

Fixes: QTBUG-108183
Change-Id: I16d18dd9b2e7a77fe86d1a353b426075b5050b8e
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit 84a68ef75ce8a8e5b90d799c90905cc998c7c2f6)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2022-12-22 11:36:49 +01:00 committed by Qt Cherry-pick Bot
parent 43500a1e66
commit f6e3ea4f73

View File

@ -2553,8 +2553,9 @@ recalc_minmax_widths:
const QFixed allottedPercentage = QFixed::fromReal(columnWidthConstraints.at(i).rawValue());
const QFixed percentWidth = totalPercentagedWidth * allottedPercentage / totalPercentage;
if (percentWidth >= td->minWidths.at(i)) {
td->widths[i] = qBound(td->minWidths.at(i), percentWidth, remainingWidth - remainingMinWidths);
QFixed maxWidth = remainingWidth - remainingMinWidths;
if (percentWidth >= td->minWidths.at(i) && maxWidth > td->minWidths.at(i)) {
td->widths[i] = qBound(td->minWidths.at(i), percentWidth, maxWidth);
} else {
td->widths[i] = td->minWidths.at(i);
}