summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-12-09 15:17:54 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-12-16 13:15:56 +0100
commitc81e31461fd5a5bd2fe959f26b2e6d134b9a71e9 (patch)
treeed7196ef5892497c632f0e85d352fd6a0637bd95 /src/plugins/platforms/cocoa
parent4271114dc6b6c699efe11dc1a2b8946d2bbbb241 (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.mm41
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];