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()) {