Prevent dock widget from resizing upon unplugging from main window

QDockWidgetLayoutState::itemRect() has been used to calculate a dock
widget's size when unplugging from the main window. This method is meant
to calculate the size of the rubber band, showing the dock widget's
dock area.

The rubber band is by QDockAreaLayout::sep wider (top or bottom dock)
or higher (left or right dock) than the respective dock widget. This is
to make sure the rubber band is never fully covered by the dock widget.

By wrongly using itemRect() also for the dock widget's size after
unplugging, the dock widget grows in size each time it is unplugged.

This patch passes an invalid QRect to QDockWidgetPrivate::unplug(), in
order to prevent resizing.

tst_QDockWidget::unplugAndResize() is extended to check size
consistency after unplugging (corrected for frame margins).

Fixes: QTBUG-106531
Pick-to: 6.4 6.2
Change-Id: I1cf9f695691b0e165a5cb2881781602426e5d587
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Axel Spoerl 2022-09-19 16:50:37 +02:00 committed by Shawn Rutledge
parent a8ccd9cd84
commit 10a143ccd7
2 changed files with 17 additions and 3 deletions

View File

@ -2654,7 +2654,9 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group)
} else
#endif // QT_CONFIG(tabwidget)
{
dw->d_func()->unplug(r);
// Dock widget is unplugged from the main window
// => geometry is not supposed to change
dw->d_func()->unplug(QRect());
}
}
#endif // QT_CONFIG(dockwidget)

View File

@ -1230,21 +1230,33 @@ void tst_QDockWidget::unplugAndResize(QMainWindow* mainWindow, QDockWidget* dw,
return;
}
// Remember size for comparison with unplugged object
#ifdef Q_OS_LINUX
const int pluggedWidth = dw->width();
const int pluggedHeight = dw->height();
#endif
// unplug and resize a dock Widget
qCDebug(lcTestDockWidget) << "*** unplug and resize" << dw->objectName();
QPoint pos1 = dw->mapToGlobal(dw->rect().center());
pos1.rx() += mx;
pos1.ry() += my;
moveDockWidget(dw, pos1, dw->mapToGlobal(dw->rect().center()));
//QTest::mousePress(dw, Qt::LeftButton, Qt::KeyboardModifiers(), dw->mapFromGlobal(pos1));
QTRY_VERIFY(dw->isFloating());
// Unplugged object's size may differ max. by 2x frame size
#ifdef Q_OS_LINUX
const int xMargin = 2 * dw->frameSize().width();
const int yMargin = 2 * dw->frameSize().height();
QVERIFY(dw->height() - pluggedHeight <= xMargin);
QVERIFY(dw->width() - pluggedWidth <= yMargin);
#endif
qCDebug(lcTestDockWidget) << "Resizing" << dw->objectName() << "to" << size;
dw->setFixedSize(size);
QTest::qWait(waitingTime);
qCDebug(lcTestDockWidget) << "Move" << dw->objectName() << "to its home" << dw->mapFromGlobal(home);
dw->move(home);
//moveDockWidget(dw, home);
}
bool tst_QDockWidget::checkFloatingTabs(QMainWindow* mainWindow, QPointer<QDockWidgetGroupWindow> &ftabs, const QList<QDockWidget*> &dwList) const