vcl/unx/gtk3/a11y/atkselection.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
New commits: commit eec233bf33ac0d9ac1ba0ecc669a5ecf58626ef2 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Oct 26 16:51:35 2021 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Oct 28 20:36:14 2021 +0200 gtk3 a11y: Use correct index when deselecting child The AT-SPI selection interface provides two functions to unselect: gboolean atspi_selection_deselect_selected_child (AtspiSelection *obj, gint selected_child_index, GError **error); gboolean atspi_selection_deselect_child (AtspiSelection *obj, gint child_index, GError **error); For the first one, 'atspi_selection_deselect_selected_child', "child_index is the index in the selected-children list, not the index in the parent container." [1] For the second one, 'atspi_selection_deselect_child', "child_index is the index of the child in the parent container". [2] ATKSelection, on the other hand, only has gboolean atk_selection_remove_selection (AtkSelection *selection, gint i); where the index 'i' is "a gint specifying the index in the selection set. (e.g. the ith selection as opposed to the ith child)." [3] That means, the meaning of the index in 'atk_selection_remove_selection' is the same as in 'atspi_selection_deselect_selected_child', while 'XAccessibleSelection::deselectAccessibleChild' expects an index in the parent container, not in the selection set. Therefore, convert the index from an index in the selection to a child index first before passing it into 'XAccessibleSelection::deselectAccessibleChild'. (For ATK, the mapping from the two AT-SPI to the ATK function is done in libatk-bridge.) Example to reproduce wrong behaviour without this change in place: 1) select cells B1 to E5 in Calc 2) start Accerciser 3) select the Calc table in Accerciser 4) get AT-SPI selection interface for the table by typing the following in the IPython Console in Accerciser: sel = acc.querySelection() 5) check whether child 0 (i.e. cell A1) is selected In : sel.isChildSelected(0) Out: False -> OK 6) check whether child 1 (i.e. cell B1) is selected: In : sel.isChildSelected(1) Out: True -> OK 7a) try to unselect cell B1: In : sel.deselectChild(1) Out: True -> NOK: selection remains unchanged, cell B1 is still selected Alternatively, intead of step 7a: 7b) try to unselect cell C1 (2nd item in the selection): In : sel.deselectSelectedChild(1) Out: True -> NOK: cell B1 gets unselected instead of C1 [1] https://developer-old.gnome.org/libatspi/unstable/libatspi-atspi-selection.html#atspi-selection-deselect-selected-child [2] https://developer-old.gnome.org/libatspi/unstable/libatspi-atspi-selection.html#atspi-selection-deselect-child [3] https://gnome.pages.gitlab.gnome.org/atk/AtkSelection.html#atk-selection-remove-selection Change-Id: I3c63c647e61baaa6288ffd545d8d89d8b94231de Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124329 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/unx/gtk3/a11y/atkselection.cxx b/vcl/unx/gtk3/a11y/atkselection.cxx index 91759e8d0b21..22d515f1b6fa 100644 --- a/vcl/unx/gtk3/a11y/atkselection.cxx +++ b/vcl/unx/gtk3/a11y/atkselection.cxx @@ -141,7 +141,13 @@ selection_remove_selection( AtkSelection *selection, = getSelection( selection ); if( pSelection.is() ) { - pSelection->deselectAccessibleChild( i ); + css::uno::Reference<css::accessibility::XAccessible> xAcc = pSelection->getSelectedAccessibleChild(i); + if (!xAcc.is()) + return false; + + css::uno::Reference<css::accessibility::XAccessibleContext> xAccContext = xAcc->getAccessibleContext(); + const sal_Int32 nChildIndex = xAccContext->getAccessibleIndexInParent(); + pSelection->deselectAccessibleChild(nChildIndex); return true; } }