sfx2/source/control/thumbnailviewacc.cxx | 40 +++++++++++++++---------------- sfx2/source/control/thumbnailviewacc.hxx | 4 +-- svtools/source/control/valueacc.cxx | 4 +-- svtools/source/control/valueimp.hxx | 2 - svtools/source/control/valueset.cxx | 20 +++++++++------ 5 files changed, 37 insertions(+), 33 deletions(-)
New commits: commit a67a353b0387858627e1e33d41e3604f89ec4514 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Feb 25 15:40:17 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Wed Feb 26 08:09:58 2025 +0100 thumbnailview a11y: Rename ThumbnailViewAcc::mpParent Same motivation as in commit 8f0b672a1ac712c75227e9497aa812e17724638b Author: Michael Weghorn <m.wegh...@posteo.de> Date: Mon Feb 24 15:04:32 2025 +0100 valueset a11y: Rename ValueSetAcc::mpParent to mpValueSet The object referred to by ThumbnailViewAcc::mpParent is the ThumbnailView for which this is the accessible object, not any parent widget/accessible, so rename to avoid confusion. Change-Id: If188f8bce7e47223ac89c03e5300b89fd38e302c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182183 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/sfx2/source/control/thumbnailviewacc.cxx b/sfx2/source/control/thumbnailviewacc.cxx index 0e4aedceb5f0..af6a9d8495fd 100644 --- a/sfx2/source/control/thumbnailviewacc.cxx +++ b/sfx2/source/control/thumbnailviewacc.cxx @@ -35,8 +35,8 @@ using namespace ::com::sun::star; -ThumbnailViewAcc::ThumbnailViewAcc( ThumbnailView* pParent ) : - mpParent( pParent ) +ThumbnailViewAcc::ThumbnailViewAcc(ThumbnailView* pThumbnailView) + : mpThumbnailView(pThumbnailView) { } @@ -55,7 +55,7 @@ sal_Int64 SAL_CALL ThumbnailViewAcc::getAccessibleChildCount() const SolarMutexGuard aSolarGuard; ThrowIfDisposed(); - return mpParent->ImplGetVisibleItemCount(); + return mpThumbnailView->ImplGetVisibleItemCount(); } uno::Reference< accessibility::XAccessible > SAL_CALL ThumbnailViewAcc::getAccessibleChild( sal_Int64 i ) @@ -79,7 +79,7 @@ uno::Reference< accessibility::XAccessible > SAL_CALL ThumbnailViewAcc::getAcces { ThrowIfDisposed(); const SolarMutexGuard aSolarGuard; - return mpParent->GetDrawingArea()->get_accessible_parent(); + return mpThumbnailView->GetDrawingArea()->get_accessible_parent(); } sal_Int64 SAL_CALL ThumbnailViewAcc::getAccessibleIndexInParent() @@ -138,9 +138,9 @@ OUString SAL_CALL ThumbnailViewAcc::getAccessibleName() const SolarMutexGuard aSolarGuard; OUString aRet; - if (mpParent) + if (mpThumbnailView) { - aRet = mpParent->GetAccessibleName(); + aRet = mpThumbnailView->GetAccessibleName(); } return aRet; @@ -238,16 +238,16 @@ uno::Reference< accessibility::XAccessible > SAL_CALL ThumbnailViewAcc::getAcces { ThrowIfDisposed(); const SolarMutexGuard aSolarGuard; - const sal_uInt16 nItemId = mpParent->GetItemId( Point( aPoint.X, aPoint.Y ) ); + const sal_uInt16 nItemId = mpThumbnailView->GetItemId(Point(aPoint.X, aPoint.Y)); uno::Reference< accessibility::XAccessible > xRet; if ( nItemId ) { - const size_t nItemPos = mpParent->GetItemPos( nItemId ); + const size_t nItemPos = mpThumbnailView->GetItemPos(nItemId); if( THUMBNAILVIEW_ITEM_NONEITEM != nItemPos ) { - ThumbnailViewItem *const pItem = mpParent->mFilteredItemList[nItemPos]; + ThumbnailViewItem* const pItem = mpThumbnailView->mFilteredItemList[nItemPos]; xRet = pItem->GetAccessible( /*bIsTransientChildrenDisabled*/false ); } } @@ -260,7 +260,7 @@ awt::Rectangle SAL_CALL ThumbnailViewAcc::getBounds() ThrowIfDisposed(); const SolarMutexGuard aSolarGuard; const Point aOutPos; - const Size aOutSize( mpParent->GetOutputSizePixel() ); + const Size aOutSize(mpThumbnailView->GetOutputSizePixel()); awt::Rectangle aRet; aRet.X = aOutPos.X(); @@ -323,7 +323,7 @@ void SAL_CALL ThumbnailViewAcc::grabFocus() { ThrowIfDisposed(); const SolarMutexGuard aSolarGuard; - mpParent->GrabFocus(); + mpThumbnailView->GrabFocus(); } sal_Int32 SAL_CALL ThumbnailViewAcc::getForeground( ) @@ -353,7 +353,7 @@ void SAL_CALL ThumbnailViewAcc::selectAccessibleChild( sal_Int64 nChildIndex ) if(pItem == nullptr) throw lang::IndexOutOfBoundsException(); - mpParent->SelectItem( pItem->mnId ); + mpThumbnailView->SelectItem(pItem->mnId); } sal_Bool SAL_CALL ThumbnailViewAcc::isAccessibleChildSelected( sal_Int64 nChildIndex ) @@ -369,7 +369,7 @@ sal_Bool SAL_CALL ThumbnailViewAcc::isAccessibleChildSelected( sal_Int64 nChildI if (pItem == nullptr) throw lang::IndexOutOfBoundsException(); - return mpParent->IsItemSelected( pItem->mnId ); + return mpThumbnailView->IsItemSelected(pItem->mnId); } void SAL_CALL ThumbnailViewAcc::clearAccessibleSelection() @@ -393,7 +393,7 @@ sal_Int64 SAL_CALL ThumbnailViewAcc::getSelectedAccessibleChildCount() { ThumbnailViewItem* pItem = getItem (i); - if( pItem && mpParent->IsItemSelected( pItem->mnId ) ) + if (pItem && mpThumbnailView->IsItemSelected(pItem->mnId)) ++nRet; } @@ -410,7 +410,8 @@ uno::Reference< accessibility::XAccessible > SAL_CALL ThumbnailViewAcc::getSelec { ThumbnailViewItem* pItem = getItem(i); - if( pItem && mpParent->IsItemSelected( pItem->mnId ) && ( nSelectedChildIndex == static_cast< sal_Int32 >( nSel++ ) ) ) + if (pItem && mpThumbnailView->IsItemSelected(pItem->mnId) + && (nSelectedChildIndex == static_cast<sal_Int32>(nSel++))) xRet = pItem->GetAccessible( /*bIsTransientChildrenDisabled*/false ); } @@ -443,7 +444,7 @@ void ThumbnailViewAcc::disposing(std::unique_lock<std::mutex>& rGuard) // Reset the pointer to the parent. It has to be the one who has // disposed us because he is dying. - mpParent = nullptr; + mpThumbnailView = nullptr; if (mxEventListeners.empty()) return; @@ -469,12 +470,12 @@ void ThumbnailViewAcc::disposing(std::unique_lock<std::mutex>& rGuard) sal_uInt16 ThumbnailViewAcc::getItemCount() const { - return mpParent->ImplGetVisibleItemCount(); + return mpThumbnailView->ImplGetVisibleItemCount(); } ThumbnailViewItem* ThumbnailViewAcc::getItem (sal_uInt16 nIndex) const { - return mpParent->ImplGetVisibleItem (nIndex); + return mpThumbnailView->ImplGetVisibleItem(nIndex); } void ThumbnailViewAcc::ThrowIfDisposed() @@ -488,7 +489,7 @@ void ThumbnailViewAcc::ThrowIfDisposed() } else { - DBG_ASSERT (mpParent!=nullptr, "ValueSetAcc not disposed but mpParent == NULL"); + DBG_ASSERT (mpThumbnailView!=nullptr, "ValueSetAcc not disposed but mpThumbnailView == NULL"); } } diff --git a/sfx2/source/control/thumbnailviewacc.hxx b/sfx2/source/control/thumbnailviewacc.hxx index e483e64a7afc..dd7ee8251876 100644 --- a/sfx2/source/control/thumbnailviewacc.hxx +++ b/sfx2/source/control/thumbnailviewacc.hxx @@ -47,7 +47,7 @@ class ThumbnailViewAcc : { public: - ThumbnailViewAcc( ThumbnailView* pParent ); + ThumbnailViewAcc(ThumbnailView* pThumbnailView); virtual ~ThumbnailViewAcc() override; void FireAccessibleEvent( short nEventId, @@ -113,7 +113,7 @@ public: private: ::std::vector< css::uno::Reference< css::accessibility::XAccessibleEventListener > > mxEventListeners; - ThumbnailView* mpParent; + ThumbnailView* mpThumbnailView; /** Tell all listeners that the object is dying. This callback is usually called from the WeakComponentImplHelper class. commit 0b92534cd705862f8610ef68464c8934bb18a419 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Feb 25 15:33:17 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Wed Feb 26 08:09:52 2025 +0100 thumbnailview a11y: Drop misleading comment ThumbnailViewItemAcc::getLocationOnScreen is supposed to return the position of the object itself (not its parent) in screen/global coordinates, so the // get position of the accessible parent in screen coordinates comment is rather misleading. Change-Id: Iaf371b7b7644b2f08831588baa7f306b285fb46e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182182 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/sfx2/source/control/thumbnailviewacc.cxx b/sfx2/source/control/thumbnailviewacc.cxx index bd321118e899..0e4aedceb5f0 100644 --- a/sfx2/source/control/thumbnailviewacc.cxx +++ b/sfx2/source/control/thumbnailviewacc.cxx @@ -794,7 +794,6 @@ awt::Point SAL_CALL ThumbnailViewItemAcc::getLocation() return aRet; } -// get position of the accessible parent in screen coordinates awt::Point SAL_CALL ThumbnailViewItemAcc::getLocationOnScreen() { const SolarMutexGuard aSolarGuard; commit b3c460980c34d2d9f91120823bb525ece7bc2fac Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Tue Feb 25 12:33:21 2025 +0100 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Wed Feb 26 08:09:46 2025 +0100 valueset a11y: Dispose ValueItemAcc objects So far, the ValueItemAcc objects created by ValueSet were never disposed. While this is a preexisting issue, this started triggering crashes with the qt6 VCL plugin after Change-Id: If448008b3a6dc7b22a06b6ed551b08a40b2d5de3 Author: Michael Weghorn <m.wegh...@posteo.de> Date: Tue Feb 25 12:14:24 2025 +0100 valueset a11y: Use OAccessibleComponentHelper for ValueItemAcc as described in its commit message. Fix this by disposing the objects in ValueSet::ImplDeleteItems, and not just sending an AccessibleEventId::CHILD event. Adjust the logic to be independent of whether the item is visible, but instead do this for all items that have an associated ValueItemAcc. Add a new `bCreate` param to ValueSetItem::GetAccessible and pass false here to avoid creating new ones. In the ValueSet dtor, call `ImplDeleteItems` before invalidating the accessible object, as it may still be needed in `ImplDeleteItems` to send the events. This fixes the crash on exit for the scenario described in the above-mentioned commit. Backtrace of such a crash/assert: soffice.bin: /home/michi/development/git/libreoffice/comphelper/source/misc/accessibleeventnotifier.cxx:142: bool (anonymous namespace)::implLookupClient(const AccessibleEventNotifier::TClientId, ClientMap::iterator &): Assertion `rClients.end() != rPos && "AccessibleEventNotifier::implLookupClient: invalid client id " "(did you register your client?)!"' failed. [New Thread 9546.9547] [New Thread 9546.9548] [New Thread 9546.9549] [New Thread 9546.9557] Thread 1 received signal SIGABRT, Aborted. __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 warning: 44 ./nptl/pthread_kill.c: No such file or directory (rr) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ff8c289de2f in __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:78 #2 0x00007ff8c2849d02 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ff8c28324f0 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007ff8c2832418 in __assert_fail_base (fmt=0x7ff8c29b6ca0 "%s%s%s:%u: %s%sAssertion `%s' failed. %n", assertion=assertion@entry=0x7ff8c0f27cc6 "rClients.end() != rPos && \"AccessibleEventNotifier::implLookupClient: invalid client id \" \"(did you register your client?)!\"", file=file@entry=0x7ff8c0f360b9 "/home/michi/development/git/libreoffice/comphelper/source/misc/accessibleeventnotifier.cxx", line=line@entry=142, function=function@entry=0x7ff8c0efd262 "bool (anonymous namespace)::implLookupClient(const AccessibleEventNotifier::TClientId, ClientMap::iterator &)") at ./assert/assert.c:96 #5 0x00007ff8c2842612 in __assert_fail (assertion=0x7ff8c0f27cc6 "rClients.end() != rPos && \"AccessibleEventNotifier::implLookupClient: invalid client id \" \"(did you register your client?)!\"", file=0x7ff8c0f360b9 "/home/michi/development/git/libreoffice/comphelper/source/misc/accessibleeventnotifier.cxx", line=142, function=0x7ff8c0efd262 "bool (anonymous namespace)::implLookupClient(const AccessibleEventNotifier::TClientId, ClientMap::iterator &)") at ./assert/assert.c:105 #6 0x00007ff8c10eb4c8 in (anonymous namespace)::implLookupClient (nClient=24, rPos=...) at /home/michi/development/git/libreoffice/comphelper/source/misc/accessibleeventnotifier.cxx:140 #7 0x00007ff8c10eb938 in comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing (_nClient=24, _rxEventSource=uno::Reference to (ValueItemAcc *) 0x558da6f7a220) at /home/michi/development/git/libreoffice/comphelper/source/misc/accessibleeventnotifier.cxx:185 #8 0x00007ff8c10e751d in comphelper::OCommonAccessibleComponent::disposing (this=0x558da6f7a220) at /home/michi/development/git/libreoffice/comphelper/source/misc/accessiblecomponenthelper.cxx:61 #9 0x00007ff8c0b3cee0 in cppu::WeakComponentImplHelperBase::dispose (this=0x558da6f7a220) at /home/michi/development/git/libreoffice/cppuhelper/source/implbase.cxx:104 #10 0x00007ff8bb84a0c5 in cppu::PartialWeakComponentImplHelper<com::sun::star::accessibility::XAccessibleContext2, com::sun::star::accessibility::XAccessibleEventBroadcaster>::dispose (this=0x558da6f7a220) at include/cppuhelper/compbase.hxx:90 #11 0x00007ff8c0b3cc07 in cppu::WeakComponentImplHelperBase::release (this=0x558da6f7a220) at /home/michi/development/git/libreoffice/cppuhelper/source/implbase.cxx:79 #12 0x00007ff8bb84d6c5 in cppu::PartialWeakComponentImplHelper<com::sun::star::accessibility::XAccessibleContext2, com::sun::star::accessibility::XAccessibleEventBroadcaster>::release (this=0x558da6f7a220) at include/cppuhelper/compbase.hxx:86 #13 0x00007ff8bb8e0b95 in cppu::ImplInheritanceHelper<comphelper::OCommonAccessibleComponent, com::sun::star::accessibility::XAccessibleComponent>::release (this=0x558da6f7a220) at include/cppuhelper/implbase.hxx:171 #14 0x00007ff8bb97d595 in cppu::ImplInheritanceHelper<comphelper::OAccessibleComponentHelper, com::sun::star::accessibility::XAccessible>::release (this=0x558da6f7a220) at include/cppuhelper/implbase.hxx:171 #15 0x00007ff8af309baa in com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible>::~Reference (this=0x558da6f7a428) at include/com/sun/star/uno/Reference.hxx:114 #16 0x00007ff8af321bad in QtAccessibleWidget::~QtAccessibleWidget (this=0x558da6f7a3e0) at vcl/inc/qt6/../qt5/QtAccessibleWidget.hxx:39 #17 0x00007ff8af321c49 in QtAccessibleWidget::~QtAccessibleWidget (this=0x558da6f7a3e0) at vcl/inc/qt6/../qt5/QtAccessibleWidget.hxx:39 #18 0x00007ff8ad8faf48 in QAccessibleCache::deleteInterface (this=0x558d9fbd0ac0, id=2147483692, obj=0x558da6eecdb0) at /home/michi/development/git/qt5/qtbase/src/gui/accessible/qaccessiblecache.cpp:173 #19 0x00007ff8ad8fad78 in QAccessibleCache::~QAccessibleCache (this=0x558d9fbd0ac0) at /home/michi/development/git/qt5/qtbase/src/gui/accessible/qaccessiblecache.cpp:31 #20 0x00007ff8ad8faf8d in QAccessibleCache::~QAccessibleCache (this=0x558d9fbd0ac0) at /home/michi/development/git/qt5/qtbase/src/gui/accessible/qaccessiblecache.cpp:29 #21 0x00007ff8ad8fb027 in cleanupAccessibleCache () at /home/michi/development/git/qt5/qtbase/src/gui/accessible/qaccessiblecache.cpp:24 #22 0x00007ff8ae44a792 in qt_call_post_routines () at /home/michi/development/git/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:343 #23 0x00007ff8ac3ddee4 in QApplication::~QApplication (this=0x558d9e8c76c0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:667 #24 0x00007ff8ac3de29d in QApplication::~QApplication (this=0x558d9e8c76c0) at /home/michi/development/git/qt5/qtbase/src/widgets/kernel/qapplication.cpp:663 #25 0x00007ff8af3d63b8 in std::default_delete<QApplication>::operator() (this=0x558d9e955870, __ptr=0x558d9e8c76c0) at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/unique_ptr.h:93 #26 0x00007ff8af3d7da8 in std::__uniq_ptr_impl<QApplication, std::default_delete<QApplication> >::reset (this=0x558d9e955870, __p=0x0) at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/unique_ptr.h:205 #27 0x00007ff8af3cfcbd in std::unique_ptr<QApplication, std::default_delete<QApplication> >::reset (this=0x558d9e955870, __p=0x0) at /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/bits/unique_ptr.h:504 #28 0x00007ff8af3c7b34 in QtInstance::~QtInstance (this=0x558d9e9556e0) at vcl/qt6/../qt5/QtInstance.cxx:323 #29 0x00007ff8af3c7c29 in QtInstance::~QtInstance (this=0x558d9e9556e0) at vcl/qt6/../qt5/QtInstance.cxx:320 #30 0x00007ff8b9bb1c54 in DestroySalInstance (pInst=0x558d9e9556f0) at /home/michi/development/git/libreoffice/vcl/source/app/salplug.cxx:361 #31 0x00007ff8b9ca1509 in DeInitVCL () at /home/michi/development/git/libreoffice/vcl/source/app/svmain.cxx:629 #32 0x00007ff8b9c9fa4f in ImplSVMain () at /home/michi/development/git/libreoffice/vcl/source/app/svmain.cxx:241 #33 0x00007ff8b9ca15e9 in SVMain () at /home/michi/development/git/libreoffice/vcl/source/app/svmain.cxx:248 #34 0x00007ff8c2b9f4ba in soffice_main () at /home/michi/development/git/libreoffice/desktop/source/app/sofficemain.cxx:122 #35 0x0000558d9330ba6d in sal_main () at /home/michi/development/git/libreoffice/desktop/source/app/main.c:51 #36 0x0000558d9330ba47 in main (argc=2, argv=0x7ffd2669fb48) at /home/michi/development/git/libreoffice/desktop/source/app/main.c:49 Change-Id: Ifa7e18393edcc1889bcb390fa453c611d9345bdc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182174 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx index a6b85777bb6b..98eda5ce9f96 100644 --- a/svtools/source/control/valueacc.cxx +++ b/svtools/source/control/valueacc.cxx @@ -54,9 +54,9 @@ ValueSetItem::~ValueSetItem() } } -const rtl::Reference< ValueItemAcc > & ValueSetItem::GetAccessible() +const rtl::Reference<ValueItemAcc>& ValueSetItem::GetAccessible(bool bCreate) { - if( !mxAcc.is() ) + if (!mxAcc.is() && bCreate) mxAcc = new ValueItemAcc(this); return mxAcc; diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx index f5fc3b5460f1..4b8490d66bff 100644 --- a/svtools/source/control/valueimp.hxx +++ b/svtools/source/control/valueimp.hxx @@ -59,7 +59,7 @@ struct ValueSetItem explicit ValueSetItem( ValueSet& rParent ); ~ValueSetItem(); - const rtl::Reference< ValueItemAcc > & GetAccessible(); + const rtl::Reference<ValueItemAcc>& GetAccessible(bool bCreate = true); }; class ValueSetAcc final diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx index 7ad76cc3fa53..06fa29977900 100644 --- a/svtools/source/control/valueset.cxx +++ b/svtools/source/control/valueset.cxx @@ -125,10 +125,10 @@ Reference<XAccessible> ValueSet::CreateAccessible() ValueSet::~ValueSet() { + ImplDeleteItems(); + if (mxAccessible) mxAccessible->Invalidate(); - - ImplDeleteItems(); } void ValueSet::ImplDeleteItems() @@ -137,14 +137,18 @@ void ValueSet::ImplDeleteItems() for ( size_t i = 0; i < n; ++i ) { - ValueSetItem* pItem = mItemList[i].get(); - if ( pItem->mbVisible && ImplHasAccessibleListeners() ) + if (ValueSetItem* pItem = mItemList[i].get()) { - Any aOldAny; - Any aNewAny; + rtl::Reference<ValueItemAcc> xItemAcc = pItem->GetAccessible(false); + if (xItemAcc.is()) + { + Any aOldAny; + Any aNewAny; + aOldAny <<= Reference<XAccessible>(xItemAcc); + ImplFireAccessibleEvent(AccessibleEventId::CHILD, aOldAny, aNewAny); - aOldAny <<= Reference< XAccessible >(pItem->GetAccessible()); - ImplFireAccessibleEvent(AccessibleEventId::CHILD, aOldAny, aNewAny); + xItemAcc->dispose(); + } } mItemList[i].reset();