vcl/unx/gtk3/a11y/atktext.cxx |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

New commits:
commit 76db1af13b394c944876adddd8ddd6bc61a7557f
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Thu Aug 14 11:19:14 2025 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Aug 19 13:01:01 2025 +0200

    tdf#167930 gtk3 a11y: Keep caret pos when removing selection
    
    Don't always use an index of 0 for the start and end index
    of the new empty selection, but use the current caret position
    instead.
    
    This prevents the cursor from jumping to the beginning of
    a paragraph when removing a selection via the AT-SPI Text
    interface as decribed in tdf#167930:
    
    Example using Accerciser's IPython console with a sample
    Writer paragraph with text "abcdefghijk", with "efgh"
    initially selected.
    
    Previously (unexpected line marked with arrow):
    
        In [64]: text = acc.queryText()
        In [65]: text.caretOffset
        Out[65]: 8
        In [66]: text.getNSelections()
        Out[66]: 1
        In [67]: selection = text.getSelection(0)
        In [68]: selection[0]
        Out[68]: 4
        In [69]: selection[1]
        Out[69]: 8
        In [70]: text.removeSelection(0)
        Out[70]: True
        In [71]: text.caretOffset
    ->  Out[71]: 0
        In [72]: text.getNSelections()
        Out[72]: 0
    
    With this commit in place, the caret offset remains
    unchanged:
    
        In [74]: text = acc.queryText()
        In [75]: text.caretOffset
        Out[75]: 8
        In [76]: text.getNSelections()
        Out[76]: 1
        In [77]: selection = text.getSelection(0)
        In [78]: selection[0]
        Out[78]: 4
        In [79]: selection[1]
        Out[79]: 8
        In [80]: text.removeSelection(0)
        Out[80]: True
        In [81]: text.caretOffset
    ->  Out[81]: 8
        In [82]: text.getNSelections()
        Out[82]: 0
    
    There is also an XAccessibleTextSelection UNO interface
    that SwAccessibleParagraph implements that looks like
    it should be useful to implement the methods to
    add/remove/count selections, but it didn't work as
    expected in a quick test, so the implementation inside
    Writer would likely need to be fixed first if going
    that route.
    
    Change-Id: Ieca9dff66eef366bf2a3845e5fdb53b3bfa70df9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189579
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    (cherry picked from commit 315c94c91adc6a9e79a78b304e8d2b95e2f45b80)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189609
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/vcl/unx/gtk3/a11y/atktext.cxx b/vcl/unx/gtk3/a11y/atktext.cxx
index b140232055d3..54973d739e0c 100644
--- a/vcl/unx/gtk3/a11y/atktext.cxx
+++ b/vcl/unx/gtk3/a11y/atktext.cxx
@@ -793,10 +793,12 @@ text_wrapper_remove_selection (AtkText *text,
     g_return_val_if_fail( selection_num == 0, FALSE );
 
     try {
-        css::uno::Reference<css::accessibility::XAccessibleText> pText
-            = getText( text );
-        if( pText.is() )
-            return pText->setSelection( 0, 0 ); // ?
+        css::uno::Reference<css::accessibility::XAccessibleText> xText = 
getText(text);
+        if (!xText.is())
+            return false;
+
+        const sal_Int32 nCaretPos = xText->getCaretPosition();
+        return xText->setSelection(nCaretPos, nCaretPos);
     }
     catch(const uno::Exception&) {
         g_warning( "Exception in setSelection()" );

Reply via email to