vcl/inc/accessibility/vclxaccessiblelistitem.hxx    |   38 +-----
 vcl/source/accessibility/vclxaccessiblelistitem.cxx |  122 ++------------------
 2 files changed, 24 insertions(+), 136 deletions(-)

New commits:
commit 95aaa121a5705a029f147a92d5818469c161ce92
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Feb 11 15:32:59 2025 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Feb 12 08:07:25 2025 +0100

    list item a11y: Use comphelper::OAccessibleComponentHelper
    
    Let VCLXAccessibleListItem subclass
    comphelper::OAccessibleComponentHelper which already
    implements the logic for event handling and most of the
    location/bounds handling, instead of duplicating the
    logic here.
    
    The existing VCLXAccessibleListItem::implGetBounds
    basically already implements the logic needed to override
    the purely virtual
    comphelper::OAccessibleComponentHelper::implGetBounds,
    only the required conversion from tools::Rectangle to awt::Rectangle
    is still added in this commit.
    
    Tested as described in more detail in previous commit
    
        Change-Id: I53c686276537713fec604eb22d19be2331ce1f56
        Author: Michael Weghorn <m.wegh...@posteo.de>
        Date:   Tue Feb 11 15:13:41 2025 +0100
    
            list item a11y: Fix parent-relative position
    
    with no change in behavior noticed (now that the issues
    detected previously have been addressed in previous
    commits already in preparation for this commit).
    
    Change-Id: I74e53e3297948977bed1b8608468dc8378859426
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181433
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/inc/accessibility/vclxaccessiblelistitem.hxx 
b/vcl/inc/accessibility/vclxaccessiblelistitem.hxx
index 5345de57ffe9..e3d3b87abc35 100644
--- a/vcl/inc/accessibility/vclxaccessiblelistitem.hxx
+++ b/vcl/inc/accessibility/vclxaccessiblelistitem.hxx
@@ -21,10 +21,7 @@
 
 #include <com/sun/star/accessibility/AccessibleScrollType.hpp>
 #include <com/sun/star/accessibility/XAccessible.hpp>
-#include <com/sun/star/accessibility/XAccessibleComponent.hpp>
-#include <com/sun/star/accessibility/XAccessibleContext.hpp>
 #include <com/sun/star/accessibility/XAccessibleText.hpp>
-#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <comphelper/compbase.hxx>
 #include <comphelper/accessibletexthelper.hxx>
@@ -42,18 +39,13 @@ namespace com::sun::star::awt {
 
 // class VCLXAccessibleListItem ------------------------------------------
 
-typedef ::comphelper::WeakComponentImplHelper< css::accessibility::XAccessible
-                                            , 
css::accessibility::XAccessibleContext
-                                            , 
css::accessibility::XAccessibleComponent
-                                            , 
css::accessibility::XAccessibleEventBroadcaster
-                                            , 
css::accessibility::XAccessibleText
-                                            , css::lang::XServiceInfo > 
VCLXAccessibleListItem_BASE;
-
 /** the class OAccessibleListBoxEntry represents the base class for an 
accessible object of a listbox entry
 */
-class VCLXAccessibleListItem final :
-                                     public 
::comphelper::OCommonAccessibleText,
-                                     public VCLXAccessibleListItem_BASE
+class VCLXAccessibleListItem final
+    : public cppu::ImplInheritanceHelper<
+          comphelper::OAccessibleComponentHelper, 
css::accessibility::XAccessible,
+          css::accessibility::XAccessibleText, css::lang::XServiceInfo>,
+      public comphelper::OCommonAccessibleText
 {
 private:
     OUString                            m_sEntryText;
@@ -61,22 +53,19 @@ private:
     bool                            m_bSelected;
     bool                            m_bVisible;
 
-    /// client id in the AccessibleEventNotifier queue
-    sal_uInt32                          m_nClientId;
-
     rtl::Reference< VCLXAccessibleList >                     m_xParent;
 
     virtual ~VCLXAccessibleListItem() override = default;
-    /** this function is called upon disposing the component
-    */
-    virtual void disposing(std::unique_lock<std::mutex>& rGuard) override;
+
+    virtual void SAL_CALL disposing() override;
 
     // OCommonAccessibleText
     virtual OUString                        implGetText() override;
     virtual css::lang::Locale               implGetLocale() override;
     virtual void                            implGetSelection( sal_Int32& 
nStartIndex, sal_Int32& nEndIndex ) override;
 
-    tools::Rectangle implGetBounds();
+    // OCommonAccessibleComponent
+    virtual css::awt::Rectangle implGetBounds() override;
 
     OUString getTextRangeImpl(sal_Int32 nStartIndex, sal_Int32 nEndIndex);
 
@@ -120,12 +109,7 @@ public:
     virtual css::lang::Locale SAL_CALL getLocale(  ) override;
 
     // XAccessibleComponent
-    virtual sal_Bool SAL_CALL containsPoint( const css::awt::Point& aPoint ) 
override;
     virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL 
getAccessibleAtPoint( const css::awt::Point& aPoint ) override;
-    virtual css::awt::Rectangle SAL_CALL getBounds(  ) override;
-    virtual css::awt::Point SAL_CALL getLocation(  ) override;
-    virtual css::awt::Point SAL_CALL getLocationOnScreen(  ) override;
-    virtual css::awt::Size SAL_CALL getSize(  ) override;
     virtual void SAL_CALL grabFocus(  ) override;
     virtual sal_Int32 SAL_CALL getForeground() override;
     virtual sal_Int32 SAL_CALL getBackground() override;
@@ -149,10 +133,6 @@ public:
     virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( 
sal_Int32 nIndex, sal_Int16 aTextType ) override;
     virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 
nEndIndex ) override;
     virtual sal_Bool SAL_CALL scrollSubstringTo( sal_Int32 nStartIndex, 
sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) 
override;
-
-    // XAccessibleEventBroadcaster
-    virtual void SAL_CALL addAccessibleEventListener( const 
css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener 
) override;
-    virtual void SAL_CALL removeAccessibleEventListener( const 
css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener 
) override;
 };
 
 
