vcl/inc/qt5/QtWidget.hxx | 3 + vcl/inc/window.h | 3 - vcl/qt5/QtWidget.cxx | 83 +++++++++++------------------------- vcl/source/window/accessibility.cxx | 40 ----------------- vcl/source/window/window.cxx | 43 ++++++++++++++++++ 5 files changed, 71 insertions(+), 101 deletions(-)
New commits: commit 04e3350214a999aa97321302fe163b524cb0edda Author: Michael Weghorn <[email protected]> AuthorDate: Wed Sep 10 12:50:05 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Sep 10 20:45:42 2025 +0200 vcl: Move FindFocusedEditableText to only source file using it ... and rename to lcl_FindFocusedEditableText. Now that Change-Id: I506f3596374e46a3894e10b21f13036b16b28c0e Author: Michael Weghorn <[email protected]> Date: Wed Sep 10 12:36:33 2025 +0200 tdf#152519 qt: Port IM handling from a11y to dedicated API ported the qt VCL plugins away from using that function, there's no more need to have it available anywhere else. Change-Id: I3821b306f1ce2f747e6b4dabeb2d0c6b4941b27a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190750 Tested-by: Jenkins Reviewed-by: Michael Weghorn <[email protected]> diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 1c92cbc58c0e..36ccb9341457 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -437,7 +437,4 @@ bool ImplLOKHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, NotifyEventTyp void ImplHandleResize( vcl::Window* pWindow, tools::Long nNewWidth, tools::Long nNewHeight ); -VCL_DLLPUBLIC css::uno::Reference<css::accessibility::XAccessibleEditableText> -FindFocusedEditableText(css::uno::Reference<css::accessibility::XAccessibleContext> const&); - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/accessibility.cxx b/vcl/source/window/accessibility.cxx index 52ab05b313d0..e65b4940c22f 100644 --- a/vcl/source/window/accessibility.cxx +++ b/vcl/source/window/accessibility.cxx @@ -679,44 +679,4 @@ bool Window::IsAccessibilityEventsSuppressed() } /* namespace vcl */ -uno::Reference<accessibility::XAccessibleEditableText> -FindFocusedEditableText(uno::Reference<accessibility::XAccessibleContext> const& xContext) -{ - if (!xContext.is()) - return uno::Reference<accessibility::XAccessibleEditableText>(); - - sal_Int64 nState = xContext->getAccessibleStateSet(); - if (nState & accessibility::AccessibleStateType::FOCUSED) - { - uno::Reference<accessibility::XAccessibleEditableText> xText(xContext, uno::UNO_QUERY); - if (xText.is()) - return xText; - if (nState & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) - return uno::Reference<accessibility::XAccessibleEditableText>(); - } - - bool bSafeToIterate = true; - sal_Int64 nCount = xContext->getAccessibleChildCount(); - if (nCount < 0 || nCount > SAL_MAX_UINT16 /* slow enough for anyone */) - bSafeToIterate = false; - if (!bSafeToIterate) - return uno::Reference<accessibility::XAccessibleEditableText>(); - - for (sal_Int64 i = 0; i < xContext->getAccessibleChildCount(); ++i) - { - uno::Reference<accessibility::XAccessible> xChild = xContext->getAccessibleChild(i); - if (!xChild.is()) - continue; - uno::Reference<accessibility::XAccessibleContext> xChildContext - = xChild->getAccessibleContext(); - if (!xChildContext.is()) - continue; - uno::Reference<accessibility::XAccessibleEditableText> xText - = FindFocusedEditableText(xChildContext); - if (xText.is()) - return xText; - } - return uno::Reference<accessibility::XAccessibleEditableText>(); -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index e6fc3d032f62..f4a830888684 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -62,6 +62,7 @@ #include <dndeventdispatcher.hxx> #include <com/sun/star/accessibility/AccessibleRelation.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> #include <com/sun/star/accessibility/XAccessible.hpp> #include <com/sun/star/accessibility/XAccessibleEditableText.hpp> #include <com/sun/star/awt/XVclWindowPeer.hpp> @@ -3801,6 +3802,46 @@ namespace { using namespace com::sun::star; + uno::Reference<accessibility::XAccessibleEditableText> + lcl_FindFocusedEditableText(uno::Reference<accessibility::XAccessibleContext> const& xContext) + { + if (!xContext.is()) + return uno::Reference<accessibility::XAccessibleEditableText>(); + + sal_Int64 nState = xContext->getAccessibleStateSet(); + if (nState & accessibility::AccessibleStateType::FOCUSED) + { + uno::Reference<accessibility::XAccessibleEditableText> xText(xContext, uno::UNO_QUERY); + if (xText.is()) + return xText; + if (nState & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) + return uno::Reference<accessibility::XAccessibleEditableText>(); + } + + bool bSafeToIterate = true; + sal_Int64 nCount = xContext->getAccessibleChildCount(); + if (nCount < 0 || nCount > SAL_MAX_UINT16 /* slow enough for anyone */) + bSafeToIterate = false; + if (!bSafeToIterate) + return uno::Reference<accessibility::XAccessibleEditableText>(); + + for (sal_Int64 i = 0; i < xContext->getAccessibleChildCount(); ++i) + { + uno::Reference<accessibility::XAccessible> xChild = xContext->getAccessibleChild(i); + if (!xChild.is()) + continue; + uno::Reference<accessibility::XAccessibleContext> xChildContext + = xChild->getAccessibleContext(); + if (!xChildContext.is()) + continue; + uno::Reference<accessibility::XAccessibleEditableText> xText + = lcl_FindFocusedEditableText(xChildContext); + if (xText.is()) + return xText; + } + return uno::Reference<accessibility::XAccessibleEditableText>(); + } + uno::Reference<accessibility::XAccessibleEditableText> lcl_GetxText(vcl::Window *pFocusWin) { uno::Reference<accessibility::XAccessibleEditableText> xText; @@ -3808,7 +3849,7 @@ namespace { rtl::Reference<comphelper::OAccessible> pAccessible = pFocusWin->GetAccessible(); if (pAccessible.is()) - xText = FindFocusedEditableText(pAccessible); + xText = lcl_FindFocusedEditableText(pAccessible); } catch(const uno::Exception&) { commit d76a7977bc9c808144ce68276ab3509c9dc54865 Author: Michael Weghorn <[email protected]> AuthorDate: Wed Sep 10 12:36:33 2025 +0200 Commit: Michael Weghorn <[email protected]> CommitDate: Wed Sep 10 20:45:35 2025 +0200 tdf#152519 qt: Port IM handling from a11y to dedicated API Port QtWidget::inputMethodQuery/lcl_retrieveSurrounding from using a11y API to using SalEvent::SurroundingTextRequest, similar to what commit ce5e41ab99af350ca8f4b9fef3017d53f3526f83 Author: Caolán McNamara <[email protected]> Date: Sun Oct 25 15:14:56 2020 +0000 Related: tdf#137620 use existing SalEvent::SurroundingTextRequest did for gtk3. This makes use of earlier commits up to Change-Id: I600b834737e4e46a60491b91e64f8f8bc4ad806c Author: Michael Weghorn <[email protected]> Date: Tue Sep 9 20:39:22 2025 +0200 tdf#152519 vcl: Report IM cursor position in order to be able to continue distinguishing between the cursor and selection anchor position, required for Qt::ImCursorPosition and Qt::ImAnchorPosition, respectively. This addresses the remaining aspect mentioned in previous commit Change-Id: Ic707cd6c7e239798d034ec0e2cb11499b60f89e9 Author: Michael Weghorn <[email protected]> Date: Tue Sep 9 20:45:56 2025 +0200 tdf#152519 qt: Update more IM query atttributes > 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. and makes the tdf#152519 scenario work as expected with qt6. Change-Id: I506f3596374e46a3894e10b21f13036b16b28c0e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190748 Reviewed-by: Michael Weghorn <[email protected]> Tested-by: Jenkins diff --git a/vcl/inc/qt5/QtWidget.hxx b/vcl/inc/qt5/QtWidget.hxx index 5e5fa2dcf6a0..f2af232a1a8d 100644 --- a/vcl/inc/qt5/QtWidget.hxx +++ b/vcl/inc/qt5/QtWidget.hxx @@ -23,6 +23,7 @@ #include <QtWidgets/QGestureEvent> #include <QtWidgets/QWidget> #include <rtl/ustring.hxx> +#include <tools/solar.h> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/accessibility/XAccessibleEditableText.hpp> @@ -45,6 +46,8 @@ class QtWidget : public QWidget void commitText(const QString& aText) const; void deleteReplacementText(int nReplacementStart, int nReplacementLength) const; + void retrieveSurrounding(sal_uLong& rPosition, sal_uLong& rAnchor, QString* pText, + QString* pSelection) const; bool handleEvent(QEvent* pEvent); // mouse events are always accepted void handleMouseButtonEvent(const QMouseEvent*) const; diff --git a/vcl/qt5/QtWidget.cxx b/vcl/qt5/QtWidget.cxx index 4c5de1f0f74a..3bf463ef7a06 100644 --- a/vcl/qt5/QtWidget.cxx +++ b/vcl/qt5/QtWidget.cxx @@ -661,52 +661,25 @@ void QtWidget::inputMethodEvent(QInputMethodEvent* pEvent) pEvent->accept(); } -static bool lcl_retrieveSurrounding(sal_Int32& rPosition, sal_Int32& rAnchor, QString* pText, - QString* pSelection) +void QtWidget::retrieveSurrounding(sal_uLong& rPosition, sal_uLong& rAnchor, QString* pText, + QString* pSelection) const { SolarMutexGuard aGuard; - vcl::Window* pFocusWin = Application::GetFocusWindow(); - if (!pFocusWin) - return false; - uno::Reference<accessibility::XAccessibleEditableText> xText; - try - { - xText = FindFocusedEditableText(pFocusWin->GetAccessible()); - } - catch (const uno::Exception&) - { - TOOLS_WARN_EXCEPTION("vcl.qt", "Exception in getting input method surrounding text"); - } + SalSurroundingTextRequestEvent aEvt; + aEvt.mnStart = aEvt.mnEnd = aEvt.mnCursorPos = 0; + m_rFrame.CallCallback(SalEvent::SurroundingTextRequest, &aEvt); - if (xText.is()) - { - rPosition = xText->getCaretPosition(); - if (rPosition != -1) - { - if (pText) - *pText = toQString(xText->getText()); - - sal_Int32 nSelStart = xText->getSelectionStart(); - sal_Int32 nSelEnd = xText->getSelectionEnd(); - if (nSelStart == nSelEnd) - { - rAnchor = rPosition; - } - else - { - if (rPosition == nSelStart) - rAnchor = nSelEnd; - else - rAnchor = nSelStart; - if (pSelection) - *pSelection = toQString(xText->getSelectedText()); - } - return true; - } - } + rPosition = aEvt.mnCursorPos; + if (pText) + *pText = toQString(aEvt.maText); - return false; + if (rPosition == aEvt.mnStart) + rAnchor = aEvt.mnEnd; + else + rAnchor = aEvt.mnStart; + if (pSelection) + *pSelection = toQString(aEvt.maText).mid(aEvt.mnStart, aEvt.mnEnd - aEvt.mnStart); } QVariant QtWidget::inputMethodQuery(Qt::InputMethodQuery property) const @@ -716,17 +689,15 @@ QVariant QtWidget::inputMethodQuery(Qt::InputMethodQuery property) const case Qt::ImSurroundingText: { QString aText; - sal_Int32 nCursorPos, nAnchor; - if (lcl_retrieveSurrounding(nCursorPos, nAnchor, &aText, nullptr)) - return QVariant(aText); - return QVariant(); + sal_uLong nCursorPos, nAnchor; + retrieveSurrounding(nCursorPos, nAnchor, &aText, nullptr); + return QVariant(aText); } case Qt::ImCursorPosition: { - sal_Int32 nCursorPos, nAnchor; - if (lcl_retrieveSurrounding(nCursorPos, nAnchor, nullptr, nullptr)) - return QVariant(static_cast<int>(nCursorPos)); - return QVariant(); + sal_uLong nCursorPos, nAnchor; + retrieveSurrounding(nCursorPos, nAnchor, nullptr, nullptr); + return QVariant(static_cast<int>(nCursorPos)); } case Qt::ImCursorRectangle: { @@ -745,18 +716,16 @@ QVariant QtWidget::inputMethodQuery(Qt::InputMethodQuery property) const } case Qt::ImAnchorPosition: { - sal_Int32 nCursorPos, nAnchor; - if (lcl_retrieveSurrounding(nCursorPos, nAnchor, nullptr, nullptr)) - return QVariant(static_cast<int>(nAnchor)); - return QVariant(); + sal_uLong nCursorPos, nAnchor; + retrieveSurrounding(nCursorPos, nAnchor, nullptr, nullptr); + return QVariant(static_cast<int>(nAnchor)); } case Qt::ImCurrentSelection: { QString aSelection; - sal_Int32 nCursorPos, nAnchor; - if (lcl_retrieveSurrounding(nCursorPos, nAnchor, nullptr, &aSelection)) - return QVariant(aSelection); - return QVariant(); + sal_uLong nCursorPos, nAnchor; + retrieveSurrounding(nCursorPos, nAnchor, nullptr, &aSelection); + return QVariant(aSelection); } default: return QWidget::inputMethodQuery(property);
