diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-12-09 15:17:54 +0100 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-12-16 13:15:56 +0100 |
commit | c81e31461fd5a5bd2fe959f26b2e6d134b9a71e9 (patch) | |
tree | ed7196ef5892497c632f0e85d352fd6a0637bd95 /src/plugins/platforms/cocoa | |
parent | 4271114dc6b6c699efe11dc1a2b8946d2bbbb241 (diff) |
macOS a11y: rebuild table model if out-of-bounds cell is requested
While it is the itemview's responsibility to keep the accessibility
bridge updated about changes in the view's structure and size, we
have experienced a number of assertions getting triggered when that
wasn't done correctly.
Instead of an assert (or hard crash in release builds), recreate the
table representation in the accessibility bridge when a cell that is
out-of-bounds for the current representation is requested. Emit a
warning message to inform widget authors, and improve the debug
message with information about the column count as well.
Amends 52c2b82082b535123c0eecafe1ec1e4e4190df2a.
Pick-to: 6.7 6.6
Change-Id: I19c20a932153268a5176d7378c485277088f10bf
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm index 0f76d564cd..fdd089e72d 100644 --- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm +++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm @@ -135,19 +135,37 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of if (tableInterface) { auto *tableElement = [QMacAccessibilityElement elementWithInterface:table]; Q_ASSERT(tableElement); - Q_ASSERT(tableElement->rows); - - qCDebug(lcAccessibilityTable) << "Creating cell representation for" - << m_rowIndex << m_columnIndex - << "in table with" - << tableElement->rows.count << "rows"; + if (!tableElement->rows + || int(tableElement->rows.count) <= m_rowIndex + || int(tableElement->rows.count) != tableInterface->rowCount()) { + qCWarning(lcAccessibilityTable) + << "Cell requested for row" << m_rowIndex << "is out of" + << "bounds for table with" << (tableElement->rows ? + tableElement->rows.count : tableInterface->rowCount()) + << "rows! Resizing table model."; + [tableElement updateTableModel]; + } + Q_ASSERT(tableElement->rows); Q_ASSERT(int(tableElement->rows.count) > m_rowIndex); + auto *rowElement = tableElement->rows[m_rowIndex]; - if (!rowElement->columns) { + if (!rowElement->columns || int(rowElement->columns.count) != tableInterface->columnCount()) { + if (rowElement->columns) { + qCWarning(lcAccessibilityTable) + << "Table representation column count is out of sync:" + << rowElement->columns.count << "!=" << tableInterface->columnCount(); + } rowElement->columns = [rowElement populateTableRow:rowElement->columns count:tableInterface->columnCount()]; } + + qCDebug(lcAccessibilityTable) << "Creating cell representation for" + << m_rowIndex << m_columnIndex + << "in table with" + << tableElement->rows.count << "rows and" + << rowElement->columns.count << "columns"; + rowElement->columns[m_columnIndex] = self; } } @@ -223,6 +241,10 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSMutableArray *)populateTableArray:(NSMutableArray *)array role:(NSAccessibilityRole)role count:(int)count { if (QAccessibleInterface *iface = self.qtInterface) { + if (array && int(array.count) != count) { + [array release]; + array = nil; + } if (!array) { array = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:count]; [array retain]; @@ -253,6 +275,11 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of - (NSMutableArray *)populateTableRow:(NSMutableArray *)array count:(int)count { Q_ASSERT(synthesizedRole == NSAccessibilityRowRole); + if (array && int(array.count) != count) { + [array release]; + array = nil; + } + if (!array) { array = [NSMutableArray<QMacAccessibilityElement *> arrayWithCapacity:count]; [array retain]; |