QmlDesigner: Prevent deadlock in drag handling in material browser

model->startDrag() starts a new event loop and doesn't exit until the
drag is over, so in the old implementation m_*ToDrag were not
cleared until the drag was complete. However, in some cases it is
possible to receive another move event while drag is still ongoing,
which would then get interpreted as start of another drag as
m_*ToDrag were still valid, causing nested drag event loops, which
caused a deadlock in gui thread.

This issue is prevented by clearing m_*ToDrag before drag starts.

Fixes: QDS-15245
Change-Id: Ib8cd4e5e9f1ab4efcc697e5a6e87d1b2df54ffb7
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Miikka Heikkinen
2025-04-29 12:08:21 +03:00
parent a562958b2b
commit b68ee8a137

View File

@@ -115,20 +115,25 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
QByteArray internalId;
if (isMaterial) {
internalId.setNum(m_materialToDrag.internalId());
qint32 internalIdVal = m_materialToDrag.internalId();
internalId.setNum(internalIdVal);
m_materialToDrag = {};
m_textureToDrag = {};
mimeData->setData(Constants::MIME_TYPE_MATERIAL, internalId);
model->startDrag(std::move(mimeData),
m_previewImageProvider->requestPixmap(
QString::number(m_materialToDrag.internalId()),
QString::number(internalIdVal),
nullptr,
{128, 128}),
this);
} else {
QString sourcePropVal = m_textureToDrag.variantProperty("source").value().toString();
internalId.setNum(m_textureToDrag.internalId());
m_textureToDrag = {};
mimeData->setData(Constants::MIME_TYPE_TEXTURE, internalId);
QString iconPath = QLatin1String("%1/%2")
.arg(DocumentManager::currentResourcePath().path(),
m_textureToDrag.variantProperty("source").value().toString());
sourcePropVal);
QPixmap pixmap;
const QString suffix = iconPath.split('.').last().toLower();
@@ -144,8 +149,6 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event)
":/propertyeditor/images/texture_default.png");
model->startDrag(std::move(mimeData), pixmap.scaled({128, 128}), this);
}
m_materialToDrag = {};
m_textureToDrag = {};
}
}
} else if (event->type() == QMouseEvent::MouseButtonRelease) {