include/comphelper/accessiblewrapper.hxx           |    8 --
 include/vcl/window.hxx                             |    2 
 vcl/inc/window.h                                   |    1 
 vcl/source/accessibility/vclxaccessibletoolbox.cxx |   77 ---------------------
 vcl/source/window/accessibility.cxx                |   14 +++
 vcl/source/window/window.cxx                       |    3 
 6 files changed, 26 insertions(+), 79 deletions(-)

New commits:
commit 92999e090c12751a7928d4952b35ea716e1c8da9
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Mon Mar 3 18:02:17 2025 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Sun Mar 16 04:02:50 2025 +0100

    a11y: Make OAccessibleWrapper::createAccessibleContext non-virtual
    
    ... and private.
    
    The only override in a subclass was dropped in
    
        Change-Id: I3b2182ca953056a939670e73687f4568620a4087
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Mon Mar 3 17:42:03 2025 +0100
    
            tdf#163989 vcl a11y: Rework toolbar item window a11y
    
    Change-Id: I3074ed748e460e0608d28b5312e1fec702a2b8b4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182395
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/include/comphelper/accessiblewrapper.hxx 
b/include/comphelper/accessiblewrapper.hxx
index 02e3da19d8a4..0ee9dc1ff259 100644
--- a/include/comphelper/accessiblewrapper.hxx
+++ b/include/comphelper/accessiblewrapper.hxx
@@ -104,15 +104,13 @@ namespace comphelper
         const css::uno::Reference< css::accessibility::XAccessible >&
                     getParent() const { return m_xParentAccessible; }
 
-        // own overridables
-        virtual rtl::Reference<OAccessibleContextWrapper> 
createAccessibleContext(
-                const css::uno::Reference< 
css::accessibility::XAccessibleContext >& _rxInnerContext
-            );
-
     protected:
         virtual ~OAccessibleWrapper( ) override;
 
     private:
+        rtl::Reference<OAccessibleContextWrapper> createAccessibleContext(
+            const css::uno::Reference<css::accessibility::XAccessibleContext>& 
_rxInnerContext);
+
         OAccessibleWrapper( const OAccessibleWrapper& ) = delete;
         OAccessibleWrapper& operator=( const OAccessibleWrapper& ) = delete;
     };
commit 39e0bdb686baf76a4c54d12cfa66aa9f08db8c3f
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Mon Mar 3 17:42:03 2025 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Sun Mar 16 04:02:38 2025 +0100

    tdf#163989 vcl a11y: Rework toolbar item window a11y
    
    If a toolbar item has a window
    (as returned by ToolBox::GetItemWindow), then the
    toolbar item's accessible (a VCLXAccessibleToolBoxItem)
    should be reported as the parent of the accessible
    object for that item window.
    
    Reporting the item window's accessible as a child is
    pretty straightforward and already implemented in
    The VCLXAccessibleToolBoxItem::getAccessibleChild.
    
    Ensuring that the item window's accessible reports
    the VCLXAccessibleToolBoxItem as its parent and
    the proper index is more challenging, because it
    does not match the vcl::Window hierarchy. (There
    is no vcl::Window for toolbar items, but only for
    the toolbar itself.)
    
    So far, in order to make that work, OToolBoxWindowItem
    was the XAccessible implementation for toolbar item windows
    and OToolBoxWindowItemContext was the XAccessibleContext
    implementation that got returned by OToolBoxWindowItem::getAccessibleContext
    (via the base class implementation 
OAccessibleWrapper::getAccessibleContext).
    
    Those were subclassing OAccessibleWrapper and
    OAccessibleContextWrapper in order to report
    the parent (and index in parent) as needed.
    
    One effect of this however is that the gtk3 logic
    to include native GtkWidgets that are contained in a
    vcl::Window in the a11y hierarchy, as implemented in
    
        commit 305c6fee0be4db38023d9ca5f7915e443e0bc1fc
        Author: Caolán McNamara <caol...@redhat.com>
        Date:   Wed Mar 24 11:33:42 2021 +0000
    
            tdf#141197 if we have a sysobj child then include that in the atk 