diff --git a/vcl/source/accessibility/vclxaccessiblelistitem.cxx 
b/vcl/source/accessibility/vclxaccessiblelistitem.cxx
index cfde41faa73e..54bb44ddd281 100644
--- a/vcl/source/accessibility/vclxaccessiblelistitem.cxx
+++ b/vcl/source/accessibility/vclxaccessiblelistitem.cxx
@@ -59,11 +59,11 @@ using namespace ::com::sun::star;
 
 // Ctor() and Dtor()
 
-VCLXAccessibleListItem::VCLXAccessibleListItem(sal_Int32 _nIndexInParent, 
rtl::Reference< VCLXAccessibleList > _xParent)
+VCLXAccessibleListItem::VCLXAccessibleListItem(sal_Int32 _nIndexInParent,
+                                               
rtl::Reference<VCLXAccessibleList> _xParent)
     : m_nIndexInParent(_nIndexInParent)
     , m_bSelected(false)
     , m_bVisible(false)
-    , m_nClientId(0)
     , m_xParent(std::move(_xParent))
 {
     assert(m_xParent.is());
@@ -104,14 +104,8 @@ void VCLXAccessibleListItem::NotifyAccessibleEvent( 
sal_Int16 _nEventId,
                                                     const css::uno::Any& 
_aOldValue,
                                                     const css::uno::Any& 
_aNewValue )
 {
-    AccessibleEventObject aEvt;
-    aEvt.Source = *this;
-    aEvt.EventId = _nEventId;
-    aEvt.OldValue = _aOldValue;
-    aEvt.NewValue = _aNewValue;
-
-    if (m_nClientId)
-        comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEvt );
+    comphelper::OAccessibleComponentHelper::NotifyAccessibleEvent(_nEventId, 
_aOldValue,
+                                                                  _aNewValue);
 }
 
 // OCommonAccessibleText
@@ -132,7 +126,7 @@ void VCLXAccessibleListItem::implGetSelection( sal_Int32& 
nStartIndex, sal_Int32
     nEndIndex = 0;
 }
 
-tools::Rectangle VCLXAccessibleListItem::implGetBounds()
+awt::Rectangle VCLXAccessibleListItem::implGetBounds()
 {
     tools::Rectangle aRect;
     IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? 
m_xParent->getListBoxHelper() : nullptr;
@@ -144,7 +138,7 @@ tools::Rectangle VCLXAccessibleListItem::implGetBounds()
         aRect -= vcl::unohelper::ConvertToVCLPoint(m_xParent->getLocation());
     }
 
-    return aRect;
+    return vcl::unohelper::ConvertToAWTRect(aRect);
 }
 
 // XTypeProvider
@@ -156,24 +150,12 @@ Sequence< sal_Int8 > 
VCLXAccessibleListItem::getImplementationId()
 
 // XComponent
 
