Skip to content

Commit

Permalink
Drag'n'Drop: fix crash when widgets are destroyed during event handling
Browse files Browse the repository at this point in the history
Widgets might be destroyed when handling a dragMoveEvent, in which case
the following code will operate on dangling pointers or null pointers.
Use a QPointer to watch for the original event receiver to disappear,
and add the necessary checks for the objects we deliver events to being
null.

Change-Id: I4ca2f182540ae21113f4bea4e5c569e983cc58bf
Fixes: QTBUG-78907
Reviewed-by: Gatis Paeglis <[email protected]>
  • Loading branch information
vohi authored and ec1oud committed Oct 10, 2019
1 parent 9845c06 commit 3dbc759
Showing 1 changed file with 13 additions and 9 deletions.
22 changes: 13 additions & 9 deletions src/widgets/kernel/qwidgetwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ void QWidgetWindow::handleDragEnterEvent(QDragEnterEvent *event, QWidget *widget

void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
{
auto *widget = findDnDTarget(m_widget, event->pos());
QPointer<QWidget> widget = findDnDTarget(m_widget, event->pos());
if (!widget) {
event->ignore();
if (m_dragTarget) { // Send DragLeave to previous
Expand All @@ -908,14 +908,18 @@ void QWidgetWindow::handleDragMoveEvent(QDragMoveEvent *event)
QGuiApplication::forwardEvent(m_dragTarget, &leaveEvent, event);
m_dragTarget = nullptr;
}
// Send DragEnter to new widget.
handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget);
// Handling 'DragEnter' should suffice for the application.
translated.setDropAction(event->dropAction());
translated.setAccepted(event->isAccepted());
// The drag enter event is always immediately followed by a drag move event,
// see QDragEnterEvent documentation.
QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
// widget might have been deleted when handling the leaveEvent
if (widget) {
// Send DragEnter to new widget.
handleDragEnterEvent(static_cast<QDragEnterEvent*>(event), widget);
// Handling 'DragEnter' should suffice for the application.
translated.setDropAction(event->dropAction());
translated.setAccepted(event->isAccepted());
// The drag enter event is always immediately followed by a drag move event,
// see QDragEnterEvent documentation.
if (m_dragTarget)
QGuiApplication::forwardEvent(m_dragTarget, &translated, event);
}
}
event->setAccepted(translated.isAccepted());
event->setDropAction(translated.dropAction());
Expand Down

0 comments on commit 3dbc759

Please sign in to comment.