editeng/source/editeng/editview.cxx |    9 +++++++--
 include/vcl/window.hxx              |    7 +++++++
 sw/source/uibase/docvw/edtwin.cxx   |   14 +++++++++-----
 vcl/qt5/QtWidget.cxx                |    2 +-
 4 files changed, 24 insertions(+), 8 deletions(-)

New commits:
commit 86bf2e50fc64b8789154f3993567ceeed012e60c
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Wed Sep 10 10:53:18 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Sep 10 20:45:10 2025 +0200

    tdf#152519 Distinguish cursor/anchor for IM selection
    
    The Selection class is used in either of two ways for
    text selection:
    
    1) Selection::Min() reports the selection anchor
       and Selection::Max() reports the cursor position.
    
    2) Selection::Min() reports the smaller of the two
       indices mentioned in 1), and Selection::Max() returns
       the greater one.
    
    vcl::Window::GetSurroundingTextSelection and its
    overrides are used for input method handling and
    were so far implementing either of the semantics.
    Adjust those that were so far using 2) to 1), which
    will allow distinguishing between the cursor and
    the selection anchor in the input method logic in
    the platform/VCL plugin implementations.
    
    (SalInstanceEntry::get_position is another non-IM related
    example already relying on Edit::GetSelection implementing
    the behavior as described in 1).)
    
    Calling Selection::Normalize can be used to transform
    an object using the 1) semantics into 2).
    Currently, ImplHandleSalSurroundingTextRequest (in
    vcl/source/window/winproc.cxx) - which uses
    vcl::Window::GetSurroundingTextSelection - does this,
    so this commit shouldn't result in any change in
    behavior by itself yet.
    
    This commit prepares for porting
    QtWidget::inputMethodQuery/lcl_retrieveSurrounding
    from using a11y API to using SalEvent::SurroundingTextRequest,
    similar to what
    
        commit ce5e41ab99af350ca8f4b9fef3017d53f3526f83
        Author: Caolán McNamara <caol...@redhat.com>
        Date:   Sun Oct 25 15:14:56 2020 +0000
    
            Related: tdf#137620 use existing SalEvent::SurroundingTextRequest
    
    did for gtk3.
    
    This commit will help to keep distinguishing
    Qt::ImCursorPosition and Qt::ImAnchorPosition in
    QtWidget::inputMethodQuery/lcl_retrieveSurrounding.
    
    Change-Id: I46fdff87e84fbbe62f9b60b50376b6123d59fdac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190744
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index ae94c4c9b3f0..0494d792fd33 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -1735,7 +1735,6 @@ OUString EditView::GetSurroundingText() const
 Selection EditView::GetSurroundingTextSelection() const
 {
     ESelection aSelection( GetSelection() );
-    aSelection.Adjust();
 
     if( HasSelection() )
     {
@@ -1745,7 +1744,13 @@ Selection EditView::GetSurroundingTextSelection() const
 
         // Stop reconversion if the selected text includes a line break.
         if ( aStr.indexOf( 0x0A ) == -1 )
-            return Selection(0, aSelection.end.nIndex - 
aSelection.start.nIndex);
+        {
+            const tools::Long nLength = std::abs(aSelection.end.nIndex - 
aSelection.start.nIndex);
+            if (aSelection.start.nIndex < aSelection.end.nIndex)
+                return Selection(0, nLength);
+            else
+                return Selection(nLength, 0);
+        }
         else
             return Selection( 0, 0 );
     }
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 06b5a5478446..2176d4e7b992 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1442,7 +1442,14 @@ public:
     void SimulateKeyPress( sal_uInt16 nKeyCode ) const;
 
     virtual OUString GetSurroundingText() const;
+
+    /**
+     * Return the non-normalized Selection, i.e. calling Selection::Min() on
+     * the returned Selection returns the selection anchor and Selection::Max()
+     * returns the cursor position.
+     */
     virtual Selection GetSurroundingTextSelection() const;
+
     virtual bool DeleteSurroundingText(const Selection& rSelection);
 
     virtual FactoryFunction GetUITestFactory() const;
diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index 77c714a8dce0..33ac354df7da 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -6943,7 +6943,11 @@ Selection SwEditWin::GetSurroundingTextSelection() const
     {
         OUString sReturn;
         rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR  );
-        return Selection(0, sReturn.getLength());
+        const SwCursor* pCursor = rSh.GetCursor();
+        if (pCursor && *pCursor->GetPoint() < *pCursor->GetMark())
+            return Selection(sReturn.getLength(), 0);
+        else
+            return Selection(0, sReturn.getLength());
     }
 
     if (rSh.GetCursor()->GetPoint()->GetNode().GetTextNode())
