include/sfx2/viewsh.hxx             |    2 +
 sc/source/ui/view/tabvwshc.cxx      |    3 +
 sd/source/ui/inc/ViewShellBase.hxx  |    2 -
 sd/source/ui/view/ViewShellBase.cxx |    5 ---
 sfx2/source/view/viewsh.cxx         |   58 ++++++++++++++++++++++++++++++++----
 sw/source/uibase/uiview/view.cxx    |    4 ++
 6 files changed, 61 insertions(+), 13 deletions(-)

New commits:
commit 9de08c6f8f2b4150da628fe3e9311f5dc64137b0
Author:     Marco Cecchetti <marco.cecche...@collabora.com>
AuthorDate: Mon Jun 5 21:33:55 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Aug 11 19:13:38 2023 +0200

    lok: a11y: get focused paragraph notified on document load
    
    Usually, when the document is loaded, a CARET_CHANGED accessibility
    event is automatically emitted for the first paragraph. That allows to
    notify the paragraph content to the client, even if no input event
    occurred yet. However, in Cypress tests no accessibility event is
    automatically emitted until some input event occurs. So we use the
    workaround in this patch to notify the content of the focused
    paragraph, without waiting for an input event.
    
    (cherry picked from commit d6f929c03ca08a0c1134937a1ff1a42f75221e93)
    
    Change-Id: I8696c5f9ea069824614e9b541f4959b315dbda5e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155575
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index 4adf62a196c4..c0628a0bd4fb 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -440,6 +440,8 @@ public:
     const LanguageTag& GetLOKLanguageTag() const { return maLOKLanguageTag; }
     /// Enable/Disable LibreOfficeKit AT support for this view.
     void SetLOKAccessibilityState(bool bEnabled);
+    /// Get LibreOfficeKit AT support state for this view.
+    bool GetLOKAccessibilityState() const { return mbLOKAccessibilityEnabled; }
 
     /// Get the LibreOfficeKit timezone of this view. See @SetLOKTimezone.
     std::pair<bool, OUString> GetLOKTimezone() const
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 997e710e18e9..56cfba5ddfdb 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -453,6 +453,9 @@ int ScTabViewShell::getPart() const
 
 void ScTabViewShell::afterCallbackRegistered()
 {
+    // common tasks
+    SfxViewShell::afterCallbackRegistered();
+
     UpdateInputHandler(true, false);
 
     ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : 
SC_MOD()->GetInputHdl();
diff --git a/sd/source/ui/inc/ViewShellBase.hxx 
b/sd/source/ui/inc/ViewShellBase.hxx
index 3f40123405f3..c2b2d16158e0 100644
--- a/sd/source/ui/inc/ViewShellBase.hxx
+++ b/sd/source/ui/inc/ViewShellBase.hxx
@@ -217,8 +217,6 @@ public:
     int getEditMode() const override;
     /// See SfxViewShell::setEditMode().
     void setEditMode(int nMode);
-    /// See SfxViewShell::afterCallbackRegistered().
-    void afterCallbackRegistered() override;
     /// See SfxViewShell::NotifyCursor().
     void NotifyCursor(SfxViewShell* pViewShell) const override;
     /// See SfxViewShell::GetColorConfigColor().
diff --git a/sd/source/ui/view/ViewShellBase.cxx 
b/sd/source/ui/view/ViewShellBase.cxx
index 460e102e7796..6ad6d454be57 100644
--- a/sd/source/ui/view/ViewShellBase.cxx
+++ b/sd/source/ui/view/ViewShellBase.cxx
@@ -1010,11 +1010,6 @@ void ViewShellBase::setEditMode(int nMode)
     }
 }
 
-void ViewShellBase::afterCallbackRegistered()
-{
-    // TODO: Add theme color palette changed callback
-}
-
 void ViewShellBase::NotifyCursor(SfxViewShell* pOtherShell) const
 {
     ViewShell* pThisShell = 
framework::FrameworkHelper::Instance(*const_cast<ViewShellBase*>(this))->GetViewShell(FrameworkHelper::msCenterPaneURL).get();
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index 0d61e2f3f005..f204b03c3721 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -554,8 +554,10 @@ public:
     int getCaretPosition() const;
 
 private:
-    void updateParagraphInfo(const 
uno::Reference<css::accessibility::XAccessibleText>& xAccText,
+    bool updateParagraphInfo(const 
uno::Reference<css::accessibility::XAccessibleText>& xAccText,
                              bool force, std::string msg = "");
+    void updateAndNotifyParagraph(const 
uno::Reference<css::accessibility::XAccessibleText>& xAccText,
+                                  bool force, std::string msg = "");
 };
 
 LOKDocumentFocusListener::LOKDocumentFocusListener(const SfxViewShell* 
pViewShell)
@@ -676,12 +678,13 @@ void LOKDocumentFocusListener::disposing( const 
lang::EventObject& aEvent )
 
 }
 
