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

Reply via email to