-void VCLXAccessibleListItem::disposing(std::unique_lock<std::mutex>& rGuard)
+void SAL_CALL VCLXAccessibleListItem::disposing()
 {
-    VCLXAccessibleListItem_BASE::disposing(rGuard);
-
     m_sEntryText.clear();
-    m_xParent           = nullptr;
-    comphelper::AccessibleEventNotifier::TClientId nId = m_nClientId;
-    m_nClientId =  0;
-    Reference< XInterface > xEventSource;
-    if ( nId )
-    {
-        xEventSource = *this;
+    m_xParent = nullptr;
 
-        // Send a disposing to all listeners.
-        rGuard.unlock();
-        comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, 
*this );
-        rGuard.lock();
-    }
+    OAccessibleComponentHelper::disposing();
 }
 
 // XServiceInfo
@@ -257,7 +239,7 @@ sal_Int64 SAL_CALL 
VCLXAccessibleListItem::getAccessibleStateSet(  )
 
     sal_Int64 nStateSet = 0;
 
-    if ( !m_bDisposed )
+    if (isAlive())
     {
         nStateSet |= AccessibleStateType::TRANSIENT;
 
@@ -292,55 +274,11 @@ Locale SAL_CALL VCLXAccessibleListItem::getLocale(  )
 
 // XAccessibleComponent
 
-sal_Bool SAL_CALL VCLXAccessibleListItem::containsPoint( const awt::Point& 
_aPoint )
-{
-    SolarMutexGuard aSolarGuard;
-
-    tools::Rectangle aRect = implGetBounds();
-    aRect.SetPos(Point(0, 0));
-    const bool bInside = 
aRect.Contains(vcl::unohelper::ConvertToVCLPoint(_aPoint));
-    return bInside;
-}
-
 Reference< XAccessible > SAL_CALL 
VCLXAccessibleListItem::getAccessibleAtPoint( const awt::Point& )
 {
     return Reference< XAccessible >();
 }
 
-awt::Rectangle SAL_CALL VCLXAccessibleListItem::getBounds(  )
-{
-    SolarMutexGuard aSolarGuard;
-
-    return vcl::unohelper::ConvertToAWTRect(implGetBounds());
-}
-
-awt::Point SAL_CALL VCLXAccessibleListItem::getLocation(  )
-{
-    SolarMutexGuard aSolarGuard;
-
-    const Point aPoint = implGetBounds().TopLeft();
-    return vcl::unohelper::ConvertToAWTPoint(aPoint);
-}
-
-awt::Point SAL_CALL VCLXAccessibleListItem::getLocationOnScreen(  )
-{
-    SolarMutexGuard aSolarGuard;
-
-    Point aPoint = implGetBounds().TopLeft();
-    if (m_xParent.is())
-        aPoint += 
vcl::unohelper::ConvertToVCLPoint(m_xParent->getLocationOnScreen());
-
-    return vcl::unohelper::ConvertToAWTPoint(aPoint);
-}
-
-awt::Size SAL_CALL VCLXAccessibleListItem::getSize(  )
-{
-    SolarMutexGuard aSolarGuard;
-
-    Size aSize = implGetBounds().GetSize();
-    return vcl::unohelper::ConvertToAWTSize(aSize);
-}
-
 void SAL_CALL VCLXAccessibleListItem::grabFocus(  )
 {
     // no focus for each item
@@ -526,40 +464,6 @@ sal_Bool VCLXAccessibleListItem::scrollSubstringTo( 
sal_Int32, sal_Int32, Access
     return false;
 }
 
-// XAccessibleEventBroadcaster
-
-void SAL_CALL VCLXAccessibleListItem::addAccessibleEventListener( const 
Reference< XAccessibleEventListener >& xListener )
-{
-    if (xListener.is())
-    {
-        if (!m_nClientId)
-            m_nClientId = comphelper::AccessibleEventNotifier::registerClient( 
);
-        comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, 
xListener );
-    }
-}
-
-void SAL_CALL VCLXAccessibleListItem::removeAccessibleEventListener( const 
Reference< XAccessibleEventListener >& xListener )
-{
-    if ( !(xListener.is() && m_nClientId) )
-        return;
-
-    sal_Int32 nListenerCount = 
comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, 
xListener );
-    if ( nListenerCount )
-        return;
-
-    // no listeners anymore
-    // -> revoke ourself. This may lead to the notifier thread dying (if we 
were the last client),
-    // and at least to us not firing any events anymore, in case somebody calls
-    // NotifyAccessibleEvent, again
-    if ( m_nClientId )
-    {
-        comphelper::AccessibleEventNotifier::TClientId nId( m_nClientId );
-        m_nClientId = 0;
-        comphelper::AccessibleEventNotifier::revokeClient( nId );
-    }
-}
-
-
 // AF (Oct. 29 2002): Return black as constant foreground color.  This is an
 // initial implementation and has to be substituted by code that determines
 // the color that is actually used.
