diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-05-22 13:51:28 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2022-05-23 21:12:05 +0200 |
commit | fb56a0f2ce34e95d955095c01ecf2943046be85e (patch) | |
tree | 6a2ad91bee1613164973befbfa833fa3881c6e8a | |
parent | 80996d2e5d6d04b08452cf507f6ced7d8a09068c (diff) |
Don't hide a widget that is swapped into a hidden splitter
When replacing a widget in a hidden splitter, then we only need to keep
the new widget hidden if the previous widget was hidden.
If the new widget is not explicitly hidden, and the splitter is already
visible, then we need to explicitly show the new widget.
Augment test case; the existing test cases already cover swapping out a
collapsed or hidden widget.
Fixes: QTBUG-102134
Pick-to: 6.3 6.2
Change-Id: I9b60711a5c1cab79777ce4183783114a16ac3394
Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
-rw-r--r-- | src/widgets/widgets/qsplitter.cpp | 12 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp | 43 |
2 files changed, 53 insertions, 2 deletions
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index 7dfc2a04fa..a954d6ce66 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -701,6 +701,11 @@ void QSplitterPrivate::setSizes_helper(const QList<int> &sizes, bool clampNegati doResize(); } +/* + Used by various methods inserting a widget to find out if we need to show the widget + explicitly, which we have to if the splitter is already visible, and if the widget hasn't + been explicitly hidden before inserting it. +*/ bool QSplitterPrivate::shouldShowWidget(const QWidget *w) const { Q_Q(const QSplitter); @@ -1144,7 +1149,7 @@ QWidget *QSplitter::replaceWidget(int index, QWidget *widget) QBoolBlocker b(d->blockChildAdd); const QRect geom = current->geometry(); - const bool shouldShow = d->shouldShowWidget(current); + const bool wasHidden = current->isHidden(); s->widget = widget; current->setParent(nullptr); @@ -1154,7 +1159,10 @@ QWidget *QSplitter::replaceWidget(int index, QWidget *widget) // should not change. Only set the geometry on the new widget widget->setGeometry(geom); widget->lower(); - widget->setVisible(shouldShow); + if (wasHidden) + widget->hide(); + else if (d->shouldShowWidget(widget)) + widget->show(); return current; } diff --git a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp index edcfdcfca2..667c6868b7 100644 --- a/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/widgets/widgets/qsplitter/tst_qsplitter.cpp @@ -58,6 +58,8 @@ private slots: void replaceWidget(); void replaceWidgetWithSplitterChild_data(); void replaceWidgetWithSplitterChild(); + void replaceWidgetWhileHidden_data(); + void replaceWidgetWhileHidden(); void handleMinimumWidth(); // task-specific tests below me: @@ -829,6 +831,47 @@ void tst_QSplitter::replaceWidgetWithSplitterChild() } } +void tst_QSplitter::replaceWidgetWhileHidden_data() +{ + QTest::addColumn<bool>("splitterVisible"); + QTest::addColumn<bool>("widgetVisible"); + + QTest::addRow("visibleToVisible") << true << true; + QTest::addRow("hiddenToVisible") << true << false; + QTest::addRow("visibleToHidden") << false << true; + QTest::addRow("hiddenToHidden") << false << false; +} + +void tst_QSplitter::replaceWidgetWhileHidden() +{ + QFETCH(bool, splitterVisible); + QFETCH(bool, widgetVisible); + + MyFriendlySplitter splitter; + + splitter.addWidget(new QLabel("One")); + splitter.addWidget(new QLabel("Two")); + + if (splitterVisible) { + splitter.show(); + QVERIFY(QTest::qWaitForWindowExposed(&splitter)); + } + QWidget *newWidget = new QLabel("Three"); + if (!widgetVisible) + newWidget->hide(); + + const bool wasExplicitHide = !widgetVisible && newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide); + splitter.replaceWidget(1, newWidget); + + QCOMPARE(!widgetVisible && newWidget->testAttribute(Qt::WA_WState_ExplicitShowHide), wasExplicitHide); + + if (!splitterVisible) { + splitter.show(); + QVERIFY(QTest::qWaitForWindowExposed(&splitter)); + } + QCOMPARE(widgetVisible, newWidget->isVisible()); +} + void tst_QSplitter::handleMinimumWidth() { MyFriendlySplitter split; |