QDockAreaLayoutInfo::takeAt(): don't greate gap for demoted QDockWidget

In the current implementation, when a dock widget is deleted, the
QWidget destructor triggers a ChildRemoved event to inform the layout
of the widget's removal. During this process,
QDockAreaLayoutInfo::takeAt() is invoked to remove the dock widget from
the item list in its QDockAreaLayoutInfo.

However, the existing logic in takeAt() incorrectly assumes that the
dock widget is either being moved or closed, failing to account for its
destruction. This leads to the construction of a QPlaceholderItem with
a QWidget pointer, despite the widget already having been demoted to a
QObject.

Check QObject::isWidgetType() before creating a QPlaceholderItem,
ensuring that placeholders are only created for active QDockWidgets.

Task-number: QTBUG-135442
Pick-to: 6.9 6.8 6.5
Change-Id: Ie583cff260b62dd07acd473364003a2f04a18f8c
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Axel Spoerl 2025-04-07 07:40:16 +02:00
parent b8ff842ace
commit b7446b1f5b

View File

@ -1777,7 +1777,11 @@ QLayoutItem *QDockAreaLayoutInfo::takeAt(int *x, int index)
}
} else if (item.widgetItem) {
if ((*x)++ == index) {
item.placeHolderItem = new QPlaceHolderItem(item.widgetItem->widget());
QWidget *widget = item.widgetItem->widget();
if (widget->isWidgetType())
item.placeHolderItem = new QPlaceHolderItem(widget);
else
qCDebug(lcQpaDockWidgets) << widget << "is in destruction. No gap created.";
QLayoutItem *ret = item.widgetItem;
item.widgetItem = nullptr;
if (item.size != -1)