diff options
author | Gabriel de Dietrich <gabriel.dedietrich@qt.io> | 2016-04-29 16:32:42 -0700 |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dedietrich@qt.io> | 2016-05-10 18:32:49 +0000 |
commit | ce37467acf34edf1380f896a0942b616dc4cbead (patch) | |
tree | 6ade0fed6e024d49cfd27df2f272d1b61b570028 /src/widgets/kernel/qapplication.cpp | |
parent | 6a84a51611f69f3641ae47bbd7b6bd5266ae88ef (diff) |
Acknowledge QWidgetWindow::widget() may be null
We guard QWidgetWindow's widget with a QPointer to avoid
sending it events during destruction (which may result in
undefined behavior, since this originates from ~QObject and
we expect the object to behave as a QWidget). Therefore, we
need to harden all access to that widget since it can now
be null, specially during destruction.
As an example, QGestureManager may crash when we delete a
top-level widget. The crash stack trace is:
1 QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>::data() const
2 QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>::pointer qGetPtrHelper<QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>>(QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>> const&)
3 QWidget::d_func()
4 QGestureManager::filterEvent(QWidget *, QEvent *) <-- the widget ptr is null
5 QGestureManager::filterEvent(QObject *, QEvent *)
6 QApplication::notify(QObject *, QEvent *)
7 QCoreApplication::notifyInternal2(QObject *, QEvent *)
8 QCoreApplication::sendEvent(QObject *, QEvent *)
9 QWindow::destroy()
10 QWidgetPrivate::deleteTLSysExtra()
11 QWidgetPrivate::deleteExtra()
12 QWidgetPrivate::~QWidgetPrivate()
13 QWidgetPrivate::~QWidgetPrivate()
14 QWidgetPrivate::~QWidgetPrivate()
15 QScopedPointerDeleter<QObjectData>::cleanup(QObjectData *)
16 QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>::~QScopedPointer()
17 QScopedPointer<QObjectData, QScopedPointerDeleter<QObjectData>>::~QScopedPointer()
18 QObject::~QObject()
19 QWidget::~QWidget()
Task-number: QTBUG-53103
Change-Id: I1bb32648270c4f7791f668b8f0b639ddb4235703
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Diffstat (limited to 'src/widgets/kernel/qapplication.cpp')
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index a459a57482..fcc195f601 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2249,10 +2249,10 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) QApplication::setActiveWindow(tlw); // QTBUG-37126, Active X controls may set the focus on native child widgets. if (wnd && tlw && wnd != tlw->windowHandle()) { - if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) { - if (widgetWindow->widget()->inherits("QAxHostWidget")) - widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); - } + if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) + if (QWidget *widget = widgetWindow->widget()) + if (widget->inherits("QAxHostWidget")) + widget->setFocus(Qt::ActiveWindowFocusReason); } } |