-void LOKDocumentFocusListener::updateParagraphInfo(const 
uno::Reference<css::accessibility::XAccessibleText>& xAccText,
+bool LOKDocumentFocusListener::updateParagraphInfo(const 
uno::Reference<css::accessibility::XAccessibleText>& xAccText,
                                                    bool force, std::string msg)
 {
     if (!xAccText.is())
-        return;
+        return false;
 
+    bool bNotify = false;
     // If caret is present inside the paragraph (pos != -1), it means that 
paragraph has focus in the current view.
     sal_Int32 nCaretPosition = xAccText->getCaretPosition();
     if (nCaretPosition >= 0)
@@ -695,7 +698,7 @@ void LOKDocumentFocusListener::updateParagraphInfo(const 
uno::Reference<css::acc
         if (m_sFocusedParagraph != sText)
         {
             m_sFocusedParagraph = sText;
-            notifyFocusedParagraphChanged(force);
+            bNotify = true;
         }
     }
     else
@@ -708,9 +711,19 @@ void LOKDocumentFocusListener::updateParagraphInfo(const 
uno::Reference<css::acc
     if (msg.size())
         header += ": " + msg;
     aboutParagraph(header, xAccText, force);
+    return bNotify;
+
+}
 
+void LOKDocumentFocusListener::updateAndNotifyParagraph(
+        const uno::Reference<css::accessibility::XAccessibleText>& xAccText,
+        bool force, std::string msg)
+{
+    if (updateParagraphInfo(xAccText, force, msg))
+        notifyFocusedParagraphChanged(force);
 }
 
+
 void LOKDocumentFocusListener::notifyEvent(const 
accessibility::AccessibleEventObject& aEvent )
 {
     aboutView("LOKDocumentFocusListener::notifyEvent", this, m_pViewShell);
@@ -742,7 +755,7 @@ void LOKDocumentFocusListener::notifyEvent(const 
accessibility::AccessibleEventO
                         }
                     }
                     uno::Reference<css::accessibility::XAccessibleText> 
xAccText(xAccessibleObject, uno::UNO_QUERY);
-                    updateParagraphInfo(xAccText, false, "STATE_CHANGED: 
FOCUSED");
+                    updateAndNotifyParagraph(xAccText, false, "STATE_CHANGED: 
FOCUSED");
                     
aboutTextFormatting("LOKDocumentFocusListener::notifyEvent: STATE_CHANGED: 
FOCUSED", xAccText);
                 }
                 break;
@@ -810,7 +823,7 @@ void LOKDocumentFocusListener::notifyEvent(const 
accessibility::AccessibleEventO
                 // paragraph content updating on the client, even if current 
editing involves composing.
                 // We make a guess that if the paragraph accessibility node is 
not focused,
                 // it means that the text change has been performed in another 
view.
-                updateParagraphInfo(xAccText, !isFocused(aEvent), 
"TEXT_CHANGED");
+                updateAndNotifyParagraph(xAccText, !isFocused(aEvent), 
"TEXT_CHANGED");
 
                 break;
             }
@@ -1013,6 +1026,34 @@ void LOKDocumentFocusListener::attachRecursive(
                     attachRecursive(xChild);
             }
         }
+        else
+        {
+            // Usually, when the document is loaded, a CARET_CHANGED 
accessibility event is automatically emitted
+            // for the first paragraph. That allows to notify the paragraph 
content to the client, even if no input
+            // event occurred yet. However, in Cypress tests no accessibility 
event is automatically emitted until
+            // some input event occurs. So we use the following workaround to 
notify the content of the focused
+            // paragraph, without waiting for an input event.
+            // Here we update the paragraph info related to the focused 
paragraph,
+            // later when afterCallbackRegistered is executed we notify the 
paragraph content.
+            sal_Int64 nChildCount = xContext->getAccessibleChildCount();
+            if (nChildCount > 0)
+            {
+                uno::Reference< accessibility::XAccessible > xChild( 
xContext->getAccessibleChild( 0 ) );
+                if( xChild.is() )
+                {
+                    uno::Reference<css::accessibility::XAccessibleText> 
xAccText(xChild, uno::UNO_QUERY);
+                    if (xAccText.is())
+                    {
+                        sal_Int32 nPos = xAccText->getCaretPosition();
+                        if (nPos >= 0)
+                        {
+                            attachRecursive(xChild);
+                            updateParagraphInfo(xAccText, false, 
"LOKDocumentFocusListener::attachRecursive(3)");
+                        }
+                    }
+                }
+            }
+        }
     }
 }
 
@@ -2479,6 +2520,11 @@ void 
SfxViewShell::libreOfficeKitViewAddPendingInvalidateTiles()
 
 void SfxViewShell::afterCallbackRegistered()
 {
+    if (GetLOKAccessibilityState())
+    {
+        LOKDocumentFocusListener& rDocFocusListener = 
GetLOKDocumentFocusListener();
+        rDocFocusListener.notifyFocusedParagraphChanged();
+    }
 }
 
 void SfxViewShell::flushPendingLOKInvalidateTiles()
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index d1f18b7b08b9..0e998a57fa71 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -1182,6 +1182,10 @@ void SwView::afterCallbackRegistered()
 {
     if (!comphelper::LibreOfficeKit::isActive())
         return;
+
+    // common tasks
+    SfxViewShell::afterCallbackRegistered();
+
     auto* pDocShell = GetDocShell();
     if (pDocShell)
     {

Reply via email to