winaccessibility/inc/AccEventListener.hxx | 2 winaccessibility/source/service/AccEventListener.cxx | 43 +++++----------- winaccessibility/source/service/AccObjectWinManager.cxx | 2 3 files changed, 18 insertions(+), 29 deletions(-)
New commits: commit af8c52479064a72623f2d8eb9f479b741a2c735c Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Thu Jun 5 20:49:50 2025 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sat Jun 7 11:46:45 2025 +0200 tdf#166875: Don't notify broadcaster from its disposing notification An assert failed in debugging, when closing print preview in Writer: ucrtbased.dll!_wassert(const wchar_t * expression, const wchar_t * file_name, unsigned int line_number) Line 443 comphelper.dll!`anonymous namespace'::implLookupClient(const unsigned long nClient, std::_List_iterator<std::_List_val<std::_List_simple_types<std::pair<unsigned long const ,comphelper::OInterfaceContainerHelper4<com::sun::star::accessibility::XAccessibleEventListener>>>>> & rPos) Line 140 comphelper.dll!comphelper::AccessibleEventNotifier::removeEventListener(const unsigned long _nClient, const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessibleEventListener> & _rxListener) Line 229 swlo.dll!SwAccessibleContext::removeAccessibleEventListener(const com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessibleEventListener> & xListener) Line 746 winaccessibility.dll!AccEventListener::RemoveMeFromBroadcaster(bool isNotifyDestroy) Line 262 winaccessibility.dll!AccEventListener::disposing(const com::sun::star::lang::EventObject & __formal) Line 287 comphelper.dll!comphelper::OInterfaceContainerHelper4<com::sun::star::accessibility::XAccessibleEventListener>::disposeAndClear(std::unique_lock<std::mutex> & rGuard, const com::sun::star::lang::EventObject & rEvt) Line 492 comphelper.dll!comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(const unsigned long _nClient, const com::sun::star::uno::Reference<com::sun::star::uno::XInterface> & _rxEventSource) Line 204 swlo.dll!SwAccessibleContext::Dispose(bool bRecursive, bool bCanSkipInvisible) Line 1050 swlo.dll!SwAccessibleMap::~SwAccessibleMap() Line 1571 swlo.dll!SwAccessibleMap::`scalar deleting destructor'(unsigned int) swlo.dll!std::_Destroy_in_place<SwAccessibleMap>(SwAccessibleMap & _Obj) Line 324 swlo.dll!std::_Ref_count_obj2<SwAccessibleMap>::_Destroy() Line 2118 swlo.dll!std::_Ref_count_base::_Decref() Line 1161 swlo.dll!std::_Ptr_base<SwAccessibleMap>::_Decref() Line 1385 swlo.dll!std::shared_ptr<SwAccessibleMap>::~shared_ptr<SwAccessibleMap>() Line 1690 swlo.dll!std::shared_ptr<SwAccessibleMap>::reset() Line 1737 swlo.dll!SwViewShellImp::~SwViewShellImp() Line 108 swlo.dll!SwViewShellImp::`scalar deleting destructor'(unsigned int) swlo.dll!std::default_delete<SwViewShellImp>::operator()(SwViewShellImp * _Ptr) Line 3309 swlo.dll!std::unique_ptr<SwViewShellImp,std::default_delete<SwViewShellImp>>::reset(SwViewShellImp * _Ptr) Line 3471 swlo.dll!SwViewShell::~SwViewShell() Line 324 swlo.dll!SwViewShell::`scalar deleting destructor'(unsigned int) swlo.dll!SwPagePreview::~SwPagePreview() Line 1235 swlo.dll!SwPagePreview::`vector deleting destructor'(unsigned int) sfxlo.dll!SfxViewFrame::SwitchToViewShell_Impl(unsigned short nViewIdOrNo, bool bIsIndex) Line 2690 SwAccessibleContext::Dispose called revokeClientNotifyDisposing, which removed the SwAccessibleContext's id from its map, and then called disposing() for all listenera of the SwAccessibleContext. When one of the listeners, in its disposing(), tried to call broadcaster's removeAccessibleEventListener, this violated the API: XEventListener::disposing documentation directly prohibits calling any methods of the broadcaster. This was obviously a confusion, already present in commit a18bdb3bc05e761704cc345a66a9d642bc4f4a0a (Integrate branch of IAccessible2, 2013-11-19), where the semantics of disposing() was thought as "the listener is disposing", when in fact, it's broadcaster notification about broadcaster's disposal. Change-Id: Ib7f79b2214ffeedec6b4a4c75813e4ffa2d43270 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/186242 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins diff --git a/winaccessibility/inc/AccEventListener.hxx b/winaccessibility/inc/AccEventListener.hxx index 256780612964..f9153263c987 100644 --- a/winaccessibility/inc/AccEventListener.hxx +++ b/winaccessibility/inc/AccEventListener.hxx @@ -72,7 +72,7 @@ public: //get the accessible parent's role virtual short GetParentRole(); - void RemoveMeFromBroadcaster(bool isNotifyDestroy); + void RemoveMeFromBroadcaster(); }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccEventListener.cxx b/winaccessibility/source/service/AccEventListener.cxx index 82b435e62399..aa9d291b6d6a 100644 --- a/winaccessibility/source/service/AccEventListener.cxx +++ b/winaccessibility/source/service/AccEventListener.cxx @@ -244,47 +244,36 @@ short AccEventListener::GetParentRole() /** * remove the listener from accessible object */ -void AccEventListener::RemoveMeFromBroadcaster(bool const isNotifyDestroy) +void AccEventListener::RemoveMeFromBroadcaster() { + if (!m_xAccessible.is()) + return; + try { - if (!m_xAccessible.is()) - { - return; - } - try + css::uno::Reference<XAccessibleEventBroadcaster> const xBroadcaster( + m_xAccessible->getAccessibleContext(), UNO_QUERY); + if (xBroadcaster.is()) { - css::uno::Reference<XAccessibleEventBroadcaster> const xBroadcaster( - m_xAccessible->getAccessibleContext(), UNO_QUERY); - if (xBroadcaster.is()) - { - //remove the lister from accessible object - xBroadcaster->removeAccessibleEventListener(this); - } - } - catch (Exception const&) - { // may throw if it's already disposed - ignore that + //remove the lister from accessible object + xBroadcaster->removeAccessibleEventListener(this); } - if (isNotifyDestroy) - { - m_rObjManager.NotifyDestroy(m_xAccessible.get()); - } - m_xAccessible.clear(); // release cyclic reference } - catch (...) - { - return; + catch (Exception const&) + { // may throw if it's already disposed - ignore that } + + m_xAccessible.clear(); // release cyclic reference } /** - * this method is invoked before listener is disposed + * this method is invoked before broadcaster is disposed */ void AccEventListener::disposing(const css::lang::EventObject& /*Source*/) { SolarMutexGuard g; - - RemoveMeFromBroadcaster(true); + // No method should be invoked anymore on broadcaster! + m_xAccessible.clear(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/winaccessibility/source/service/AccObjectWinManager.cxx b/winaccessibility/source/service/AccObjectWinManager.cxx index f2253eae59e1..364f51e19bbc 100644 --- a/winaccessibility/source/service/AccObjectWinManager.cxx +++ b/winaccessibility/source/service/AccObjectWinManager.cxx @@ -474,7 +474,7 @@ void AccObjectWinManager::DeleteAccObj( XAccessible* pXAcc ) } if (pListener) { - pListener->RemoveMeFromBroadcaster(false); + pListener->RemoveMeFromBroadcaster(); } }