diff options
author | Yulong Bai <yulong.bai@qt.io> | 2019-10-10 23:05:16 +0200 |
---|---|---|
committer | Yulong Bai <yulong.bai@qt.io> | 2019-10-27 17:40:44 +0200 |
commit | a21d4395f4f9afea52b6c2da359ce6ad21ebc763 (patch) | |
tree | 8aa2791b581ba2099676343a7a616350b21b63b8 /src | |
parent | 73cb5cb01e9531d2b2249597a64d57fa0029c300 (diff) |
Drag'n'Drop: fix attached Drag object deleted when DnD is progressing
The attached Drag object's owner, i.e. its parent, is also the dragged
item. So the attached Drag object will also be destroyed as the dragged
item is deleted.
Fixes: QTBUG-65701
Change-Id: I39b0a3180f205c427deed5c70cd1912524f9324e
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qdnd.cpp | 9 | ||||
-rw-r--r-- | src/gui/kernel/qdnd_p.h | 4 | ||||
-rw-r--r-- | src/gui/kernel/qdrag.cpp | 7 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbdrag.cpp | 8 |
4 files changed, 19 insertions, 9 deletions
diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index 5c5f166554..dd541af3b8 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -113,11 +113,12 @@ Qt::DropAction QDragManager::drag(QDrag *o) m_object->d_func()->target = 0; - QGuiApplicationPrivate::instance()->notifyDragStarted(o); + QGuiApplicationPrivate::instance()->notifyDragStarted(m_object.data()); const Qt::DropAction result = m_platformDrag->drag(m_object); - m_object = 0; - if (!m_platformDrag->ownsDragObject()) - o->deleteLater(); + if (!m_object.isNull() && !m_platformDrag->ownsDragObject()) + m_object->deleteLater(); + + m_object.clear(); return result; } diff --git a/src/gui/kernel/qdnd_p.h b/src/gui/kernel/qdnd_p.h index 8f8eb03f87..f095fbf7a0 100644 --- a/src/gui/kernel/qdnd_p.h +++ b/src/gui/kernel/qdnd_p.h @@ -101,13 +101,13 @@ public: void setCurrentTarget(QObject *target, bool dropped = false); QObject *currentTarget() const; - QDrag *object() const { return m_object; } + QPointer<QDrag> object() const { return m_object; } QObject *source() const; private: QObject *m_currentDropTarget; QPlatformDrag *m_platformDrag; - QDrag *m_object; + QPointer<QDrag> m_object; static QDragManager *m_instance; Q_DISABLE_COPY_MOVE(QDragManager) diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp index dcd0d13d5c..8e2f7be23e 100644 --- a/src/gui/kernel/qdrag.cpp +++ b/src/gui/kernel/qdrag.cpp @@ -279,8 +279,11 @@ Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defa } d->supported_actions = supportedActions; d->default_action = transformedDefaultDropAction; - d->executed_action = QDragManager::self()->drag(this); - + QPointer<QDrag> self = this; + auto executed_action = QDragManager::self()->drag(self.data()); + if (self.isNull()) + return Qt::IgnoreAction; + d->executed_action = executed_action; return d->executed_action; } diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 1ce947165d..3d525598ca 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -354,6 +354,11 @@ bool QXcbDrag::findXdndAwareTarget(const QPoint &globalPos, xcb_window_t *target void QXcbDrag::move(const QPoint &globalPos, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { + // currentDrag() might be deleted while 'drag' is progressing + if (!currentDrag()) { + cancel(); + return; + } // The source sends XdndEnter and XdndPosition to the target. if (source_sameanswer.contains(globalPos) && source_sameanswer.isValid()) return; @@ -1076,7 +1081,8 @@ void QXcbDrag::cancel() send_leave(); // remove canceled object - currentDrag()->deleteLater(); + if (currentDrag()) + currentDrag()->deleteLater(); canceled = true; } |