aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickwindow.cpp
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-04-24 12:46:44 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-04-24 18:38:00 +0000
commit127659c45020a83b80eeed7106c1f377a36c5c77 (patch)
tree101acd9d0d36da0a2d64f2b8eb172f3af90ef16c /src/quick/items/qquickwindow.cpp
parent913dc3f4f2be7c2c23237bcb9bffb3192cb10d60 (diff)
QQuickWindow: Don’t crash on events during destruction
Deleting d->contentItem may call into the platform plugin, for example if the contentItem is a Window. This can again make the platform (plugin) generate events for the QQuickWindow that is being destroyed. The QQuickWindow may try to use the now invalid d->contentItem during event processing, and crash. This is especially prone to happening if/when the platform plugin does less queuing of events, for example on macOS after commit ed483346. Fix this by clearing the d->contentItem pointer before deleting it. Also make sure all d->contentItem accesses have nullptr checks. Task-number: QTBUG-67802 Change-Id: Ieff97711fbe15818948d4b6ade069b096a55c683 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/quick/items/qquickwindow.cpp')
-rw-r--r--src/quick/items/qquickwindow.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 48eba6a7a0..b0b747a5eb 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -256,14 +256,16 @@ void QQuickWindow::hideEvent(QHideEvent *)
void QQuickWindow::focusOutEvent(QFocusEvent *ev)
{
Q_D(QQuickWindow);
- d->contentItem->setFocus(false, ev->reason());
+ if (d->contentItem)
+ d->contentItem->setFocus(false, ev->reason());
}
/*! \reimp */
void QQuickWindow::focusInEvent(QFocusEvent *ev)
{
Q_D(QQuickWindow);
- d->contentItem->setFocus(true, ev->reason());
+ if (d->contentItem)
+ d->contentItem->setFocus(true, ev->reason());
d->updateFocusItemTransform();
}
@@ -1315,7 +1317,9 @@ QQuickWindow::~QQuickWindow()
#if QT_CONFIG(draganddrop)
delete d->dragGrabber; d->dragGrabber = nullptr;
#endif
- delete d->contentItem; d->contentItem = nullptr;
+ QQuickRootItem *root = d->contentItem;
+ d->contentItem = nullptr;
+ delete root;
qDeleteAll(d->pointerEventInstances);
d->pointerEventInstances.clear();
@@ -1571,6 +1575,8 @@ bool QQuickWindow::event(QEvent *e)
return d->deliverTouchCancelEvent(static_cast<QTouchEvent*>(e));
break;
case QEvent::Enter: {
+ if (!d->contentItem)
+ return false;
QEnterEvent *enter = static_cast<QEnterEvent*>(e);
bool accepted = enter->isAccepted();
bool delivered = d->deliverHoverEvent(d->contentItem, enter->windowPos(), d->lastMousePosition,
@@ -1592,7 +1598,8 @@ bool QQuickWindow::event(QEvent *e)
break;
#endif
case QEvent::WindowDeactivate:
- contentItem()->windowDeactivateEvent();
+ if (d->contentItem)
+ d->contentItem->windowDeactivateEvent();
break;
case QEvent::Close: {
// TOOD Qt 6 (binary incompatible)
@@ -1617,7 +1624,8 @@ bool QQuickWindow::event(QEvent *e)
}
#if QT_CONFIG(gestures)
case QEvent::NativeGesture:
- d->deliverNativeGestureEvent(d->contentItem, static_cast<QNativeGestureEvent*>(e));
+ if (d->contentItem)
+ d->deliverNativeGestureEvent(d->contentItem, static_cast<QNativeGestureEvent*>(e));
break;
#endif
case QEvent::ShortcutOverride:
@@ -1937,7 +1945,8 @@ void QQuickWindow::wheelEvent(QWheelEvent *event)
return;
event->ignore();
- d->deliverWheelEvent(d->contentItem, event);
+ if (d->contentItem)
+ d->deliverWheelEvent(d->contentItem, event);
d->lastWheelEventAccepted = event->isAccepted();
}
#endif // wheelevent