commit f315c44bbf1cf8002302f1f760befbb0aa031b22
Author:     Michael Weghorn <m.wegh...@posteo.de>
AuthorDate: Tue Feb 11 15:13:41 2025 +0100
Commit:     Michael Weghorn <m.wegh...@posteo.de>
CommitDate: Wed Feb 12 08:07:20 2025 +0100

    list item a11y: Fix parent-relative position
    
    XAccessibleComponent::getLocation etc. are supposed
    to return the objects position relative to its direct
    accessible parent.
    
    However, IComboListBoxHelper::GetBoundingRectangle used by the
    VCLXAccessibleListItem::implGetBounds helper method returns
    the position relative to the ComboBox or ListBox for which the
    a11y implementation is , which is a VCLXAccessibleBox subclass,
    and that is actually the VCLXAccessibleListItem's accessible
    "grandparent" (parent's parent), as the direct parent is a
    VCLXAccessibleList.
    Therefore, the parent-relative position was incorrect.
    
    Fix that by subtracting the parent's relative position
    within the ListBox/ComboBox.
    
    VCLXAccessibleListItem::getLocationOnScreen, which returns
    the absolute screen position, was correct, because it
    added the combobox/listbox position to the "parent-relative"
    position (which was actually the position relative to the
    combobox/listbox).
    Now that VCLXAccessibleListItem::implGetBounds returns the
    position relative to the actual parent, also adjust
    VCLXAccessibleListItem::getLocationOnScreen to add the
    actual parent's location on screen.
    
    The issue about incorrect parent-relative positions
    was noticed with an (upcoming) change that refactors
    VCLXAccessibleListItem to subclass comphelper::OAccessibleComponentHelper
    where the parent-relative position gets used.
    
    Issue could also be reproduced like this:
    
    1) apply only the VCLXAccessibleListItem::getLocationOnScreen
       part of this change
    
    2) run Python script attachment 199141 from tdf#161087 on X11/XWayland
       which highlights the area of the currently focused object:
    
        GDK_BACKEND=x11 python3 ./highlight-focused-object.py
    
    3) start LO with the qt6 VCL plugin on X11/XWayland:
    
        QT_QPA_PLATFORM=xcb SAL_USE_VCLPLUGIN=qt6 ./instdir/program/soffice.bin 
--writer
    
    4) Navigate to the "Styles" combobox in the formatting toolbar
    
    5) Press Alt+Down to expand, then arrow keys to navigate through
       the combobox entries
    
    (Note: Running Orca in addition can help to trigger creation of the
    the required a11y objects and events.)
    
    Without this change in place, the wrong area was highlighted
    when moving between entries. Now, the correct area of the currently
    focused combobox entry is highlighted.
    
    Change-Id: I53c686276537713fec604eb22d19be2331ce1f56
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181432
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <m.wegh...@posteo.de>

diff --git a/vcl/source/accessibility/vclxaccessiblelistitem.cxx 
b/vcl/source/accessibility/vclxaccessiblelistitem.cxx
index 5437f0f58627..cfde41faa73e 100644
--- a/vcl/source/accessibility/vclxaccessiblelistitem.cxx
+++ b/vcl/source/accessibility/vclxaccessiblelistitem.cxx
@@ -137,7 +137,12 @@ tools::Rectangle VCLXAccessibleListItem::implGetBounds()
     tools::Rectangle aRect;
     IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? 
m_xParent->getListBoxHelper() : nullptr;
     if (pListBoxHelper)
+    {
         aRect = 
pListBoxHelper->GetBoundingRectangle(static_cast<sal_uInt16>(m_nIndexInParent));
+        // convert position relative to the combobox/listbox (parent's parent) 
to position relative
+        // to direct parent by subtracting parent's relative position in the 
combobox/listbox
+        aRect -= vcl::unohelper::ConvertToVCLPoint(m_xParent->getLocation());
+    }
 
     return aRect;
 }
@@ -322,9 +327,8 @@ awt::Point SAL_CALL 
VCLXAccessibleListItem::getLocationOnScreen(  )
     SolarMutexGuard aSolarGuard;
 
     Point aPoint = implGetBounds().TopLeft();
-    IComboListBoxHelper* pListBoxHelper = m_xParent.is() ? 
m_xParent->getListBoxHelper() : nullptr;
-    if (pListBoxHelper)
-        aPoint += Point(pListBoxHelper->GetWindowExtentsAbsolute().TopLeft());
+    if (m_xParent.is())
+        aPoint += 
vcl::unohelper::ConvertToVCLPoint(m_xParent->getLocationOnScreen());
 
     return vcl::unohelper::ConvertToAWTPoint(aPoint);
 }

Reply via email to