accessibility/inc/standard/vclxaccessibleedit.hxx             |    3 +
 accessibility/inc/standard/vclxaccessibletextcomponent.hxx    |    5 ++
 accessibility/source/standard/vclxaccessibleedit.cxx          |   16 ++++++++
 accessibility/source/standard/vclxaccessibletextcomponent.cxx |   18 +++++++++-
 4 files changed, 41 insertions(+), 1 deletion(-)

New commits:
commit ab7a94b8403e7fc89398a603a10e9002bd7e2077
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Fri May 10 15:35:23 2024 +0200
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Fri May 10 21:49:49 2024 +0200

    tdf#160971 a11y: Send full text on changed combobox text
    
    When the text of an editable combobox is changed
    (e.g. using the up/down keys), the Orca screen
    reader on Linux announces the newly inserted text.
    
    This has been the case for other GTK or Qt
    applications for a while, and with recent Orca
    commit [1]
    
        commit 3a9e6b8d7b16bf2fc7919868cfd1a16e44422710
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Fri May 10 10:16:58 2024 +0200
    
            soffice: Use default logic for editable combobox value change
    
    , the same logic is used for LibreOffice as well.
    
    For the gtk3 VCL plugin which has a custom combobox
    implementation using native GTK widgets, this generally
    works since
    
        commit 9f078ed7b625e86182d64d5ccfbb410cdd38081c
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Tue May 7 10:04:16 2024 +0200
    
            tdf#160971 gtk3 a11y: Set role for custom editable combobox
    
    However, the qt6 VCL plugin uses the VCL combobox
    implementation, and only the actual difference between
    the text of the previous and current entry was sent
    in the TEXT_CHANGED event, resulting in Orca only
    announcing those letters that were added/changed,
    e.g. just "ans Narrow" when changing the font in the
    Writer formatting toolbar from "Liberation Serif"
    to "Liberation Sans Narrow".
    
    This doesn't really make clear what entry is selected.
    Align the a11y event with what GTK and Qt do
    and set the full old and new entry texts in the event.
    
    To do that, add a new virtual
    `VCLXAccessibleTextComponent:PreferFullTextInTextChangedEvent`
    that defaults to false to keep the previous behavior as default,
    and override it for `VCLXAccessibleEdit` to return true
    in the case that the edit is the subedit of a combobox
    (the parent has a combobox role).
    Use this in `VCLXAccessibleTextComponent::SetText` to
    determine whether to notify just of the changed characters
    or to send the whole old/new text.
    
    With this in place, Orca also announces the whole new
    entry text (e.g. "Liberation Sans Narrow" for the above
    example) when using the qt6 VCL plugin.
    (It currently additionally announces an extra "Selection
    deleted" when switching entries, as the text selection
    also changes, but that aspect is to be handled separate
    from this change here.)
    
    [1] 
https://gitlab.gnome.org/GNOME/orca/-/commit/3a9e6b8d7b16bf2fc7919868cfd1a16e44422710
    
    Change-Id: I240aa0ad5ac9585e007d67a8c69e305cf1f38185
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167479
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/accessibility/inc/standard/vclxaccessibleedit.hxx 
b/accessibility/inc/standard/vclxaccessibleedit.hxx
index b3b6a239b9d7..187a03264718 100644
--- a/accessibility/inc/standard/vclxaccessibleedit.hxx
+++ b/accessibility/inc/standard/vclxaccessibleedit.hxx
@@ -50,6 +50,9 @@ protected:
     virtual OUString            implGetText() override;
     virtual void                implGetSelection( sal_Int32& nStartIndex, 
sal_Int32& nEndIndex ) override;
 
+    // VCLXAccessibleTextComponent
+    virtual bool                PreferFullTextInTextChangedEvent() override;
+
 public:
     VCLXAccessibleEdit( VCLXWindow* pVCLXindow );
 
diff --git a/accessibility/inc/standard/vclxaccessibletextcomponent.hxx 
b/accessibility/inc/standard/vclxaccessibletextcomponent.hxx
index 3585dd778574..9678eb15469b 100644
--- a/accessibility/inc/standard/vclxaccessibletextcomponent.hxx
+++ b/accessibility/inc/standard/vclxaccessibletextcomponent.hxx
@@ -40,6 +40,11 @@ class VCLXAccessibleTextComponent : public 
cppu::ImplInheritanceHelper<
 protected:
     void                                    SetText( const OUString& sText );
 
+    // Whether text segments for old/new value in 
AccessibleEventId::TEXT_CHANGED
+    // event should always include the whole old and new text instead of just
+    // the characters that changed between the two
+    virtual bool                            PreferFullTextInTextChangedEvent() 
{ return false; };
+
     virtual void                            ProcessWindowEvent( const 
VclWindowEvent& rVclWindowEvent ) override;
 
     // OCommonAccessibleText
diff --git a/accessibility/source/standard/vclxaccessibleedit.cxx 
b/accessibility/source/standard/vclxaccessibleedit.cxx
index f29e3224e293..0ab1580f3cca 100644
--- a/accessibility/source/standard/vclxaccessibleedit.cxx
+++ b/accessibility/source/standard/vclxaccessibleedit.cxx
@@ -162,6 +162,22 @@ void VCLXAccessibleEdit::implGetSelection( sal_Int32& 
nStartIndex, sal_Int32& nE
     nEndIndex = aSelection.Max();
 }
 
+// VCLXAccessibleTextComponent
+bool VCLXAccessibleEdit::PreferFullTextInTextChangedEvent()
+{
+    // for a combobox subedit, the Orca screen reader announces the new/added 
text
+    // so always send the whole old and new text and not just
+    // the changed characters, so the whole entry text gets announced
+    Reference<XAccessible> xParent = getAccessibleParent();
+    if (xParent.is())
+    {
+        Reference<XAccessibleContext> xParentContext = 
xParent->getAccessibleContext();
+        if (xParentContext.is() && xParentContext->getAccessibleRole() == 
AccessibleRole::COMBO_BOX)
+            return true;
+    }
+
+    return false;
+}
 
 // XServiceInfo
 
diff --git a/accessibility/source/standard/vclxaccessibletextcomponent.cxx 
b/accessibility/source/standard/vclxaccessibletextcomponent.cxx
index f876f0b9ed38..0bf781f09758 100644
--- a/accessibility/source/standard/vclxaccessibletextcomponent.cxx
+++ b/accessibility/source/standard/vclxaccessibletextcomponent.cxx
@@ -56,7 +56,23 @@ VCLXAccessibleTextComponent::VCLXAccessibleTextComponent( 
VCLXWindow* pVCLXWindo
 void VCLXAccessibleTextComponent::SetText( const OUString& sText )
 {
     Any aOldValue, aNewValue;
-    if ( implInitTextChangedEvent( m_sText, sText, aOldValue, aNewValue ) )
+    bool bChanged = false;
+    if (!PreferFullTextInTextChangedEvent())
+    {
+        bChanged = implInitTextChangedEvent(m_sText, sText, aOldValue, 
aNewValue);
+
+    }
+    else if (sText != m_sText)
+    {
+        // use the full old/new text as old/new value
+        TextSegment aDeletedText(m_sText, 0, m_sText.getLength());
+        aOldValue <<= aDeletedText;
+        TextSegment aInsertedText(sText, 0, sText.getLength());
+        aNewValue <<= aInsertedText;
+        bChanged = true;
+    }
+
+    if (bChanged)
     {
         m_sText = sText;
         NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, 
aNewValue );

Reply via email to