diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-11-26 11:53:13 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-11-27 10:28:52 +0100 |
commit | 980c859480be431311ba803c5251694160dcb3d5 (patch) | |
tree | 57766be2cf7a0867e90148a3cb4ee32fc925d0d2 | |
parent | 2fcc04722d72dbadf8d3decd7a5014ec39b93d27 (diff) |
tdf#108642 load accessibility children faster
Reduces the cost of repeatedly iterating over the page objects, by
adding a new XAccessibleContext3 interface to return accesibility
children in one call.
This takes the load time from 5.6s to 3.2s.
Change-Id: Ifcc20fa7e7ab8ad50417073882c8c3a2405d1eaa
Reviewed-on: https://gerrit.libreoffice.org/83850
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | offapi/UnoApi_offapi.mk | 1 | ||||
-rw-r--r-- | offapi/com/sun/star/accessibility/XAccessibleContext3.idl | 45 | ||||
-rw-r--r-- | sw/source/core/access/acccontext.cxx | 42 | ||||
-rw-r--r-- | sw/source/core/access/acccontext.hxx | 5 | ||||
-rw-r--r-- | vcl/unx/gtk3/a11y/gtk3atklistener.cxx | 58 |
5 files changed, 127 insertions, 24 deletions
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk index 81dbf3c3441b..12ab8e2057e9 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -1634,6 +1634,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/accessibility,\ XAccessibleComponent \ XAccessibleContext \ XAccessibleContext2 \ + XAccessibleContext3 \ XAccessibleEditableText \ XAccessibleEventBroadcaster \ XAccessibleEventListener \ diff --git a/offapi/com/sun/star/accessibility/XAccessibleContext3.idl b/offapi/com/sun/star/accessibility/XAccessibleContext3.idl new file mode 100644 index 000000000000..8bc4dee3d1f0 --- /dev/null +++ b/offapi/com/sun/star/accessibility/XAccessibleContext3.idl @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef __com_sun_star_accessibility_XAccessibleContext3_idl__ +#define __com_sun_star_accessibility_XAccessibleContext3_idl__ + +module com { module sun { module star { module accessibility { + + interface XAccessible; + +/** Implement this interface to speed up operations when iterating over large amounts of children. + * + @since LibreOffice 6.4 +*/ +interface XAccessibleContext3 : ::com::sun::star::uno::XInterface +{ + /** Return the children. + + <p>The order in which the children are enumerated is implementation + dependent.</p> + */ + sequence<XAccessible> getAccessibleChildren(); +}; + +}; }; }; }; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/access/acccontext.cxx b/sw/source/core/access/acccontext.cxx index d3bb318584b5..0e8d45f91a24 100644 --- a/sw/source/core/access/acccontext.cxx +++ b/sw/source/core/access/acccontext.cxx @@ -620,6 +620,48 @@ uno::Reference< XAccessible> SAL_CALL return xChild; } +css::uno::Sequence<uno::Reference<XAccessible>> SAL_CALL + SwAccessibleContext::getAccessibleChildren() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + std::list< sw::access::SwAccessibleChild > aChildren; + GetChildren( *GetMap(), aChildren ); + + std::vector<uno::Reference<XAccessible>> aRet; + aRet.reserve(aChildren.size()); + for (const auto & rSwChild : aChildren) + { + uno::Reference< XAccessible > xChild; + if( rSwChild.GetSwFrame() ) + { + ::rtl::Reference < SwAccessibleContext > xChildImpl( + GetMap()->GetContextImpl( rSwChild.GetSwFrame(), !m_isDisposing ) ); + if( xChildImpl.is() ) + { + xChildImpl->SetParent( this ); + xChild = xChildImpl.get(); + } + } + else if ( rSwChild.GetDrawObject() ) + { + ::rtl::Reference < ::accessibility::AccessibleShape > xChildImpl( + GetMap()->GetContextImpl( rSwChild.GetDrawObject(), + this, !m_isDisposing) ); + if( xChildImpl.is() ) + xChild = xChildImpl.get(); + } + else if ( rSwChild.GetWindow() ) + { + xChild = rSwChild.GetWindow()->GetAccessible(); + } + aRet.push_back(xChild); + } + return comphelper::containerToSequence(aRet); +} + uno::Reference< XAccessible> SwAccessibleContext::getAccessibleParentImpl() { SolarMutexGuard aGuard; diff --git a/sw/source/core/access/acccontext.hxx b/sw/source/core/access/acccontext.hxx index 52dfe42827d9..ddbc019b2e6a 100644 --- a/sw/source/core/access/acccontext.hxx +++ b/sw/source/core/access/acccontext.hxx @@ -23,6 +23,7 @@ #include "accframe.hxx" #include <accmap.hxx> #include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleContext3.hpp> #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> #include <cppuhelper/implbase.hxx> @@ -46,6 +47,7 @@ class SwAccessibleContext : public ::cppu::WeakImplHelper< css::accessibility::XAccessible, css::accessibility::XAccessibleContext, + css::accessibility::XAccessibleContext3, css::accessibility::XAccessibleComponent, css::accessibility::XAccessibleEventBroadcaster, css::lang::XServiceInfo @@ -220,6 +222,9 @@ public: virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL getAccessibleChild (sal_Int32 nIndex) override; + virtual css::uno::Sequence<css::uno::Reference< css::accessibility::XAccessible>> SAL_CALL + getAccessibleChildren() override; + // Return a reference to the parent. virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL getAccessibleParent() override; diff --git a/vcl/unx/gtk3/a11y/gtk3atklistener.cxx b/vcl/unx/gtk3/a11y/gtk3atklistener.cxx index 600403773b92..8606b7bde5ab 100644 --- a/vcl/unx/gtk3/a11y/gtk3atklistener.cxx +++ b/vcl/unx/gtk3/a11y/gtk3atklistener.cxx @@ -29,10 +29,12 @@ #include <com/sun/star/accessibility/AccessibleTableModelChange.hpp> #include <com/sun/star/accessibility/AccessibleTableModelChangeType.hpp> #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/accessibility/XAccessibleContext3.hpp> #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> #include "atklistener.hxx" #include "atkwrapper.hxx" +#include <comphelper/sequence.hxx> #include <vcl/svapp.hxx> #include <sal/log.hxx> @@ -129,30 +131,38 @@ void AtkListener::updateChildList( css::uno::Reference<css::accessibility::XAccessibleContext> const & pContext) { - m_aChildList.clear(); - - uno::Reference< accessibility::XAccessibleStateSet > xStateSet = pContext->getAccessibleStateSet(); - if( xStateSet.is() - && !xStateSet->contains(accessibility::AccessibleStateType::DEFUNC) - && !xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS) ) - { - sal_Int32 nChildren = pContext->getAccessibleChildCount(); - m_aChildList.resize(nChildren); - for(sal_Int32 n = 0; n < nChildren; n++) - { - try - { - m_aChildList[n] = pContext->getAccessibleChild(n); - } - catch (lang::IndexOutOfBoundsException const&) - { - sal_Int32 nChildren2 = pContext->getAccessibleChildCount(); - assert(nChildren2 <= n && "consistency?"); - m_aChildList.resize(std::min(nChildren2, n)); - break; - } - } - } + m_aChildList.clear(); + + uno::Reference< accessibility::XAccessibleStateSet > xStateSet = pContext->getAccessibleStateSet(); + if( xStateSet.is() + && !xStateSet->contains(accessibility::AccessibleStateType::DEFUNC) + && !xStateSet->contains(accessibility::AccessibleStateType::MANAGES_DESCENDANTS) ) + { + css::uno::Reference<css::accessibility::XAccessibleContext3> xContext3(pContext, css::uno::UNO_QUERY); + if (xContext3.is()) + { + m_aChildList = comphelper::sequenceToContainer<std::vector<css::uno::Reference< css::accessibility::XAccessible >>>(xContext3->getAccessibleChildren()); + } + else + { + sal_Int32 nChildren = pContext->getAccessibleChildCount(); + m_aChildList.resize(nChildren); + for(sal_Int32 n = 0; n < nChildren; n++) + { + try + { + m_aChildList[n] = pContext->getAccessibleChild(n); + } + catch (lang::IndexOutOfBoundsException const&) + { + sal_Int32 nChildren2 = pContext->getAccessibleChildCount(); + assert(nChildren2 <= n && "consistency?"); + m_aChildList.resize(std::min(nChildren2, n)); + break; + } + } + } + } } /*****************************************************************************/ |