hierarchy
    
    does not work for that case, because it relies on
    the accessible to be an XWindow in order to extract
    the underlying vcl::Window. With OAccessibleWrapper
    being used, that is not the case.
    As a consequence, native GTK widgets inside the vcl ToolBox
    (i.e. non-native toolbar) like the Paragraph Styles or Font Style
    comboboxes or the combobox in Writer's search toolbar
    cannot be found in Accerciser's treeview of the LO a11y hierarchy.
    (There are panels, but the comboboxes inside the panels are missing.)
    
    While the logic inside the gtk3 a11y bridge could be
    extended to cover that case also (by making use of
    implementation details in OAccessibleWrapper, e.g.
    getting its OAccessibleWrapper::m_xInnerAccessible),
    choose another solution that doesn't depend on making
    use of more implementation details and ports away
    from OAccessible(Context)Wrapper for the
    toolbar item windows completely:
    
    Introduce Window::SetAccessibleParent that allows
    to explicitly set an accessible parent for a vcl::Window.
    If this is done, Window::GetAccessibleParent, used by
    VCLXAccessibleComponent::getAccessibleParent returns
    this accessible instead of using the accessible for
    the vcl::Window returned by vcl::Window::GetAccessibleParentWindow.
    
    This ensures that the item window returns the
    toolbar item as its parent in
    VCLXAccessibleComponent::getAccessibleParent
    and the base class implementation in
    OCommonAccessibleComponent::getAccessibleIndexInParent
    ensures that the correct child index is also returned.
    
    Drop the now unused classes OToolBoxWindowItem and
    OToolBoxWindowItemContext.
    
    With this commit in place, the native GTK widgets
    inside VCL toolbars now show up in Accerciser's
    treeview of the LO a11y tree when using the gtk3
    VCL plugin as expected.
    
    Change-Id: I3b2182ca953056a939670e73687f4568620a4087
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182426
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 38e3f0eaf9a1..791baf025abd 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1132,6 +1132,8 @@ public:
     vcl::Window*                        GetAccessibleChildWindow( sal_uInt16 n 
);
 
     css::uno::Reference<css::accessibility::XAccessible> GetAccessibleParent() 
const;
+    // Explicitly set an accessible parent (usually not needed)
+    void                                SetAccessibleParent(const 
css::uno::Reference<css::accessibility::XAccessible>& rxParent);
 
     void                                SetAccessibleRole( sal_uInt16 nRole );
     sal_uInt16                          GetAccessibleRole() const;
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index ea4cd20d6928..7bbb51913dcb 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -194,6 +194,7 @@ struct ImplAccessibleInfos
                         pAccessibleName;
     std::optional<OUString>
                         pAccessibleDescription;
+    css::uno::Reference<css::accessibility::XAccessible> xAccessibleParent;
     VclPtr<vcl::Window> pLabeledByWindow;
     VclPtr<vcl::Window> pLabelForWindow;
 
diff --git a/vcl/source/accessibility/vclxaccessibletoolbox.cxx 
b/vcl/source/accessibility/vclxaccessibletoolbox.cxx
index 1a150326a015..639d3b6cb61f 100644
--- a/vcl/source/accessibility/vclxaccessibletoolbox.cxx
+++ b/vcl/source/accessibility/vclxaccessibletoolbox.cxx
@@ -29,9 +29,9 @@
 #include <vcl/unohelp.hxx>
 #include <vcl/vclevent.hxx>
 #include <comphelper/accessiblecontexthelper.hxx>
-#include <comphelper/accessiblewrapper.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/servicehelper.hxx>
+#include <comphelper/sequence.hxx>
 #include <comphelper/types.hxx>
 
 using namespace ::comphelper;
@@ -40,75 +40,6 @@ using namespace ::com::sun::star::uno;
 using namespace ::com::sun::star::lang;
 using namespace ::com::sun::star::accessibility;
 
