QDockAreaLayout/QPlaceHolderItem: Store geometry excluding frame.

Previously, the geometry stored for floating dock widgets
in QPlaceHolderItem::topLevelRect and QDockAreaLayoutInfo::saveState()
included the window frame (frame position/content area size).
This does not work in the case where a floating dock widget is deleted
since the geometry is determined after reparenting the widget when the
frame geometry is no longer available. Change the behavior to store
the geometry excluding frame to avoid such problems and adapt
QDockWidgetPrivate::setWindowState() accordingly.

Task-number: QTBUG-49832
Task-number: QTBUG-45780
Change-Id: I84b5c80df6e1c9e738bbb1407b9047cc84719ce0
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
Friedemann Kleint 2015-12-15 10:49:47 +01:00
parent 482165057d
commit bece6fa0b9
3 changed files with 18 additions and 9 deletions

View File

@ -1816,7 +1816,8 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const
stream << flags;
if (w->isWindow()) {
stream << w->x() << w->y() << w->width() << w->height();
const QRect geometry = w->geometry();
stream << geometry.x() << geometry.y() << geometry.width() << geometry.height();
} else {
stream << item.pos << item.size << pick(o, item.minimumSize())
<< pick(o, item.maximumSize());

View File

@ -1093,14 +1093,8 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
q->setWindowFlags(flags);
if (!rect.isNull()) {
if (floating) {
q->resize(rect.size());
q->move(rect.topLeft());
} else {
if (!rect.isNull())
q->setGeometry(rect);
}
}
updateButtons();

View File

@ -761,6 +761,9 @@ void tst_QDockWidget::restoreDockWidget()
{
QByteArray geometry;
QByteArray state;
const bool isXcb = !QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive);
const QString name = QStringLiteral("main");
const QRect availableGeometry = QApplication::desktop()->availableGeometry();
const QSize size = availableGeometry.size() / 5;
@ -785,11 +788,22 @@ void tst_QDockWidget::restoreDockWidget()
QVERIFY(dock->isFloating());
state = saveWindow.saveState();
geometry = saveWindow.saveGeometry();
// QTBUG-49832: Delete and recreate the dock; it should be restored to the same position.
delete dock;
dock = createTestDock(saveWindow);
QVERIFY(saveWindow.restoreDockWidget(dock));
dock->show();
QVERIFY(QTest::qWaitForWindowExposed(dock));
QTRY_VERIFY(dock->isFloating());
if (!isXcb) // Avoid Window manager positioning issues
QTRY_COMPARE(dock->pos(), dockPos);
}
QVERIFY(!geometry.isEmpty());
QVERIFY(!state.isEmpty());
// QTBUG-45780: Completely recreate the dock widget from the saved state.
{
QMainWindow restoreWindow;
restoreWindow.setObjectName(name);
@ -804,7 +818,7 @@ void tst_QDockWidget::restoreDockWidget()
restoreWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&restoreWindow));
QTRY_VERIFY(dock->isFloating());
if (!QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive))
if (isXcb)
QSKIP("Skip due to Window manager positioning issues", Abort);
QTRY_COMPARE(dock->pos(), dockPos);
}