diff options
-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; } |