1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-07-07 10:51:45 +00:00

Fix accessibility ancestor tree

Before this commit, KItemListViewAccessible would always return
nullptr as its parent. This meant that accessibility software would
have to guess to which window/hierarchy the KItemListView belongs
to. Guessing shouldn't be necessary here.

This commit makes sure that the KItemListView always returns a
sensible parent in the accessible hierarchy. It does so by
explicitly setting the accessible parent for every KItemListView
after construction in the DolphinView contructor. Since
KItemListView now always knows about its accessible parent, the
accessibleInterfaceFactory can always ask the KItemListView for
that information when constructing the QAccessibleInterfaces.

Fixes https://invent.kde.org/system/dolphin/-/issues/47.
This commit is contained in:
Felix Ernst 2023-07-17 17:13:51 +03:00 committed by Felix Ernst
parent 7a6cba7f51
commit 549fad2dae
7 changed files with 54 additions and 5 deletions

View File

@ -50,9 +50,14 @@ QAccessibleInterface *accessibleInterfaceFactory(const QString &key, QObject *ob
Q_UNUSED(key)
if (KItemListContainer *container = qobject_cast<KItemListContainer *>(object)) {
if (auto controller = container->controller(); controller) {
if (KItemListView *view = controller->view(); view && view->accessibleParent()) {
return view->accessibleParent();
}
}
return new KItemListContainerAccessible(container);
} else if (KItemListView *view = qobject_cast<KItemListView *>(object)) {
return new KItemListViewAccessible(view);
return new KItemListViewAccessible(view, view->accessibleParent());
}
return nullptr;
@ -337,6 +342,19 @@ KItemListGroupHeaderCreatorBase *KItemListView::groupHeaderCreator() const
return m_groupHeaderCreator;
}
#ifndef QT_NO_ACCESSIBILITY
void KItemListView::setAccessibleParentsObject(KItemListContainer *accessibleParentsObject)
{
Q_ASSERT(!m_accessibleParent);
m_accessibleParent = new KItemListContainerAccessible(accessibleParentsObject);
}
KItemListContainerAccessible *KItemListView::accessibleParent()
{
Q_CHECK_PTR(m_accessibleParent); // We always want the accessibility tree/hierarchy to be complete.
return m_accessibleParent;
}
#endif
QSizeF KItemListView::itemSize() const
{
return m_itemSize;

View File

@ -21,6 +21,8 @@
#include <QGraphicsWidget>
#include <QSet>
class KItemListContainer;
class KItemListContainerAccessible;
class KItemListController;
class KItemListGroupHeaderCreatorBase;
class KItemListHeader;
@ -142,6 +144,18 @@ public:
void setGroupHeaderCreator(KItemListGroupHeaderCreatorBase *groupHeaderCreator);
KItemListGroupHeaderCreatorBase *groupHeaderCreator() const;
#ifndef QT_NO_ACCESSIBILITY
/**
* Uses \a parent to create an accessible object for \a parent. That accessible object will
* then be used as the accessible parent of the accessible object for this KItemListView.
* Make sure \a parent is the container which contains this specific KItemListView.
* This method must be called once before the accessible interface is queried for this class.
*/
void setAccessibleParentsObject(KItemListContainer *accessibleParentsObject);
/** The parent of the QAccessibilityInterface of this class. */
KItemListContainerAccessible *accessibleParent();
#endif
/**
* @return The basic size of all items. The size of an item may be larger than
* the basic size (see KItemListView::itemRect()).
@ -711,6 +725,10 @@ private:
QList<QByteArray> m_visibleRoles;
mutable KItemListWidgetCreatorBase *m_widgetCreator;
mutable KItemListGroupHeaderCreatorBase *m_groupHeaderCreator;
#ifndef QT_NO_ACCESSIBILITY
/** The object that will be the parent of this classes QAccessibleInterface. */
KItemListContainerAccessible *m_accessibleParent = nullptr;
#endif
KItemListStyleOption m_styleOption;
QHash<int, KItemListWidget *> m_visibleItems;

View File

@ -21,10 +21,12 @@ KItemListView *KItemListViewAccessible::view() const
return qobject_cast<KItemListView *>(object());
}
KItemListViewAccessible::KItemListViewAccessible(KItemListView *view_)
KItemListViewAccessible::KItemListViewAccessible(KItemListView *view_, KItemListContainerAccessible *parent)
: QAccessibleObject(view_)
, m_parent(parent)
{
Q_ASSERT(view());
Q_CHECK_PTR(parent);
m_cells.resize(childCount());
}
@ -208,8 +210,7 @@ QAccessibleInterface *KItemListViewAccessible::childAt(int x, int y) const
QAccessibleInterface *KItemListViewAccessible::parent() const
{
// FIXME: return KItemListContainerAccessible here
return nullptr;
return m_parent;
}
int KItemListViewAccessible::childCount() const

View File

@ -18,11 +18,12 @@
class KItemListView;
class KItemListContainer;
class KItemListContainerAccessible;
class DOLPHIN_EXPORT KItemListViewAccessible : public QAccessibleObject, public QAccessibleTableInterface
{
public:
explicit KItemListViewAccessible(KItemListView *view);
explicit KItemListViewAccessible(KItemListView *view, KItemListContainerAccessible *parent);
~KItemListViewAccessible() override;
void *interface_cast(QAccessible::InterfaceType type) override;
@ -81,6 +82,8 @@ private:
QAccessible::Id id;
};
mutable QVector<AccessibleIdWrapper> m_cells;
KItemListContainerAccessible *m_parent;
};
class DOLPHIN_EXPORT KItemListAccessibleCell : public QAccessibleInterface, public QAccessibleTableCellInterface

View File

@ -48,6 +48,9 @@ void KItemListControllerExpandTest::initTestCase()
m_view = new KFileItemListView();
m_controller = new KItemListController(m_model, m_view, this);
m_container = new KItemListContainer(m_controller);
#ifndef QT_NO_ACCESSIBILITY
m_view->setAccessibleParentsObject(m_container);
#endif
m_controller = m_container->controller();
m_controller->setSelectionBehavior(KItemListController::MultiSelection);
m_selectionManager = m_controller->selectionManager();

View File

@ -109,6 +109,9 @@ void KItemListControllerTest::initTestCase()
m_view = new KFileItemListView();
m_controller = new KItemListController(m_model, m_view, this);
m_container = new KItemListContainer(m_controller);
#ifndef QT_NO_ACCESSIBILITY
m_view->setAccessibleParentsObject(m_container);
#endif
m_controller = m_container->controller();
m_controller->setSelectionBehavior(KItemListController::MultiSelection);
m_selectionManager = m_controller->selectionManager();

View File

@ -129,6 +129,9 @@ DolphinView::DolphinView(const QUrl &url, QWidget *parent)
m_container = new KItemListContainer(controller, this);
m_container->installEventFilter(this);
#ifndef QT_NO_ACCESSIBILITY
m_view->setAccessibleParentsObject(m_container);
#endif
setFocusProxy(m_container);
connect(m_container->horizontalScrollBar(), &QScrollBar::valueChanged, this, [=] {
hideToolTip();