diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2024-02-09 15:00:48 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2024-02-09 23:16:39 +0100 |
commit | a86321cb665b1af03b245b3b0fe0b57faa4a678f (patch) | |
tree | 7870b370e6c00d2bea090a468610997870f3e96f /src/widgets | |
parent | 16c27a83f0c9c6f53578dd56024719a709cafcb0 (diff) |
QTreeView: fix performance regression from accessibility updates
When expanding items in a tree view, the model as seen by accessibility
changes size and structure, and needs to be reset. This was done in
6a4afebc5ce8db69a6c9fb398cada31e6bad5e3c by emitting a ModelReset update
at the end of QTreeViewPrivate::layout when laying out the items had
changed the number of visible items.
However, QTreeViewPrivate::layout is called both recursively, and in a
loop when expanding all items, or expanding items to a certain depth,
resulting in a heavy performance hit when each recursion or iteration
causes the accessibility bridge to rebuild its representation from
scratch.
Instead, we now only store a flag that the model has to be reset in
QTreeViewPrivate::layout, and then trigger the reset in the function
that call layout, after the laying out is complete.
Fixes: QTBUG-122054
Pick-to: 6.7 6.6
Change-Id: Icb8384b56a4727c8c5050a1d501aebb55f48aafe
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/itemviews/qtreeview.cpp | 26 | ||||
-rw-r--r-- | src/widgets/itemviews/qtreeview_p.h | 6 |
2 files changed, 27 insertions, 5 deletions
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index de8f5ecdc9..744f29ca17 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2145,6 +2145,7 @@ void QTreeView::doItemsLayout() } QAbstractItemView::doItemsLayout(); d->header->doItemsLayout(); + d->updateAccessibility(); } /*! @@ -2708,6 +2709,7 @@ void QTreeView::expandAll() d->layout(-1, true); updateGeometries(); d->viewport->update(); + d->updateAccessibility(); } /*! @@ -2831,6 +2833,7 @@ void QTreeView::expandToDepth(int depth) updateGeometries(); d->viewport->update(); + d->updateAccessibility(); } /*! @@ -3142,6 +3145,7 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) beginAnimatedOperation(); #endif // animation } + updateAccessibility(); } void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem) @@ -3350,6 +3354,21 @@ void QTreeViewPrivate::columnsRemoved(const QModelIndex &parent, int start, int QAbstractItemViewPrivate::columnsRemoved(parent, start, end); } +void QTreeViewPrivate::updateAccessibility() +{ +#if QT_CONFIG(accessibility) + Q_Q(QTreeView); + if (pendingAccessibilityUpdate) { + pendingAccessibilityUpdate = false; + if (QAccessible::isActive()) { + QAccessibleTableModelChangeEvent event(q, QAccessibleTableModelChangeEvent::ModelReset); + QAccessible::updateAccessibility(&event); + } + } +#endif +} + + /** \internal creates and initialize the viewItem structure of the children of the element \li @@ -3374,11 +3393,8 @@ void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninit // QAccessibleTree's rowCount implementation uses viewItems.size(), so // we need to invalidate any cached accessibility data structures if // that value changes during the run of this function. - const auto resetModelIfNeeded = qScopeGuard([oldViewItemsSize = viewItems.size(), this, q]{ - if (oldViewItemsSize != viewItems.size() && QAccessible::isActive()) { - QAccessibleTableModelChangeEvent event(q, QAccessibleTableModelChangeEvent::ModelReset); - QAccessible::updateAccessibility(&event); - } + const auto resetModelIfNeeded = qScopeGuard([oldViewItemsSize = viewItems.size(), this]{ + pendingAccessibilityUpdate |= oldViewItemsSize != viewItems.size(); }); #endif diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h index be0a0ffe23..d0afdf1223 100644 --- a/src/widgets/itemviews/qtreeview_p.h +++ b/src/widgets/itemviews/qtreeview_p.h @@ -258,6 +258,12 @@ public: // tree position int treePosition; + // pending accessibility update +#if QT_CONFIG(accessibility) + bool pendingAccessibilityUpdate = false; +#endif + void updateAccessibility(); + QMetaObject::Connection animationConnection; QMetaObject::Connection selectionmodelConnection; std::array<QMetaObject::Connection, 2> modelConnections; |