-namespace
-{
-
-    // = OToolBoxWindowItemContext
-
-    /** XAccessibleContext implementation for a toolbox item which is 
represented by a VCL Window
-    */
-    class OToolBoxWindowItemContext final : public OAccessibleContextWrapper
-    {
-        sal_Int32 m_nIndexInParent;
-    public:
-        OToolBoxWindowItemContext(sal_Int32 _nIndexInParent,
-            const css::uno::Reference< css::uno::XComponentContext >& 
_rxContext,
-            const css::uno::Reference< css::accessibility::XAccessibleContext 
>& _rxInnerAccessibleContext,
-            const css::uno::Reference< css::accessibility::XAccessible >& 
_rxOwningAccessible,
-            const css::uno::Reference< css::accessibility::XAccessible >& 
_rxParentAccessible
-            ) : OAccessibleContextWrapper(
-            _rxContext,
-            _rxInnerAccessibleContext,
-            _rxOwningAccessible,
-            _rxParentAccessible     )
-            ,m_nIndexInParent(_nIndexInParent)
-        {
-        }
-        virtual sal_Int64 SAL_CALL getAccessibleIndexInParent(  ) override;
-    };
-
-
-    sal_Int64 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent(  
)
-    {
-        return m_nIndexInParent;
-    }
-
-
-    // = OToolBoxWindowItem
-
-    /** XAccessible implementation for a toolbox item which is represented by 
a VCL Window
-    */
-    class OToolBoxWindowItem : public OAccessibleWrapper
-    {
-    private:
-        sal_Int32 m_nIndexInParent;
-
-    public:
-        OToolBoxWindowItem(sal_Int32 _nIndexInParent,
-            const css::uno::Reference< css::accessibility::XAccessible >& 
_rxInnerAccessible,
-            const css::uno::Reference< css::accessibility::XAccessible >& 
_rxParentAccessible
-            ) : OAccessibleWrapper(
-            comphelper::getProcessComponentContext(),
-            _rxInnerAccessible,
-            _rxParentAccessible)
-            ,m_nIndexInParent(_nIndexInParent)
-        {
-        }
-
-    protected:
-        // OAccessibleWrapper
-        virtual rtl::Reference<OAccessibleContextWrapper> 
createAccessibleContext(
-                const css::uno::Reference< 
css::accessibility::XAccessibleContext >& _rxInnerContext
-            ) override;
-    };
-
-    rtl::Reference<OAccessibleContextWrapper> 
OToolBoxWindowItem::createAccessibleContext(
-            const Reference< XAccessibleContext >& _rxInnerContext )
-    {
-        return new OToolBoxWindowItemContext( m_nIndexInParent, 
getComponentContext(), _rxInnerContext, this, getParent() );
-    }
-}
-
 // VCLXAccessibleToolBox
 
 VCLXAccessibleToolBox::VCLXAccessibleToolBox(ToolBox* pToolBox)
@@ -626,13 +557,11 @@ Reference< XAccessible > SAL_CALL 
VCLXAccessibleToolBox::getAccessibleChild( sal
         xChild = new VCLXAccessibleToolBoxItem( pToolBox, i );
         if ( pItemWindow )
         {
-            rtl::Reference<VCLXAccessibleToolBoxItem> xParent = xChild;
             auto const xInnerAcc(pItemWindow->GetAccessible());
             if (xInnerAcc) // else child is being disposed - avoid crashing
             {
-                rtl::Reference<OToolBoxWindowItem> xChild2(
-                    new OToolBoxWindowItem(0, xInnerAcc, xParent));
-                xChild->SetChild( xChild2 );
+                pItemWindow->SetAccessibleParent(xChild);
+                xChild->SetChild(xInnerAcc);
             }
         }
         if ( nHighlightItemId > ToolBoxItemId(0) && nItemId == 
nHighlightItemId )
diff --git a/vcl/source/window/accessibility.cxx 
b/vcl/source/window/accessibility.cxx
index e145b2a2cda5..47c413a64cbf 100644
--- a/vcl/source/window/accessibility.cxx
+++ b/vcl/source/window/accessibility.cxx
@@ -215,8 +215,22 @@ vcl::Window* Window::GetAccessibleChildWindow( sal_uInt16 
n )
     return pChild;
 }
 
+void Window::SetAccessibleParent(const 
css::uno::Reference<css::accessibility::XAccessible>& rxParent)
+{
+    if (!mpWindowImpl->mpAccessibleInfos)
+        mpWindowImpl->mpAccessibleInfos.reset(new ImplAccessibleInfos);
+
+    mpWindowImpl->mpAccessibleInfos->xAccessibleParent = rxParent;
+}
+
 css::uno::Reference<css::accessibility::XAccessible> 
Window::GetAccessibleParent() const
 {
+    if (!mpWindowImpl)
+        return nullptr;
+
+    if (mpWindowImpl->mpAccessibleInfos && 
mpWindowImpl->mpAccessibleInfos->xAccessibleParent.is())
+        return mpWindowImpl->mpAccessibleInfos->xAccessibleParent;
+
     if (vcl::Window* pAccessibleParentWin = GetAccessibleParentWindow())
         return pAccessibleParentWin->GetAccessible();
 
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 985d0b298660..ba7fa5633331 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -225,6 +225,9 @@ void Window::dispose()
         mpWindowImpl->mxAccessible.clear();
     }
 
+    if (mpWindowImpl->mpAccessibleInfos)
+        mpWindowImpl->mpAccessibleInfos->xAccessibleParent.clear();
+
     ImplSVData* pSVData = ImplGetSVData();
 
     if ( ImplGetSVHelpData().mpHelpWin && 
(ImplGetSVHelpData().mpHelpWin->GetParent() == this) )

Reply via email to