QMdiSubwindow: respect minimum size of subwidgets when shown maximized

Size a QMdiSubWindow is no real toplevel widget, QLayout::activate() did
not properly set the minimum size based on it's children. Fix this by
treating a QMdiSubWindow as a toplevel widget during the calculation.

Fixes: QTBUG-100494
Change-Id: Ia2e6c519c7214c36383facd244711bd932231d40
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Christian Ehrlicher 2022-02-04 23:05:20 +01:00
parent d54bb53247
commit 15f7ef26b8
2 changed files with 40 additions and 1 deletions

View File

@ -2318,7 +2318,14 @@ void QMdiArea::resizeEvent(QResizeEvent *resizeEvent)
foreach (QMdiSubWindow *child, d->childWindows) { foreach (QMdiSubWindow *child, d->childWindows) {
if (sanityCheck(child, "QMdiArea::resizeEvent") && child->isMaximized() if (sanityCheck(child, "QMdiArea::resizeEvent") && child->isMaximized()
&& child->size() != resizeEvent->size()) { && child->size() != resizeEvent->size()) {
child->resize(resizeEvent->size()); auto realSize = resizeEvent->size();
const auto minSizeHint = child->minimumSizeHint();
// QMdiSubWindow is no tlw so minimumSize() is not set by the layout manager
// and therefore we have to take care by ourself that we're not getting smaller
// than allowed
if (minSizeHint.isValid())
realSize = realSize.expandedTo(minSizeHint);
child->resize(realSize);
if (!hasMaximizedSubWindow) if (!hasMaximizedSubWindow)
hasMaximizedSubWindow = true; hasMaximizedSubWindow = true;
} }

View File

@ -45,6 +45,7 @@
#include <QStyleOptionTitleBar> #include <QStyleOptionTitleBar>
#include <QPushButton> #include <QPushButton>
#include <QScreen> #include <QScreen>
#include <QScrollBar>
#include <QSizeGrip> #include <QSizeGrip>
#include <QSignalSpy> #include <QSignalSpy>
#include <QList> #include <QList>
@ -221,6 +222,7 @@ private slots:
void styleChange(); void styleChange();
void testFullScreenState(); void testFullScreenState();
void testRemoveBaseWidget(); void testRemoveBaseWidget();
void testRespectMinimumSize();
}; };
void tst_QMdiSubWindow::initTestCase() void tst_QMdiSubWindow::initTestCase()
@ -2163,6 +2165,36 @@ void tst_QMdiSubWindow::testRemoveBaseWidget()
delete widget1; delete widget1;
} }
void tst_QMdiSubWindow::testRespectMinimumSize() // QTBUG-100494
{
QMdiArea mdiArea;
mdiArea.resize(400, 400);
mdiArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
mdiArea.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
auto vlay = new QVBoxLayout;
vlay->addWidget(new QPushButton(QLatin1String("btn1-1")));
vlay->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
vlay->addWidget(new QPushButton(QLatin1String("btn1-2")));
auto w1 = new QWidget;
w1->setLayout(vlay);
w1->resize(300, 200);
w1->setMinimumSize(200, 150);
auto sw = new QMdiSubWindow;
sw->setWidget(w1);
sw->resize(w1->size());
mdiArea.addSubWindow(sw);
sw->showMaximized();
mdiArea.show();
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
QVERIFY(!mdiArea.horizontalScrollBar()->isVisible());
QVERIFY(!mdiArea.verticalScrollBar()->isVisible());
mdiArea.resize(150, 100);
QTRY_VERIFY(mdiArea.horizontalScrollBar()->isVisible());
QTRY_VERIFY(mdiArea.verticalScrollBar()->isVisible());
}
QTEST_MAIN(tst_QMdiSubWindow) QTEST_MAIN(tst_QMdiSubWindow)
#include "tst_qmdisubwindow.moc" #include "tst_qmdisubwindow.moc"