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 <miikka.heikkinen@qt.io>
This commit is contained in:
Mahmoud Badri
2021-02-22 18:36:21 +02:00
parent 3dfb866bab
commit 7d3ba0587f
3 changed files with 19 additions and 21 deletions

View File

@@ -75,7 +75,7 @@ Item {
anchors.fill: parent anchors.fill: parent
onPressed: { onPressed: {
rootView.startDragAndDrop(mouseRegion, itemLibraryEntry) rootView.startDragAndDrop(itemLibraryEntry)
} }
} }
} }

View File

@@ -84,6 +84,17 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::FocusOut) { if (event->type() == QEvent::FocusOut) {
if (obj == m_itemViewQuickWidget.data()) if (obj == m_itemViewQuickWidget.data())
QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu"); QMetaObject::invokeMethod(m_itemViewQuickWidget->rootObject(), "closeContextMenu");
} else if (event->type() == QMouseEvent::MouseMove) {
if (m_itemToDrag.isValid()) {
ItemLibraryEntry entry = m_itemToDrag.value<ItemLibraryEntry>();
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); return QObject::eventFilter(obj, event);
@@ -366,25 +377,12 @@ void ItemLibraryWidget::setResourcePath(const QString &resourcePath)
updateSearch(); updateSearch();
} }
void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibraryId) void ItemLibraryWidget::startDragAndDrop(const QVariant &itemLibEntry)
{ {
m_currentitemLibraryEntry = itemLibraryId.value<ItemLibraryEntry>(); // 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.
QMimeData *mimeData = m_itemLibraryModel->getMimeData(m_currentitemLibraryEntry); // This doesn't completely eliminate the bug but makes it significantly harder to produce.
auto drag = new QDrag(this); m_itemToDrag = itemLibEntry;
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();
});
} }
void ItemLibraryWidget::setFlowMode(bool b) void ItemLibraryWidget::setFlowMode(bool b)

View File

@@ -87,7 +87,7 @@ public:
void setModel(Model *model); void setModel(Model *model);
void setFlowMode(bool b); 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); Q_INVOKABLE void removeImport(const QString &importUrl);
signals: signals:
@@ -123,7 +123,7 @@ private:
QShortcut *m_qmlSourceUpdateShortcut; QShortcut *m_qmlSourceUpdateShortcut;
AsynchronousImageCache &m_imageCache; AsynchronousImageCache &m_imageCache;
QPointer<Model> m_model; QPointer<Model> m_model;
ItemLibraryEntry m_currentitemLibraryEntry; QVariant m_itemToDrag;
bool m_updateRetry = false; bool m_updateRetry = false;
QString m_filterText; QString m_filterText;