commit edab5f7cbeec7932e7faac19595b6d4d059f9760
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Wed Sep 10 09:52:29 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Sep 10 20:45:01 2025 +0200

    sw: Return result early in SwEditWin::GetSurroundingTextSelection
    
    ... instead of first assigning it to local variable.
    `aSel`.
    
    Change-Id: I99734a12f03d8d3315b3a5966cf55a60ca1ae1cf
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190743
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/sw/source/uibase/docvw/edtwin.cxx 
b/sw/source/uibase/docvw/edtwin.cxx
index a1e688ae3f13..77c714a8dce0 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -6939,14 +6939,14 @@ Selection SwEditWin::GetSurroundingTextSelection() const
     if (rSh.HasDrawView() && rSh.GetDrawView()->IsTextEdit())
         return 
rSh.GetDrawView()->GetTextEditOutlinerView()->GetSurroundingTextSelection();
 
-    Selection aSel(0, 0);
     if( rSh.HasSelection() )
     {
         OUString sReturn;
         rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR  );
-        aSel = Selection( 0, sReturn.getLength() );
+        return Selection(0, sReturn.getLength());
     }
-    else if (rSh.GetCursor()->GetPoint()->GetNode().GetTextNode())
+
+    if (rSh.GetCursor()->GetPoint()->GetNode().GetTextNode())
     {
         bool bUnLockView = !rSh.IsViewLocked();
         rSh.LockView(true);
@@ -6974,10 +6974,10 @@ Selection SwEditWin::GetSurroundingTextSelection() const
         if (bUnLockView)
             rSh.LockView(false);
 
-        aSel = Selection(sal_Int32(nPos - nStartPos), sal_Int32(nPos - 
nStartPos));
+        return Selection(sal_Int32(nPos - nStartPos), sal_Int32(nPos - 
nStartPos));
     }
 
-    return aSel;
+    return Selection(0, 0);
 }
 
 bool SwEditWin::DeleteSurroundingText(const Selection& rSelection)
commit 441e80546b54641661d5654f5aa4c3615753733d
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Sep 9 20:45:56 2025 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Sep 10 20:44:55 2025 +0200

    tdf#152519 qt: Update more IM query atttributes
    
    So far, QtWidget::handleKeyEvent was only
    notifying that the cursor rectangle (Qt::ImCursorRectangle)
    has changed.
    But more attributes can change, which were previously
    not reported. In particular the cursor position
    (Qt::ImCursorPosition) is relevant for the tdf#152519
    scenario of fcitx5-unikey. (Many thanks to Xuetian Weng for
    the insights in tdf#152519 comment 9!)
    
    As the QInputMethod::update doc [1] says:
    
    > In particular calling update whenever the cursor position changes is
    > important as that often causes other query attributes like surrounding
    > text and text selection to change as well. The attributes that often
    > change together with cursor position have been grouped in
    > Qt::ImQueryInput value for convenience.
    
    Use this Qt::ImQueryInput, which is one step
    towards making the tdf#152519 scenario work.
    
    However, as mentioned in tdf#152519 comment 9, this
    isn't sufficient, since not all values reported by
    QtWidget::inputMethodQuery are correct.
    This will be addressed separately.
    
    [1] https://doc.qt.io/qt-6/qinputmethod.html#update
    
    Change-Id: Ic707cd6c7e239798d034ec0e2cb11499b60f89e9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190742
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>
    Tested-by: Jenkins

diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx
index 3e3ec91d98d1..4c5de1f0f74a 100644
--- a/vcl/qt5/QtWidget.cxx
+++ b/vcl/qt5/QtWidget.cxx
@@ -343,7 +343,7 @@ bool QtWidget::handleKeyEvent(QKeyEvent* pEvent) const
         return true;
     }
 
-    QGuiApplication::inputMethod()->update(Qt::ImCursorRectangle);
+    QGuiApplication::inputMethod()->update(Qt::ImQueryInput);
 
     if (nCode == 0 && pEvent->text().isEmpty())
     {

Reply via email to