diff options
author | Michael Weghorn <m.weghorn@posteo.de> | 2021-10-26 16:51:35 +0200 |
---|---|---|
committer | Michael Weghorn <m.weghorn@posteo.de> | 2021-10-28 20:36:14 +0200 |
commit | eec233bf33ac0d9ac1ba0ecc669a5ecf58626ef2 (patch) | |
tree | cda9d8af97c6d3970a9314376fd45dcaf880182b | |
parent | eee0b76a8c3dab62d1751db2f29f7f075c65b0c5 (diff) |
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.weghorn@posteo.de>
-rw-r--r-- | vcl/unx/gtk3/a11y/atkselection.cxx | 8 |
1 files changed, 7 insertions, 1 deletions
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; } } |