From b68ee8a13710894a06f73ec64b638aec80835aab Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 29 Apr 2025 12:08:21 +0300 Subject: [PATCH] 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 --- .../materialbrowser/materialbrowserwidget.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index e8f297b4e99..6097812e2b8 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -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) {