Accessibility: Fix crash when updating in dtor

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 <jan-arve.saether@digia.com>
This commit is contained in:
Frederik Gladhorn 2013-03-18 15:59:17 +01:00 committed by The Qt Project
parent a3304489e8
commit 5147b1d410
6 changed files with 25 additions and 3 deletions

View File

@ -809,9 +809,13 @@ void AtSpiAdaptor::windowActivated(QObject* window, bool active)
return; return;
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(window); 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; delete iface;
QDBusVariant data; QDBusVariant data;

View File

@ -47,7 +47,7 @@
#include <qtreeview.h> #include <qtreeview.h>
#include <private/qtreewidget_p.h> #include <private/qtreewidget_p.h>
#include <QtGui/private/qaccessible2_p.h> #include <QtGui/private/qaccessible2_p.h>
#include <QDebug> #include <QtWidgets/private/qwidget_p.h>
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
@ -136,6 +136,11 @@ QAccessibleTable::QAccessibleTable(QWidget *w)
} }
} }
bool QAccessibleTable::isValid() const
{
return (view() && !qobject_cast<QWidget*>(view())->d_func()->data.in_destructor);
}
QAccessibleTable::~QAccessibleTable() QAccessibleTable::~QAccessibleTable()
{ {
} }

View File

@ -63,6 +63,7 @@ class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleObje
{ {
public: public:
explicit QAccessibleTable(QWidget *w); explicit QAccessibleTable(QWidget *w);
bool isValid() const;
virtual ~QAccessibleTable(); virtual ~QAccessibleTable();

View File

@ -55,6 +55,7 @@
#include <QRubberBand> #include <QRubberBand>
#include <QFocusFrame> #include <QFocusFrame>
#include <QMenu> #include <QMenu>
#include <QtWidgets/private/qwidget_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -152,6 +153,7 @@ QString Q_WIDGETS_EXPORT qt_accHotKey(const QString &text)
return QString(); return QString();
} }
// ### inherit QAccessibleObjectPrivate
class QAccessibleWidgetPrivate class QAccessibleWidgetPrivate
{ {
public: public:
@ -202,6 +204,13 @@ QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role, const Q
d->name = name; d->name = name;
} }
bool QAccessibleWidget::isValid() const
{
if (!object() || static_cast<QWidget *>(object())->d_func()->data.in_destructor)
return false;
return QAccessibleObject::isValid();
}
/*! \reimp */ /*! \reimp */
QWindow *QAccessibleWidget::window() const QWindow *QAccessibleWidget::window() const
{ {

View File

@ -56,6 +56,7 @@ class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject, public QAcc
{ {
public: public:
explicit QAccessibleWidget(QWidget *o, QAccessible::Role r = QAccessible::Client, const QString& name = QString()); explicit QAccessibleWidget(QWidget *o, QAccessible::Role r = QAccessible::Client, const QString& name = QString());
bool isValid() const;
QWindow *window() const; QWindow *window() const;
int childCount() const; int childCount() const;

View File

@ -704,6 +704,8 @@ private:
friend class QStyleSheetStyle; friend class QStyleSheetStyle;
friend struct QWidgetExceptionCleaner; friend struct QWidgetExceptionCleaner;
friend class QWidgetWindow; friend class QWidgetWindow;
friend class QAccessibleWidget;
friend class QAccessibleTable;
#ifndef QT_NO_GESTURES #ifndef QT_NO_GESTURES
friend class QGestureManager; friend class QGestureManager;
friend class QWinNativePanGestureRecognizer; friend class QWinNativePanGestureRecognizer;