From 74c9f9d83f9f5cb934d0b62b468c74df5a3b9a0d Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 22 Nov 2011 18:08:05 +0100 Subject: 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 +- src/plugins/accessible/widgets/complexwidgets.cpp | 46 ++++++++------------- src/plugins/accessible/widgets/complexwidgets.h | 4 +- src/plugins/accessible/widgets/itemviews.cpp | 12 +++--- src/plugins/accessible/widgets/itemviews.h | 10 ++--- src/plugins/accessible/widgets/qaccessiblemenu.cpp | 11 +++-- src/plugins/accessible/widgets/qaccessiblemenu.h | 10 ++--- .../accessible/widgets/qaccessiblewidgets.cpp | 48 +++++++--------------- .../accessible/widgets/qaccessiblewidgets.h | 7 ++-- .../platforms/cocoa/qcocoaaccessibilityelement.mm | 16 ++++---- .../platforms/cocoa/qnsviewaccessibility.mm | 31 ++++---------- .../platforms/windows/qwindowsaccessibility.cpp | 24 ++++++----- src/widgets/accessible/qaccessiblewidget.cpp | 22 ---------- src/widgets/accessible/qaccessiblewidget.h | 1 - .../other/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 c65e7df327..7c23ede6fc 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 6ee1885a3d..3831b7d8e1 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 18941437fe..b3e9479013 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 f2a9fd0430..ac385fcc39 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 91f13676d3..5f62ab1506 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 2e80e24e0f..1a69178a87 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 87956b139f..03f9afe275 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 9f95285d16..be309e61a7 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 2fe67fedfe..95c5c05097 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 cf6a703b0c..4ce161309b 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 7387e2ea53..1e74de6ffd 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 e8c2e6ddf5..a544fd941c 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 332577d6e9..5ad9e57c31 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 327bace123..562ad4264a 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 aa4507484d..53d7b33769 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 a1c53e934e..a2295f4749 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 b807dbc088..01730f7070 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 2a838c0e3d..9b14fb9e22 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 d451ed4ac7..af7fd521e8 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 504fecd6b5..0ec25c94e0 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 9c987271fc..9387aa625d 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 3a73f21314..aa17bfb6ee 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; -- cgit v1.2.3