From 7d3ba0587f76c6905e1f2ee00ae54d4211af523c Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 22 Feb 2021 18:36:21 +0200 Subject: [PATCH] QmlDesigner: Fix item library expand issue If a click happens on an item library item, mouse interaction (expanding, collapsing sections, and showing context menu) is blocked until some action happens (right-click for example). This is due to a bug in QDrag. With this commit it is very hard to reproduce the issue unless one's deliberately insisting to reproduce it. Fixes: QDS-3792 Fixes: QDS-1652 Change-Id: I201b07aabf144adbb4d51e32c1fcc4990f89f5f9 Reviewed-by: Miikka Heikkinen --- .../itemLibraryQmlSources/ItemDelegate.qml | 2 +- .../itemlibrary/itemlibrarywidget.cpp | 34 +++++++++---------- .../itemlibrary/itemlibrarywidget.h | 4 +-- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml index b7bc9b0b58c..f7cf00d92c3 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml @@ -75,7 +75,7 @@ Item { anchors.fill: parent onPressed: { - rootView.startDragAndDrop(mouseRegion, itemLibraryEntry) + rootView.startDragAndDrop(itemLibraryEntry) } } } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index dc31d169459..68226022865 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -84,6 +84,17 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) if (event->type() == QEvent::FocusOut) { if (obj == m_itemViewQuickWidget.data()) QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu"); + } else if (event->type() == QMouseEvent::MouseMove) { + if (m_itemToDrag.isValid()) { + ItemLibraryEntry entry = m_itemToDrag.value(); + auto drag = new QDrag(this); + drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile(entry.libraryEntryIconPath())); + drag->setMimeData(m_itemLibraryModel->getMimeData(entry)); + drag->exec(); + drag->deleteLater(); + + m_itemToDrag = {}; + } } return QObject::eventFilter(obj, event); @@ -366,25 +377,12 @@ void ItemLibraryWidget::setResourcePath(const QString &resourcePath) updateSearch(); } -void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibraryId) +void ItemLibraryWidget::startDragAndDrop(const QVariant &itemLibEntry) { - m_currentitemLibraryEntry = itemLibraryId.value(); - - QMimeData *mimeData = m_itemLibraryModel->getMimeData(m_currentitemLibraryEntry); - auto drag = new QDrag(this); - - drag->setPixmap(Utils::StyleHelper::dpiSpecificImageFile( - m_currentitemLibraryEntry.libraryEntryIconPath())); - drag->setMimeData(mimeData); - - /* Workaround for bug in Qt. The release event is not delivered for Qt < 5.9 if a drag is started */ - QMouseEvent event (QEvent::MouseButtonRelease, QPoint(-1, -1), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); - QApplication::sendEvent(mouseArea, &event); - - QTimer::singleShot(0, [drag]() { - drag->exec(); - drag->deleteLater(); - }); + // Actual drag is created after mouse has moved to avoid a QDrag bug that causes drag to stay + // active (and blocks mouse release) if mouse is released at the same spot of the drag start. + // This doesn't completely eliminate the bug but makes it significantly harder to produce. + m_itemToDrag = itemLibEntry; } void ItemLibraryWidget::setFlowMode(bool b) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 3a274069fa2..5bde054fc9b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -87,7 +87,7 @@ public: void setModel(Model *model); void setFlowMode(bool b); - Q_INVOKABLE void startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibId); + Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry); Q_INVOKABLE void removeImport(const QString &importUrl); signals: @@ -123,7 +123,7 @@ private: QShortcut *m_qmlSourceUpdateShortcut; AsynchronousImageCache &m_imageCache; QPointer m_model; - ItemLibraryEntry m_currentitemLibraryEntry; + QVariant m_itemToDrag; bool m_updateRetry = false; QString m_filterText;