From 5147b1d4108e36f79aaf4aca539d5cf11726995e Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 18 Mar 2013 15:59:17 +0100 Subject: [PATCH] Accessibility: Fix crash when updating in dtor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This happens for example when running several tests. Widgets in destructor should be treated as invalid since their window pointer and other properties are no longer valid. When deleting a window containing only a table view there would be a table model reset update comming from the window being destroyed. Change-Id: Ia387c814333ce373fe132b189fc180787e36cdd5 Reviewed-by: Jan Arve Sæther --- src/platformsupport/linuxaccessibility/atspiadaptor.cpp | 8 ++++++-- src/plugins/accessible/widgets/itemviews.cpp | 7 ++++++- src/plugins/accessible/widgets/itemviews.h | 1 + src/widgets/accessible/qaccessiblewidget.cpp | 9 +++++++++ src/widgets/accessible/qaccessiblewidget_p.h | 1 + src/widgets/kernel/qwidget.h | 2 ++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp index 001976e9fe..050cb6a0bc 100644 --- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp +++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp @@ -809,9 +809,13 @@ void AtSpiAdaptor::windowActivated(QObject* window, bool active) return; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window); - Q_ASSERT(iface && iface->isValid()); + Q_ASSERT(iface); + Q_ASSERT(!active || iface->isValid()); - QString windowTitle = iface->text(QAccessible::Name); + QString windowTitle; + // in dtor it may be invalid + if (iface->isValid()) + windowTitle = iface->text(QAccessible::Name); delete iface; QDBusVariant data; diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index cb34116f32..822d9d8c77 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -47,7 +47,7 @@ #include #include #include -#include +#include #ifndef QT_NO_ACCESSIBILITY @@ -136,6 +136,11 @@ QAccessibleTable::QAccessibleTable(QWidget *w) } } +bool QAccessibleTable::isValid() const +{ + return (view() && !qobject_cast(view())->d_func()->data.in_destructor); +} + QAccessibleTable::~QAccessibleTable() { } diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index bba698bda2..af885fe6c1 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -63,6 +63,7 @@ class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObje { public: explicit QAccessibleTable(QWidget *w); + bool isValid() const; virtual ~QAccessibleTable(); diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 2b8e1a7036..dcbf276356 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -55,6 +55,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -152,6 +153,7 @@ QString Q_WIDGETS_EXPORT qt_accHotKey(const QString &text) return QString(); } +// ### inherit QAccessibleObjectPrivate class QAccessibleWidgetPrivate { public: @@ -202,6 +204,13 @@ QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role, const Q d->name = name; } +bool QAccessibleWidget::isValid() const +{ + if (!object() || static_cast(object())->d_func()->data.in_destructor) + return false; + return QAccessibleObject::isValid(); +} + /*! \reimp */ QWindow *QAccessibleWidget::window() const { diff --git a/src/widgets/accessible/qaccessiblewidget_p.h b/src/widgets/accessible/qaccessiblewidget_p.h index 803dc71409..cb1ce37734 100644 --- a/src/widgets/accessible/qaccessiblewidget_p.h +++ b/src/widgets/accessible/qaccessiblewidget_p.h @@ -56,6 +56,7 @@ class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject, public QAcc { public: explicit QAccessibleWidget(QWidget *o, QAccessible::Role r = QAccessible::Client, const QString& name = QString()); + bool isValid() const; QWindow *window() const; int childCount() const; diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 5c844d1566..f90f2ee5f5 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -704,6 +704,8 @@ private: friend class QStyleSheetStyle; friend struct QWidgetExceptionCleaner; friend class QWidgetWindow; + friend class QAccessibleWidget; + friend class QAccessibleTable; #ifndef QT_NO_GESTURES friend class QGestureManager; friend class QWinNativePanGestureRecognizer;