QDockWidget: Do not propagate title from a closed dock widget

When a dock widget is closed while floating, it still reports being
floating even though the QWidget::windowHandle()->isVisible() returns
false. This is documented behavior and will not be changed.

c153066baaa88718ed45b68230d81285eb436d3d relied on the isFloating() to
return false, if the dock widget is closed. When the window title was
changed by setWindowTitle(), the change was overridden by reading the
old value from the window handle.

=> Amend the patch and add a windowHandle()->isVisible() as a condition.

In c153066baaa88718ed45b68230d81285eb436d3d, an autotest for the title
propagation (QTBUG-113591) was added to floatingTabs().

=> Harden the setWindowTitle() test function. Move the tests related to
QTBUG-113591 and QTBUG-117764 to this function.

Fixes: QTBUG-117764
Pick-to: 6.5
Change-Id: Id37a9a22d4d13abad4ea55c74ea4e834bdb2bfab
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Christian Ehrlicher <ch.ehrlicher@gmx.de>
(cherry picked from commit 92d837e684e3ab619d28ad84d2ab3a1b82335173)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Axel Spoerl 2023-10-05 15:13:14 +02:00 committed by Qt Cherry-pick Bot
parent 47c2aad025
commit 72e9795d41
2 changed files with 16 additions and 14 deletions

View File

@ -1502,7 +1502,7 @@ void QDockWidget::changeEvent(QEvent *event)
switch (event->type()) { switch (event->type()) {
case QEvent::WindowTitleChange: case QEvent::WindowTitleChange:
if (isFloating() && windowHandle() && d->topData()) { if (isFloating() && windowHandle() && d->topData() && windowHandle()->isVisible()) {
// From QWidget::setWindowTitle(): Propagate window title without signal emission // From QWidget::setWindowTitle(): Propagate window title without signal emission
d->topData()->caption = windowHandle()->title(); d->topData()->caption = windowHandle()->title();
d->setWindowTitle_helper(windowHandle()->title()); d->setWindowTitle_helper(windowHandle()->title());

View File

@ -1072,9 +1072,10 @@ void tst_QDockWidget::setWindowTitle()
QMainWindow window; QMainWindow window;
QDockWidget dock1(&window); QDockWidget dock1(&window);
QDockWidget dock2(&window); QDockWidget dock2(&window);
const QString dock1Title = QStringLiteral("&Window"); constexpr QLatin1StringView dock1Title("&Window");
const QString dock2Title = QStringLiteral("&Modifiable Window [*]"); constexpr QLatin1StringView dock2Title("&Modifiable Window [*]");
// Set title on docked dock widgets, before main window is shown
dock1.setWindowTitle(dock1Title); dock1.setWindowTitle(dock1Title);
dock2.setWindowTitle(dock2Title); dock2.setWindowTitle(dock2Title);
window.addDockWidget(Qt::RightDockWidgetArea, &dock1); window.addDockWidget(Qt::RightDockWidgetArea, &dock1);
@ -1085,6 +1086,7 @@ void tst_QDockWidget::setWindowTitle()
QCOMPARE(dock1.windowTitle(), dock1Title); QCOMPARE(dock1.windowTitle(), dock1Title);
QCOMPARE(dock2.windowTitle(), dock2Title); QCOMPARE(dock2.windowTitle(), dock2Title);
// Check if title remains unchanged when docking / undocking
dock1.setFloating(true); dock1.setFloating(true);
dock1.show(); dock1.show();
QVERIFY(QTest::qWaitForWindowExposed(&dock1)); QVERIFY(QTest::qWaitForWindowExposed(&dock1));
@ -1094,12 +1096,16 @@ void tst_QDockWidget::setWindowTitle()
dock1.setFloating(true); dock1.setFloating(true);
dock1.show(); dock1.show();
QVERIFY(QTest::qWaitForWindowExposed(&dock1)); QVERIFY(QTest::qWaitForWindowExposed(&dock1));
const QString changed = QStringLiteral("Changed ");
// Change a floating dock widget's title and check remains unchanged when docking
constexpr QLatin1StringView changed("Changed ");
dock1.setWindowTitle(QString(changed + dock1Title)); dock1.setWindowTitle(QString(changed + dock1Title));
QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title)); QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title));
dock1.setFloating(false); dock1.setFloating(false);
QVERIFY(QTest::qWaitFor([&dock1](){ return !dock1.windowHandle(); }));
QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title)); QCOMPARE(dock1.windowTitle(), QString(changed + dock1Title));
// Test consistency after toggling modified and floating
dock2.setWindowModified(true); dock2.setWindowModified(true);
QCOMPARE(dock2.windowTitle(), dock2Title); QCOMPARE(dock2.windowTitle(), dock2Title);
dock2.setFloating(true); dock2.setFloating(true);
@ -1114,6 +1120,12 @@ void tst_QDockWidget::setWindowTitle()
dock2.show(); dock2.show();
QVERIFY(QTest::qWaitForWindowExposed(&dock2)); QVERIFY(QTest::qWaitForWindowExposed(&dock2));
QCOMPARE(dock2.windowTitle(), dock2Title); QCOMPARE(dock2.windowTitle(), dock2Title);
// Test title change of a closed dock widget
static constexpr QLatin1StringView closedDock2("Closed D2");
dock2.close();
dock2.setWindowTitle(closedDock2);
QCOMPARE(dock2.windowTitle(), closedDock2);
} }
// helpers for dockPermissions, hideAndShow, closeAndDelete // helpers for dockPermissions, hideAndShow, closeAndDelete
@ -1392,12 +1404,6 @@ void tst_QDockWidget::floatingTabs()
QTRY_VERIFY(d1->isFloating()); QTRY_VERIFY(d1->isFloating());
QTRY_VERIFY(!d2->isFloating()); QTRY_VERIFY(!d2->isFloating());
// Change titles
static constexpr QLatin1StringView newD1("New D1");
static constexpr QLatin1StringView newD2("New D2");
d1->setWindowTitle(newD1);
d2->setWindowTitle(newD2);
// Plug back into dock areas // Plug back into dock areas
qCDebug(lcTestDockWidget) << "*** test plugging back to dock areas ***"; qCDebug(lcTestDockWidget) << "*** test plugging back to dock areas ***";
qCDebug(lcTestDockWidget) << "Move d1 to left dock"; qCDebug(lcTestDockWidget) << "Move d1 to left dock";
@ -1417,10 +1423,6 @@ void tst_QDockWidget::floatingTabs()
QTRY_VERIFY(!mainWindow->findChild<QDockWidgetGroupWindow*>()); QTRY_VERIFY(!mainWindow->findChild<QDockWidgetGroupWindow*>());
QTRY_VERIFY(ftabs.isNull()); QTRY_VERIFY(ftabs.isNull());
// check window titles
QCOMPARE(d1->windowTitle(), newD1);
QCOMPARE(d2->windowTitle(), newD2);
// Check if paths are consistent // Check if paths are consistent
qCDebug(lcTestDockWidget) << "Checking path consistency" << layout->layoutState.indexOf(d1) << layout->layoutState.indexOf(d2); qCDebug(lcTestDockWidget) << "Checking path consistency" << layout->layoutState.indexOf(d1) << layout->layoutState.indexOf(d2);