vcl/unx/gtk4/gtkaccessibletext.cxx | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
New commits: commit 59717161953e891d4b97ba54a81dd8c173c091f0 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Fri Sep 19 09:48:03 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri Sep 19 11:57:56 2025 +0200 gtk4 a11y: Implement new GTK API to set text caret/selection Implement the new GtkAccessibleTextInterface methods to set the text caret or text selection which was added in upstream commit [1] commit b747f87516e6feee8803452e002840dc204e6102 Author: Matthias Clasen <mcla...@redhat.com> Date: Thu Sep 4 21:27:16 2025 +0200 accessibletext: Add setters Add set_caret_position and set_selection, so we can implement these parts of the atspi text interface. Fixes #7739 Part-of: <https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8914> With gtk git main and an additional related pending GTK 4 merge request to fix a crash [2], this makes setting selection and cursor positing using the AT-SPI work as expected. Sample scenario: 1) start Writer 2) type "test123" 3) start Accerciser 4) select the paragraph's accessible object in Accerciser's treeview of the LO a11y tree 5) Use the API via Accerciser's IPython console: In [17]: t = acc.queryText() In [18]: t.setCaretOffset(4) Out[18]: True In [19]: t.setSelection(0, 1, 3) Out[19]: True In [20]: t.getSelection(0) Out[20]: (1, 3) [1] https://gitlab.gnome.org/GNOME/gtk/-/commit/b747f87516e6feee8803452e002840dc204e6102 [2] https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/8950 Change-Id: I31ad6d628c34b5ba3a5b46696448855a86caff72 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/191179 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/unx/gtk4/gtkaccessibletext.cxx b/vcl/unx/gtk4/gtkaccessibletext.cxx index b00d0994dfa9..84632b658907 100644 --- a/vcl/unx/gtk4/gtkaccessibletext.cxx +++ b/vcl/unx/gtk4/gtkaccessibletext.cxx @@ -270,6 +270,48 @@ static gboolean lo_accessible_text_get_offset(GtkAccessibleText* self, } #endif +#if GTK_CHECK_VERSION(4, 21, 0) +static gboolean lo_accessible_text_set_caret_position(GtkAccessibleText* self, unsigned int offset) +{ + css::uno::Reference<css::accessibility::XAccessibleText> xText = getXText(self); + if (!xText.is()) + return false; + + if (offset > o3tl::make_unsigned(xText->getCharacterCount())) + { + SAL_WARN("vcl.gtk", + "lo_accessible_text_set_caret_position called with invalid offset: " << offset); + return false; + } + + xText->setCaretPosition(offset); + return true; +} + +static gboolean lo_accessible_text_set_selection(GtkAccessibleText* self, gsize i, + GtkAccessibleTextRange* range) +{ + if (i != 0) + return false; + + css::uno::Reference<css::accessibility::XAccessibleText> xText = getXText(self); + if (!xText.is()) + return false; + + const gsize nEndIndex = range->start + range->length; + const sal_Int32 nTextLength = xText->getCharacterCount(); + if (range->start > o3tl::make_unsigned(nTextLength) + || nEndIndex > o3tl::make_unsigned(nTextLength)) + { + SAL_WARN("vcl.qt", "lo_accessible_text_set_selection called with invalid index."); + return false; + } + + xText->setSelection(range->start, nEndIndex); + return true; +} +#endif + void lo_accessible_text_init(gpointer iface_, gpointer) { auto const iface = static_cast<GtkAccessibleTextInterface*>(iface_); @@ -283,6 +325,10 @@ void lo_accessible_text_init(gpointer iface_, gpointer) iface->get_extents = lo_accessible_text_get_extents; iface->get_offset = lo_accessible_text_get_offset; #endif +#if GTK_CHECK_VERSION(4, 21, 0) + iface->set_caret_position = lo_accessible_text_set_caret_position; + iface->set_selection = lo_accessible_text_set_selection; +#endif } #endif