sw/inc/crsrsh.hxx | 7 +++++++ sw/source/core/crsr/crsrsh.cxx | 6 ++++-- sw/source/uibase/docvw/edtwin.cxx | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-)
New commits: commit 57505216b119ede97ea4bfef154e7375bb7f0d91 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu Sep 22 23:50:07 2022 +0200 Commit: Caolán McNamara <caol...@redhat.com> CommitDate: Fri Sep 23 10:17:49 2022 +0200 tdf#149952 sw a11y: Don't send a11y events for internal-only cursor The fact that `SwEditWin::GetSurroundingText` etc. use an internal-only helper cursor is an implementation detail and should not result in a11y events getting sent from LibreOffice to the platform a11y layer. Therefore, introduce a flag to `SwCursorShell` that indicates whether or not sending of accessible cursor events is enabled and set that to false during the use of the helper cursors. As described in Sebastian Keller's very helpful analysis on what was happening on the gnome-shell magnifier side (s. tdf#149952 comment 11), sending those a11y events resulted in the gnome-shell magnifier jumping to the right when typing empty paragraphs: > Regarding the issue of jumping to the right, it looks > like there is a 'object:state-changed:selected' for the > paragraph when pressing enter multiple times. This causes the > magnifier to center the entire paragraph, which has the width > of the entire page according to the extents, so this will be > further to the right compared to caret. Change-Id: I514aa2dad5cfffbe5e8d4b7e9d7d383e70470b18 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137104 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> (cherry picked from commit 782e4502898924eb94c4ff7f6c33d9ef36959f02) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140466 Reviewed-by: Caolán McNamara <caol...@redhat.com> diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index 9f79a515153a..f961d092559a 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -234,6 +234,10 @@ private: bool m_bSetCursorInReadOnly : 1;// true -> Cursor is allowed in ReadOnly-Areas bool m_bOverwriteCursor : 1; // true -> show Overwrite Cursor + // true -> send accessible events when cursor changes + // (set to false when using internal-only helper cursor) + bool m_bSendAccessibleCursorEvents : 1; + bool m_bMacroExecAllowed : 1; SwFrame* m_oldColFrame; @@ -467,6 +471,9 @@ public: bool IsOverwriteCursor() const { return m_bOverwriteCursor; } void SetOverwriteCursor( bool bFlag ) { m_bOverwriteCursor = bFlag; } + bool IsSendAccessibleCursorEvents() const { return m_bSendAccessibleCursorEvents; }; + void SetSendAccessibleCursorEvents(bool bEnable) { m_bSendAccessibleCursorEvents = bEnable; }; + // Return current frame in which the cursor is placed. SwContentFrame *GetCurrFrame( const bool bCalcFrame = true ) const; diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx index b24920da9b2f..a2abb6a6e5e9 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -1753,7 +1753,7 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd ) } m_eMvState = CursorMoveState::NONE; // state for cursor travelling - GetModelPositionForViewPoint #if !ENABLE_WASM_STRIP_ACCESSIBILITY - if (Imp()->IsAccessible()) + if (Imp()->IsAccessible() && m_bSendAccessibleCursorEvents) Imp()->InvalidateAccessibleCursorPosition( pTableFrame ); #endif return; @@ -2027,7 +2027,7 @@ void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd ) m_eMvState = CursorMoveState::NONE; // state for cursor travelling - GetModelPositionForViewPoint #if !ENABLE_WASM_STRIP_ACCESSIBILITY - if (Imp()->IsAccessible()) + if (Imp()->IsAccessible() && m_bSendAccessibleCursorEvents) Imp()->InvalidateAccessibleCursorPosition( pFrame ); #endif @@ -2970,6 +2970,7 @@ SwCursorShell::SwCursorShell( SwCursorShell& rShell, vcl::Window *pInitWin ) m_bAllProtect = m_bVisPortChgd = m_bChgCallFlag = m_bInCMvVisportChgd = m_bGCAttr = m_bIgnoreReadonly = m_bSelTableCells = m_bBasicHideCursor = m_bOverwriteCursor = false; + m_bSendAccessibleCursorEvents = true; m_bCallChgLnk = m_bHasFocus = m_bAutoUpdateCells = true; m_bSVCursorVis = true; m_bSetCursorInReadOnly = true; @@ -3014,6 +3015,7 @@ SwCursorShell::SwCursorShell( SwDoc& rDoc, vcl::Window *pInitWin, m_bAllProtect = m_bVisPortChgd = m_bChgCallFlag = m_bInCMvVisportChgd = m_bGCAttr = m_bIgnoreReadonly = m_bSelTableCells = m_bBasicHideCursor = m_bOverwriteCursor = false; + m_bSendAccessibleCursorEvents = true; m_bCallChgLnk = m_bHasFocus = m_bAutoUpdateCells = true; m_bSVCursorVis = true; m_bSetCursorInReadOnly = true; diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index efa625bca7ee..8cc812e17c6a 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -6582,6 +6582,10 @@ OUString SwEditWin::GetSurroundingText() const rSh.LockView(true); rSh.Push(); + // disable accessible events for internal-only helper cursor + const bool bSendAccessibleEventOld = rSh.IsSendAccessibleCursorEvents(); + rSh.SetSendAccessibleCursorEvents(false); + // get the sentence around the cursor rSh.HideCursor(); rSh.GoStartSentence(); @@ -6590,6 +6594,7 @@ OUString SwEditWin::GetSurroundingText() const rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR ); rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); + rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld); rSh.HideCursor(); if (bUnLockView) @@ -6625,11 +6630,16 @@ Selection SwEditWin::GetSurroundingTextSelection() const ::std::unique_ptr<SwCallLink> pLink(::std::make_unique<SwCallLink>(rSh)); rSh.Push(); + // disable accessible events for internal-only helper cursor + const bool bSendAccessibleEventOld = rSh.IsSendAccessibleCursorEvents(); + rSh.SetSendAccessibleCursorEvents(false); + rSh.HideCursor(); rSh.GoStartSentence(); TextFrameIndex const nStartPos(rSh.GetCursorPointAsViewIndex()); rSh.Pop(SwCursorShell::PopMode::DeleteCurrent, ::std::move(pLink)); + rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld); rSh.ShowCursor(); if (bUnLockView) @@ -6652,11 +6662,17 @@ bool SwEditWin::DeleteSurroundingText(const Selection& rSelection) // rSelection is relative to the start of the sentence, so find that and // adjust the range by it rSh.Push(); + + // disable accessible events for internal-only helper cursor + const bool bSendAccessibleEventOld = rSh.IsSendAccessibleCursorEvents(); + rSh.SetSendAccessibleCursorEvents(false); + rSh.HideCursor(); rSh.GoStartSentence(); TextFrameIndex const nStartPos(rSh.GetCursorPointAsViewIndex()); rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); + rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld); rSh.ShowCursor(); if (rSh.SelectTextView(nStartPos + TextFrameIndex(rSelection.Min()), nStartPos + TextFrameIndex(rSelection.Max())))