From a132e0254005b2954b11705b32650c9018049187 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Mon, 18 Nov 2019 15:00:58 +0100 Subject: Fix QAccessibleWidget::focusChild() to return focused descendant This method should not ignore accessibility objects without corresponding widget. The widget may have parts with their own QAccessibilityInterface and these can be also focused. VoiceOver ignores them if they are not returned by focusChild(). QAccessibleTabBar::focusChild() has been implemented to demonstrate the concept and make tab titles of QTabBar readable by VoiceOver. Task-number: QTBUG-78284 Change-Id: Id7c62d86154bbd5d47d6bbee8cb7d05268c2e151 Reviewed-by: Allan Sandfeld Jensen --- src/widgets/accessible/complexwidgets.cpp | 15 ++++++++++++++- src/widgets/accessible/complexwidgets_p.h | 1 + src/widgets/accessible/qaccessiblewidget.cpp | 12 ++++++++---- 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'src/widgets/accessible') diff --git a/src/widgets/accessible/complexwidgets.cpp b/src/widgets/accessible/complexwidgets.cpp index 63c6fbb9bb..5c993262bf 100644 --- a/src/widgets/accessible/complexwidgets.cpp +++ b/src/widgets/accessible/complexwidgets.cpp @@ -108,7 +108,10 @@ public: s.invalid = true; return s; } - return parent()->state(); + + QAccessible::State s = parent()->state(); + s.focused = (m_index == m_parent->currentIndex()); + return s; } QRect rect() const override { if (!isValid()) @@ -216,6 +219,16 @@ QTabBar *QAccessibleTabBar::tabBar() const return qobject_cast(object()); } +QAccessibleInterface* QAccessibleTabBar::focusChild() const +{ + for (int i = 0; i < childCount(); ++i) { + if (child(i)->state().focused) + return child(i); + } + + return nullptr; +} + QAccessibleInterface* QAccessibleTabBar::child(int index) const { if (QAccessible::Id id = m_childInterfaces.value(index)) diff --git a/src/widgets/accessible/complexwidgets_p.h b/src/widgets/accessible/complexwidgets_p.h index e7a32c7264..335e257476 100644 --- a/src/widgets/accessible/complexwidgets_p.h +++ b/src/widgets/accessible/complexwidgets_p.h @@ -112,6 +112,7 @@ public: explicit QAccessibleTabBar(QWidget *w); ~QAccessibleTabBar(); + QAccessibleInterface *focusChild() const override; int childCount() const override; QString text(QAccessible::Text t) const override; diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 27e6b09dc7..3ab66c4ce4 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -374,11 +374,15 @@ QAccessibleInterface *QAccessibleWidget::focusChild() const QWidget *fw = widget()->focusWidget(); if (!fw) - return 0; + return nullptr; - if (isAncestor(widget(), fw) || fw == widget()) - return QAccessible::queryAccessibleInterface(fw); - return 0; + if (isAncestor(widget(), fw)) { + QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(fw); + if (!iface || iface == this || !iface->focusChild()) + return iface; + return iface->focusChild(); + } + return nullptr; } /*! \reimp */ -- cgit v1.2.3