From 74c9f9d83f9f5cb934d0b62b468c74df5a3b9a0d Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 22 Nov 2011 18:08:05 +0100 Subject: [PATCH] Accessibility: childAt returns interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit childAt used to return an integer. Return an interface instead. Not requiring a direct child to be returned allows optimizing by bypassing iterating through the hierarchy of accessibles. For QtQuick this is the only sensible way of implementing this. The bridges are still responsible for finding the top-most element. The default implementation in QAccessibleObject is sufficient to return direct children. The implementation in QAccessibleApplication is therfore no longer needed. Change-Id: Id7100dd5bcc3a98de516a7f4a12eaaa41cb46d26 Reviewed-by: Morten Johan Sørvig --- src/gui/accessible/qaccessible.cpp | 20 +++++--- src/gui/accessible/qaccessible.h | 2 +- src/gui/accessible/qaccessibleobject.cpp | 25 +++++----- src/gui/accessible/qaccessibleobject.h | 2 +- .../accessible/widgets/complexwidgets.cpp | 46 +++++++----------- .../accessible/widgets/complexwidgets.h | 4 +- src/plugins/accessible/widgets/itemviews.cpp | 12 ++--- src/plugins/accessible/widgets/itemviews.h | 10 ++-- .../accessible/widgets/qaccessiblemenu.cpp | 11 ++--- .../accessible/widgets/qaccessiblemenu.h | 10 ++-- .../accessible/widgets/qaccessiblewidgets.cpp | 48 ++++++------------- .../accessible/widgets/qaccessiblewidgets.h | 7 ++- .../cocoa/qcocoaaccessibilityelement.mm | 16 +++---- .../platforms/cocoa/qnsviewaccessibility.mm | 31 ++++-------- .../windows/qwindowsaccessibility.cpp | 24 +++++----- src/widgets/accessible/qaccessiblewidget.cpp | 22 --------- src/widgets/accessible/qaccessiblewidget.h | 1 - .../qaccessibility/tst_qaccessibility.cpp | 40 ++++++++++------ .../accessibilityinspector.cpp | 3 -- .../accessibilityinspector.h | 2 - .../accessibilityscenemanager.cpp | 4 +- util/accessibilityinspector/screenreader.cpp | 3 +- 22 files changed, 142 insertions(+), 201 deletions(-) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index c65e7df327c..7c23ede6fcc 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -740,8 +740,11 @@ void QAccessible::updateAccessibility(QObject *o, int who, Event reason) The functions childCount() and indexOfChild() return the number of children of an accessible object and the index a child object has - in its parent. The childAt() function returns the index of a child - at a given position. + in its parent. The childAt() function returns a child QAccessibleInterface + that is found at a position. The child does not have to be a direct + child. This allows bypassing intermediate layers when the parent already knows the + top-most child. childAt() is used for hit testing (finding the object + under the mouse). The relationTo() function provides information about how two different objects relate to each other, and navigate() allows @@ -875,18 +878,21 @@ QVector > QAccessibleInterfa } /*! - \fn int QAccessibleInterface::childAt(int x, int y) const + \fn QAccessibleInterface *QAccessibleInterface::childAt(int x, int y) const - Returns the 1-based index of the child that contains the screen - coordinates (\a x, \a y). This function returns 0 if the point is - positioned on the object itself. If the tested point is outside - the boundaries of the object this function returns -1. + Returns the QAccessibleInterface of a child that contains the screen coordinates (\a x, \a y). + If there are no children at this position this function returns 0. + The returned accessible must be a child, but not necessarily a direct child. This function is only relyable for visible objects (invisible object might not be laid out correctly). All visual objects provide this information. + A default implementation is provided for objects inheriting QAccessibleObject. This will iterate + over all children. If the widget manages its children (e.g. a table) it will be more efficient + to write a specialized implementation. + \sa rect() */ diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 6ee1885a3d9..3831b7d8e18 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -369,7 +369,7 @@ public: virtual QAccessible::Relation relationTo(const QAccessibleInterface *other) const; virtual QVector > relations() const; - virtual int childAt(int x, int y) const = 0; + virtual QAccessibleInterface *childAt(int x, int y) const = 0; // navigation, hierarchy virtual QAccessibleInterface *parent() const = 0; diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp index 18941437fed..b3e94790136 100644 --- a/src/gui/accessible/qaccessibleobject.cpp +++ b/src/gui/accessible/qaccessibleobject.cpp @@ -154,6 +154,18 @@ void QAccessibleObject::setText(QAccessible::Text, const QString &) { } +/*! \reimp */ +QAccessibleInterface *QAccessibleObject::childAt(int x, int y) const +{ + for (int i = 0; i < childCount(); ++i) { + QAccessibleInterface *childIface = child(i); + if (childIface->rect().contains(x,y)) { + return childIface; + } + } + return 0; +} + /*! \class QAccessibleApplication \brief The QAccessibleApplication class implements the QAccessibleInterface for QApplication. @@ -213,19 +225,6 @@ int QAccessibleApplication::indexOfChild(const QAccessibleInterface *child) cons return index; } -/*! \reimp */ -int QAccessibleApplication::childAt(int x, int y) const -{ - for (int i = 0; i < childCount(); ++i) { - QAccessibleInterface *childIface = child(i); - QRect geom = childIface->rect(); - if (geom.contains(x,y)) - return i+1; - delete childIface; - } - return rect().contains(x,y) ? 0 : -1; -} - /*! \reimp */ QAccessible::Relation QAccessibleApplication::relationTo(const QAccessibleInterface *other) const { diff --git a/src/gui/accessible/qaccessibleobject.h b/src/gui/accessible/qaccessibleobject.h index f2a9fd04309..ac385fcc39c 100644 --- a/src/gui/accessible/qaccessibleobject.h +++ b/src/gui/accessible/qaccessibleobject.h @@ -67,6 +67,7 @@ public: // properties QRect rect() const; void setText(QAccessible::Text t, const QString &text); + QAccessibleInterface *childAt(int x, int y) const; protected: virtual ~QAccessibleObject(); @@ -89,7 +90,6 @@ public: // navigation QAccessibleInterface *parent() const; - int childAt(int x, int y) const; QAccessibleInterface *child(int index) const; int navigate(QAccessible::RelationFlag, int, QAccessibleInterface **) const; diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index 91f13676d35..5f62ab1506f 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -1483,7 +1483,7 @@ public: bool isValid() const { return true; }// (!m_parent.isNull()) && m_parent->count() > m_index; } - int childAt(int, int) const { return 0; } + QAccessibleInterface *childAt(int, int) const { return 0; } int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } @@ -1661,7 +1661,7 @@ QComboBox *QAccessibleComboBox::comboBox() const return qobject_cast(object()); } -QAccessibleInterface* QAccessibleComboBox::child(int index) const +QAccessibleInterface *QAccessibleComboBox::child(int index) const { if (index == 0) { QAbstractItemView *view = comboBox()->view(); @@ -1679,10 +1679,10 @@ int QAccessibleComboBox::childCount() const return comboBox()->isEditable() ? 2 : 1; } -int QAccessibleComboBox::childAt(int x, int y) const +QAccessibleInterface *QAccessibleComboBox::childAt(int x, int y) const { if (comboBox()->isEditable() && comboBox()->lineEdit()->rect().contains(x, y)) - return 1; + return child(1); return 0; } @@ -1925,31 +1925,19 @@ int QAccessibleAbstractScrollArea::navigate(QAccessible::RelationFlag relation, return *target ? 0: -1; } -//int QAccessibleAbstractScrollArea::childAt(int x, int y) const -//{ -// if (!abstractScrollArea()->isVisible()) -// return -1; -//#if 0 -// const QRect globalSelfGeometry = rect(Self); -// if (!globalSelfGeometry.isValid() || !globalSelfGeometry.contains(QPoint(x, y))) -// return -1; -// const QWidgetList children = accessibleChildren(); -// for (int i = 0; i < children.count(); ++i) { -// const QWidget *child = children.at(i); -// const QRect globalChildGeometry = QRect(child->mapToGlobal(QPoint(0, 0)), child->size()); -// if (globalChildGeometry.contains(QPoint(x, y))) { -// return ++i; -// } -// } -// return 0; -//#else -// for (int i = childCount(); i >= 0; --i) { -// if (rect().contains(x, y)) -// return i; -// } -// return -1; -//#endif -//} +QAccessibleInterface *QAccessibleAbstractScrollArea::childAt(int x, int y) const +{ + if (!abstractScrollArea()->isVisible()) + return 0; + + for (int i = 0; i < childCount(); ++i) { + QPoint wpos = accessibleChildren().at(i)->mapToGlobal(QPoint(0, 0)); + QRect rect = QRect(wpos, accessibleChildren().at(i)->size()); + if (rect.contains(x, y)) + return child(i); + } + return 0; +} QAbstractScrollArea *QAccessibleAbstractScrollArea::abstractScrollArea() const { diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h index 2e80e24e0f1..1a69178a874 100644 --- a/src/plugins/accessible/widgets/complexwidgets.h +++ b/src/plugins/accessible/widgets/complexwidgets.h @@ -80,7 +80,7 @@ public: int indexOfChild(const QAccessibleInterface *child) const; bool isValid() const; int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; -// int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; //protected: QAbstractScrollArea *abstractScrollArea() const; @@ -255,7 +255,7 @@ public: explicit QAccessibleComboBox(QWidget *w); int childCount() const; - int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; int indexOfChild(const QAccessibleInterface *child) const; QAccessibleInterface* child(int index) const; diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 87956b139fd..03f9afe2756 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -366,7 +366,7 @@ QAccessible::State QAccessibleTable::state() const return QAccessible::Normal; } -int QAccessibleTable::childAt(int x, int y) const +QAccessibleInterface *QAccessibleTable::childAt(int x, int y) const { QPoint viewportOffset = view->viewport()->mapTo(view, QPoint(0,0)); QPoint indexPosition = view->mapFromGlobal(QPoint(x, y) - viewportOffset); @@ -374,9 +374,9 @@ int QAccessibleTable::childAt(int x, int y) const QModelIndex index = view->indexAt(indexPosition); if (index.isValid()) { - return logicalIndex(index); + return childFromLogical(logicalIndex(index)); } - return -1; + return 0; } int QAccessibleTable::childCount() const @@ -489,14 +489,14 @@ QModelIndex QAccessibleTree::indexFromLogical(int row, int column) const return modelIndex; } -int QAccessibleTree::childAt(int x, int y) const +QAccessibleInterface *QAccessibleTree::childAt(int x, int y) const { QPoint viewportOffset = view->viewport()->mapTo(view, QPoint(0,0)); QPoint indexPosition = view->mapFromGlobal(QPoint(x, y) - viewportOffset); QModelIndex index = view->indexAt(indexPosition); if (!index.isValid()) - return -1; + return 0; const QTreeView *treeView = qobject_cast(view); int row = treeView->d_func()->viewIndex(index) + (horizontalHeader() ? 1 : 0); @@ -504,7 +504,7 @@ int QAccessibleTree::childAt(int x, int y) const int i = row * view->model()->columnCount() + column + 1; Q_ASSERT(i > view->model()->columnCount()); - return i; + return child(i - 1); } int QAccessibleTree::childCount() const diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index 9f95285d169..be309e61a7d 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -71,7 +71,7 @@ public: QString text(QAccessible::Text t) const; QRect rect() const; - int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; int childCount() const; int indexOfChild(const QAccessibleInterface *) const; @@ -153,7 +153,7 @@ public: virtual ~QAccessibleTree() {} - int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; int childCount() const; int indexOfChild(const QAccessibleInterface *) const; @@ -184,7 +184,7 @@ public: QRect rect() const; bool isValid() const; - int childAt(int, int) const { return 0; } + QAccessibleInterface *childAt(int, int) const { return 0; } int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } @@ -231,7 +231,7 @@ public: QRect rect() const; bool isValid() const; - int childAt(int, int) const { return 0; } + QAccessibleInterface *childAt(int, int) const { return 0; } int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } @@ -268,7 +268,7 @@ public: QRect rect() const { return QRect(); } bool isValid() const { return true; } - int childAt(int, int) const { return 0; } + QAccessibleInterface *childAt(int, int) const { return 0; } int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index 2fe67fedfe4..95c5c050977 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -71,12 +71,12 @@ int QAccessibleMenu::childCount() const return menu()->actions().count(); } -int QAccessibleMenu::childAt(int x, int y) const +QAccessibleInterface *QAccessibleMenu::childAt(int x, int y) const { QAction *act = menu()->actionAt(menu()->mapFromGlobal(QPoint(x,y))); if(act && act->isSeparator()) act = 0; - return menu()->actions().indexOf(act) + 1; + return act ? new QAccessibleMenuItem(menu(), act) : 0; } QString QAccessibleMenu::text(QAccessible::Text t) const @@ -193,17 +193,16 @@ QAccessibleMenuItem::QAccessibleMenuItem(QWidget *owner, QAction *action) QAccessibleMenuItem::~QAccessibleMenuItem() {} -int QAccessibleMenuItem::childAt(int x, int y ) const +QAccessibleInterface *QAccessibleMenuItem::childAt(int x, int y ) const { for (int i = childCount(); i >= 0; --i) { QAccessibleInterface *childInterface = child(i); if (childInterface->rect().contains(x,y)) { - delete childInterface; - return i; + return childInterface; } delete childInterface; } - return -1; + return 0; } int QAccessibleMenuItem::childCount() const diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h index cf6a703b0c1..4ce161309bd 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ b/src/plugins/accessible/widgets/qaccessiblemenu.h @@ -59,7 +59,7 @@ public: explicit QAccessibleMenu(QWidget *w); int childCount() const; - int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; QString text(QAccessible::Text t) const; QAccessible::Role role() const; @@ -95,13 +95,13 @@ class QAccessibleMenuItem : public QAccessibleInterface, public QAccessibleActio public: explicit QAccessibleMenuItem(QWidget *owner, QAction *w); - virtual ~QAccessibleMenuItem(); - + ~QAccessibleMenuItem(); void *interface_cast(QAccessible::InterfaceType t); - int childAt(int x, int y) const; + int childCount() const; - int indexOfChild(const QAccessibleInterface * child) const; + QAccessibleInterface *childAt(int x, int y) const; bool isValid() const; + int indexOfChild(const QAccessibleInterface * child) const; QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 7387e2ea532..1e74de6ffdd 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -722,17 +722,17 @@ QVariant QAccessibleStackedWidget::invokeMethod(QAccessible::Method, const QVari } -int QAccessibleStackedWidget::childAt(int x, int y) const +QAccessibleInterface *QAccessibleStackedWidget::childAt(int x, int y) const { if (!stackedWidget()->isVisible()) - return -1; + return 0; QWidget *currentWidget = stackedWidget()->currentWidget(); if (!currentWidget) - return -1; + return 0; QPoint position = currentWidget->mapFromGlobal(QPoint(x, y)); if (currentWidget->rect().contains(position)) - return 1; - return -1; + return child(stackedWidget()->currentIndex()); + return 0; } int QAccessibleStackedWidget::childCount() const @@ -953,25 +953,6 @@ QRect QAccessibleMdiSubWindow::rect() const return QRect(pos, mdiSubWindow()->size()); } -int QAccessibleMdiSubWindow::childAt(int x, int y) const -{ - if (!mdiSubWindow()->isVisible()) - return -1; - if (!mdiSubWindow()->parent()) - return QAccessibleWidget::childAt(x, y); - const QRect globalGeometry = rect(); - if (!globalGeometry.isValid()) - return -1; - QAccessibleInterface *childIface = child(0); - const QRect globalChildGeometry = childIface->rect(); - delete childIface; - if (globalChildGeometry.isValid() && globalChildGeometry.contains(QPoint(x, y))) - return 1; - if (globalGeometry.contains(QPoint(x, y))) - return 0; - return -1; -} - QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const { return static_cast(object()); @@ -1344,17 +1325,16 @@ QRect QAccessibleTitleBar::rect() const return rect; } -int QAccessibleTitleBar::childAt(int x, int y) const +QAccessibleInterface *QAccessibleTitleBar::childAt(int x, int y) const { - for (int i = childCount(); i >= 0; --i) { - QAccessibleInterface *childIface = child(i - 1); + for (int i = 0; i < childCount(); ++i) { + QAccessibleInterface *childIface = child(i); if (childIface->rect().contains(x,y)) { - delete childIface; - return i; + return childIface; } delete childIface; } - return -1; + return 0; } QObject *QAccessibleTitleBar::object() const @@ -1463,21 +1443,21 @@ int QAccessibleMainWindow::indexOfChild(const QAccessibleInterface *iface) const return childIndex == -1 ? -1 : ++childIndex; } -int QAccessibleMainWindow::childAt(int x, int y) const +QAccessibleInterface *QAccessibleMainWindow::childAt(int x, int y) const { QWidget *w = widget(); if (!w->isVisible()) - return -1; + return 0; QPoint gp = w->mapToGlobal(QPoint(0, 0)); if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y)) - return -1; + return 0; QWidgetList kids = childWidgets(mainWindow(), true); QPoint rp = mainWindow()->mapFromGlobal(QPoint(x, y)); for (int i = 0; i < kids.size(); ++i) { QWidget *child = kids.at(i); if (!child->isWindow() && !child->isHidden() && child->geometry().contains(rp)) { - return i + 1; + return QAccessible::queryAccessibleInterface(child); } } return 0; diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index e8c2e6ddf51..a544fd941c6 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -122,7 +122,7 @@ public: explicit QAccessibleStackedWidget(QWidget *widget); QVariant invokeMethod(QAccessible::Method method, const QVariantList ¶ms); - int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; QAccessibleInterface *child(int index) const; @@ -173,7 +173,6 @@ public: int indexOfChild(const QAccessibleInterface *child) const; int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; QRect rect() const; - int childAt(int x, int y) const; protected: QMdiSubWindow *mdiSubWindow() const; @@ -261,12 +260,12 @@ public: int indexOfChild(const QAccessibleInterface *child) const; int childCount() const; QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + QAccessibleInterface *childAt(int x, int y) const; void setText(QAccessible::Text t, const QString &text); QString text(QAccessible::Text t) const; QAccessible::Role role() const; QRect rect () const; QAccessible::State state() const; - int childAt(int x, int y) const; QObject *object() const; bool isValid() const; @@ -287,7 +286,7 @@ public: QAccessibleInterface *child(int index) const; int childCount() const; int indexOfChild(const QAccessibleInterface *iface) const; - int childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const; QMainWindow *mainWindow() const; QVariant invokeMethod(QAccessible::Method method, const QVariantList ¶ms); diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 332577d6e95..5ad9e57c310 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -197,21 +197,19 @@ static QAccessibleInterface *acast(void *ptr) } - (id)accessibilityHitTest:(NSPoint)point { - int index = acast(accessibleInterface)->childAt(point.x, qt_mac_flipYCoordinate(point.y)); - // hit outside - if (index == -1) { - return 0; - } + if (!accessibleInterface) + return NSAccessibilityUnignoredAncestor(self); + QAccessibleInterface *childInterface = acast(accessibleInterface)->childAt(point.x, qt_mac_flipYCoordinate(point.y)); - // hit this element - if (index == 0) { + // No child found, meaning we hit this element. + if (!childInterface) { return NSAccessibilityUnignoredAncestor(self); } // hit a child, forward to child accessible interface. - QAccessibleInterface *childInterface = acast(accessibleInterface)->child(index - 1); - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:index - 1 parent:self accessibleInterface: childInterface]; + int childIndex = acast(accessibleInterface)->indexOfChild(childInterface); + QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:childIndex -1 parent:self accessibleInterface: childInterface]; return [accessibleElement accessibilityHitTest:point]; } diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm index 327bace123c..562ad4264a9 100644 --- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm +++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm @@ -83,34 +83,19 @@ } - (id)accessibilityHitTest:(NSPoint)point { + if (!m_accessibleRoot) + return [super accessibilityHitTest:point]; NSPoint windowPoint = [[self window] convertScreenToBase:point]; - NSPoint localPoint = [self convertPoint:windowPoint fromView:nil]; - int index = -1; - if (m_accessibleRoot) { - index = m_accessibleRoot->childAt(point.x, qt_mac_flipYCoordinate(point.y)); - - // qDebug() << "root rect" << m_accessibleRoot->rect(); - // qDebug() << "hit screen" << point.x << qt_mac_flipYCoordinate(point.y) << index; - // if (index > 0) { - // qDebug() << "child name" << m_accessibleRoot->child(index - 1)->text(QAccessible::Name); - // qDebug() << "child rect" << m_accessibleRoot->child(index - 1)->rect(); - // } - } - - // hit outside - if (index == -1) { + QAccessibleInterface *childInterface = m_accessibleRoot->childAt(point.x, qt_mac_flipYCoordinate(point.y)); + // No child found, meaning we hit the NSView + if (!childInterface) { return [super accessibilityHitTest:point]; } - // hit the NSView / top-level window - if (index == 0) { - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:index parent:self accessibleInterface:(void*)m_accessibleRoot]; - return [accessibleElement accessibilityHitTest:point]; - } - - // hit a child, forward to child accessible interface. - QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:index - 1 parent:self accessibleInterface:(void*)m_accessibleRoot->child(index -1)]; + // Hit a child, forward to child accessible interface. + int childIndex = m_accessibleRoot->indexOfChild(childInterface); + QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithIndex:childIndex -1 parent:self accessibleInterface: childInterface]; return [accessibleElement accessibilityHitTest:point]; } diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/qwindowsaccessibility.cpp index aa4507484da..53d7b33769c 100644 --- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp +++ b/src/plugins/platforms/windows/qwindowsaccessibility.cpp @@ -753,21 +753,23 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop, if (!accessible->isValid()) return E_FAIL; - int control = accessible->childAt(xLeft, yTop); - if (control == -1) { + QAccessibleInterface *child = accessible->childAt(xLeft, yTop); + if (child == 0) { + // no child found, return this item if it contains the coordinates + if (accessible->rect().contains(xLeft, yTop)) { + IDispatch *iface = 0; + QueryInterface(IID_IDispatch, (void**)&iface); + if (iface) { + (*pvarID).vt = VT_DISPATCH; + (*pvarID).pdispVal = iface; + return S_OK; + } + } (*pvarID).vt = VT_EMPTY; return S_FALSE; } - QAccessibleInterface *acc = 0; - if (control) - accessible->navigate(QAccessible::Child, control, &acc); - if (!acc) { - (*pvarID).vt = VT_I4; - (*pvarID).lVal = control; - return S_OK; - } - QWindowsAccessible* wacc = new QWindowsAccessible(acc); + QWindowsAccessible* wacc = new QWindowsAccessible(child); IDispatch *iface = 0; wacc->QueryInterface(IID_IDispatch, (void**)&iface); if (iface) { diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index a1c53e934e8..a2295f47490 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -221,28 +221,6 @@ QObject *QAccessibleWidget::parentObject() const return parent; } -/*! \reimp */ -int QAccessibleWidget::childAt(int x, int y) const -{ - QWidget *w = widget(); - if (!w->isVisible()) - return -1; - QPoint gp = w->mapToGlobal(QPoint(0, 0)); - if (!QRect(gp.x(), gp.y(), w->width(), w->height()).contains(x, y)) - return -1; - - for (int i = 0; i < childCount(); ++i) { - QAccessibleInterface *childIface = child(i); - bool found = false; - if (childIface->rect().contains(x, y)) - found = true; - delete childIface; - if (found) - return i + 1; - } - return 0; -} - /*! \reimp */ QRect QAccessibleWidget::rect() const { diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index b807dbc0888..01730f70709 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -64,7 +64,6 @@ public: int indexOfChild(const QAccessibleInterface *child) const; QAccessible::Relation relationTo(const QAccessibleInterface *other) const; - int childAt(int x, int y) const; QRect rect() const; QAccessibleInterface *parent() const; diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 2a838c0e3d2..9b14fb9e227 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -89,7 +89,6 @@ static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface, // QAccessibleInterface::indexOfChild(): // Verify that indexOfChild() returns an index equal to the index passed in int indexFromIndexOfChild = interface->indexOfChild(childInterface); - delete childInterface; if (indexFromIndexOfChild != index) { qWarning("tst_QAccessibility::verifyChild (indexOfChild()):"); qWarning() << "Expected:" << index; @@ -109,13 +108,21 @@ static inline bool verifyChild(QWidget *child, QAccessibleInterface *interface, // Calculate global child position and check that the interface // returns the correct index for that position. QPoint globalChildPos = child->mapToGlobal(QPoint(0, 0)); - int indexFromChildAt = interface->childAt(globalChildPos.x(), globalChildPos.y()); - if (indexFromChildAt != index) { + QAccessibleInterface *childAtInterface = interface->childAt(globalChildPos.x(), globalChildPos.y()); + if (!childAtInterface) { qWarning("tst_QAccessibility::verifyChild (childAt()):"); - qWarning() << "Expected:" << index; - qWarning() << "Actual: " << indexFromChildAt; + qWarning() << "Expected:" << childInterface; + qWarning() << "Actual: no child"; return false; } + if (childAtInterface->object() != childInterface->object()) { + qWarning("tst_QAccessibility::verifyChild (childAt()):"); + qWarning() << "Expected:" << childInterface; + qWarning() << "Actual: " << childAtInterface; + return false; + } + delete childInterface; + delete childAtInterface; // QAccessibleInterface::rect(): // Calculate global child geometry and check that the interface @@ -1931,11 +1938,14 @@ void tst_QAccessibility::mdiSubWindowTest() QCOMPARE(childRect(interface), QRect(globalWidgetPos, widgetGeometry.size())); // childAt - QCOMPARE(interface->childAt(-10, 0), -1); - QCOMPARE(interface->childAt(globalPos.x(), globalPos.y()), 0); - QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), 1); + QCOMPARE(interface->childAt(-10, 0), static_cast(0)); + QCOMPARE(interface->childAt(globalPos.x(), globalPos.y()), static_cast(0)); + QAccessibleInterface *child = interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()); + QCOMPARE(child->role(), QAccessible::PushButton); + QCOMPARE(child->text(QAccessible::Name), QString("QAccessibilityTest")); + delete child; testWindow->widget()->hide(); - QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), 0); + QCOMPARE(interface->childAt(globalWidgetPos.x(), globalWidgetPos.y()), static_cast(0)); } QTestAccessibility::clearEvents(); @@ -2288,7 +2298,7 @@ void tst_QAccessibility::abstractScrollAreaTest() QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&abstractScrollArea); QVERIFY(interface); QVERIFY(!interface->rect().isValid()); - QCOMPARE(interface->childAt(200, 200), -1); + QCOMPARE(interface->childAt(200, 200), static_cast(0)); abstractScrollArea.resize(400, 400); abstractScrollArea.show(); @@ -2767,7 +2777,7 @@ void tst_QAccessibility::calendarWidgetTest() QVERIFY(interface); QCOMPARE(interface->role(), QAccessible::Table); QVERIFY(!interface->rect().isValid()); - QCOMPARE(interface->childAt(200, 200), -1); + QCOMPARE(interface->childAt(200, 200), static_cast(0)); calendarWidget.resize(400, 300); calendarWidget.show(); @@ -2903,9 +2913,11 @@ void tst_QAccessibility::dockWidgetTest() QPoint globalPos = dock1->mapToGlobal(QPoint(0,0)); globalPos.rx()+=5; //### query style globalPos.ry()+=5; - int entry = accDock1->childAt(globalPos.x(), globalPos.y()); //### - QCOMPARE(entry, 1); - QAccessibleInterface *accTitleBar = accDock1->child(entry - 1); + QAccessibleInterface *childAt = accDock1->childAt(globalPos.x(), globalPos.y()); //### + QCOMPARE(childAt->role(), QAccessible::TitleBar); + int index = accDock1->indexOfChild(childAt); + delete childAt; + QAccessibleInterface *accTitleBar = accDock1->child(index - 1); QCOMPARE(accTitleBar->role(), QAccessible::TitleBar); QCOMPARE(accDock1->indexOfChild(accTitleBar), 1); diff --git a/util/accessibilityinspector/accessibilityinspector.cpp b/util/accessibilityinspector/accessibilityinspector.cpp index d451ed4ac74..af7fd521e87 100644 --- a/util/accessibilityinspector/accessibilityinspector.cpp +++ b/util/accessibilityinspector/accessibilityinspector.cpp @@ -67,9 +67,6 @@ void accessibilityUpdateHandler(QObject *object, int who, QAccessible::Event rea if (updateHandlerRecursion) return; - if (!qobject_cast(object)) - return; - updateHandlerRecursion = true; if (sceneManager) { diff --git a/util/accessibilityinspector/accessibilityinspector.h b/util/accessibilityinspector/accessibilityinspector.h index 504fecd6b5f..0ec25c94e04 100644 --- a/util/accessibilityinspector/accessibilityinspector.h +++ b/util/accessibilityinspector/accessibilityinspector.h @@ -64,8 +64,6 @@ public: void saveWindowGeometry(); signals: -public slots: - private: OptionsWidget *optionsWidget; MouseInterceptingGraphicsScene *accessibilityScene; diff --git a/util/accessibilityinspector/accessibilityscenemanager.cpp b/util/accessibilityinspector/accessibilityscenemanager.cpp index 9c987271fcd..9387aa625dd 100644 --- a/util/accessibilityinspector/accessibilityscenemanager.cpp +++ b/util/accessibilityinspector/accessibilityscenemanager.cpp @@ -158,7 +158,7 @@ void AccessibilitySceneManager::handleUpdate(QObject *object, QAccessible::Event m_animatedObjects.clear(); } else { - qDebug() << "other update" << object; +// qDebug() << "other update" << object; } } @@ -273,7 +273,7 @@ QGraphicsRectItem * AccessibilitySceneManager::processInterface(QAccessibleInter if (!m_rootItem) m_rootItem = item; - QString name = interface->text(QAccessibleInterface::Name); + QString name = interface->text(QAccessible::Name); QString description; // = interface->text(QAccessibleInterface::Description, child); QString role = translateRole(interface->role()); int childCount = interface->childCount(); diff --git a/util/accessibilityinspector/screenreader.cpp b/util/accessibilityinspector/screenreader.cpp index 3a73f213145..aa17bfb6eea 100644 --- a/util/accessibilityinspector/screenreader.cpp +++ b/util/accessibilityinspector/screenreader.cpp @@ -103,7 +103,7 @@ void ScreenReader::processTouchPoint() qDebug() << "touchPoint exit recursion overflow"; return; // outside } - +/* hit = currentInterface->childAt(m_currentTouchPoint.x(), m_currentTouchPoint.y()); //qDebug() << "hit" << hit; if (hit == -1) { @@ -121,6 +121,7 @@ void ScreenReader::processTouchPoint() delete currentInterface; currentInterface = childInterface; } +*/ } m_selectedInterface = currentInterface;