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 782e4502898924eb94c4ff7f6c33d9ef36959f02 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Thu Sep 22 23:50:07 2022 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Fri Sep 23 07:49:33 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> diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx index d552cba2b503..2c1001b44c50 100644 --- a/sw/inc/crsrsh.hxx +++ b/sw/inc/crsrsh.hxx @@ -235,6 +235,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; @@ -468,6 +472,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 0ec692f47e7d..8f3840f22fcc 100644 --- a/sw/source/core/crsr/crsrsh.cxx +++ b/sw/source/core/crsr/crsrsh.cxx @@ -1751,7 +1751,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; @@ -2025,7 +2025,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 @@ -2966,6 +2966,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; @@ -3010,6 +3011,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 d6d828db846e..66145652c6d7 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -6598,6 +6598,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(); @@ -6606,6 +6610,7 @@ OUString SwEditWin::GetSurroundingText() const rSh.GetSelectedText( sReturn, ParaBreakType::ToOnlyCR ); rSh.Pop(SwCursorShell::PopMode::DeleteCurrent); + rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld); rSh.HideCursor(); if (bUnLockView) @@ -6641,11 +6646,16 @@ Selection SwEditWin::GetSurroundingTextSelection() const ::std::optional<SwCallLink> aLink(std::in_place, 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, aLink); + rSh.SetSendAccessibleCursorEvents(bSendAccessibleEventOld); rSh.ShowCursor(); if (bUnLockView) @@ -6668,11 +6678,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())))