diff options
author | Marco Cecchetti <marco.cecchetti@collabora.com> | 2023-06-05 21:33:55 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-08-11 19:13:38 +0200 |
commit | 9de08c6f8f2b4150da628fe3e9311f5dc64137b0 (patch) | |
tree | fccd0f3985d23685605f420d804b86fe56a6e74d | |
parent | 69972719542cd686687ddd91f2b5284483513608 (diff) |
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 <vmiklos@collabora.com>
-rw-r--r-- | include/sfx2/viewsh.hxx | 2 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwshc.cxx | 3 | ||||
-rw-r--r-- | sd/source/ui/inc/ViewShellBase.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/view/ViewShellBase.cxx | 5 | ||||
-rw-r--r-- | sfx2/source/view/viewsh.cxx | 58 | ||||
-rw-r--r-- | sw/source/uibase/uiview/view.cxx | 4 |
6 files changed, 61 insertions, 13 deletions
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) { |