diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-05-05 12:11:34 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-05-05 14:39:58 +0200 |
commit | 2361718a34ee4ef47901846cb35eea4552bca46b (patch) | |
tree | 37e0e2da41cda45476209209e99c8b734131100c /vcl/unx | |
parent | b10417eb1e5a4a6959e7fc1cdd9819e5b09d39a4 (diff) |
tdf#155149 Crash when exiting cell edit mode
regression from
commit 2dc240a82646fc23c673a6fd5a29ade934dd5b67
Author: Noel Grandin <noel.grandin@collabora.co.uk>
Date: Tue May 2 14:47:43 2023 +0200
improve AccessibleEventNotifier::addEvent
and
commit 3b7db802731826b6cc3b55100470b0c61c1f2dfa
Author: Noel Grandin <noel.grandin@collabora.co.uk>
Date: Thu May 4 10:06:14 2023 +0200
tdf#105404 [API CHANGE] add index to accessiblity change event
(*) Send better index hints
(*) Error check the index hints better
(*) Convert asserts to warnings and fall back to old code when
index hint is wrong.
Change-Id: I8e752fc26e729c9c8926beb2c7b196f5418a147e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/151419
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'vcl/unx')
-rw-r--r-- | vcl/unx/gtk3/a11y/atklistener.cxx | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/vcl/unx/gtk3/a11y/atklistener.cxx b/vcl/unx/gtk3/a11y/atklistener.cxx index b0f091142832..57f40af1db06 100644 --- a/vcl/unx/gtk3/a11y/atklistener.cxx +++ b/vcl/unx/gtk3/a11y/atklistener.cxx @@ -171,16 +171,23 @@ void AtkListener::handleChildAdded( if( !pChild ) return; + bool bNeedToFullFullChildList = true; if (nIndexHint != -1) { + bNeedToFullFullChildList = false; sal_Int64 nStateSet = rxParent->getAccessibleStateSet(); if( !(nStateSet & accessibility::AccessibleStateType::DEFUNC) || (nStateSet & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) ) { m_aChildList.insert(m_aChildList.begin() + nIndexHint, rxAccessible); + if (m_aChildList[nIndexHint] != rxParent->getAccessibleChild(nIndexHint)) + { + SAL_WARN("vcl", "wrong index hint, falling back to updating full child list"); + bNeedToFullFullChildList = true; + } } } - else + if (bNeedToFullFullChildList) updateChildList(rxParent); atk_object_wrapper_add_child( mpWrapper, pChild, @@ -197,20 +204,32 @@ void AtkListener::handleChildRemoved( int nChildIndexHint) { sal_Int32 nIndex = nChildIndexHint; + if (nIndex < 0 || nIndex >= static_cast<sal_Int32>(m_aChildList.size())) + { + SAL_WARN("vcl", "index hint out of range, ignoring"); + nIndex = -1; + } + if (nIndex != -1 && rxChild != m_aChildList[nIndex]) + { + SAL_WARN("vcl", "index hint points to wrong child, somebody forgot to send accessibility update event"); + nIndex = -1; + } - // Locate the child in the children list + // if the hint did not work, search const size_t nmax = m_aChildList.size(); - for( size_t n = 0; n < nmax; ++n ) - { - // Comparing via uno::Reference::operator== is expensive - // with lots of objects, so assume we can find it the cheap way - // first, which works most of the time. - if( rxChild.get() == m_aChildList[n].get() ) + if (nIndex == -1) + // Locate the child in the children list + for( size_t n = 0; n < nmax; ++n ) { - nIndex = n; - break; + // Comparing via uno::Reference::operator== is expensive + // with lots of objects, so assume we can find it the cheap way + // first, which works most of the time. + if( rxChild.get() == m_aChildList[n].get() ) + { + nIndex = n; + break; + } } - } // The cheap way failed, find it via the more expensive path if (nIndex == -1) for( size_t n = 0; n < nmax; ++n ) @@ -248,7 +267,6 @@ void AtkListener::handleChildRemoved( if(!( (nStateSet & accessibility::AccessibleStateType::DEFUNC) || (nStateSet & accessibility::AccessibleStateType::MANAGES_DESCENDANTS) )) { - assert( m_aChildList[nIndex] == rxParent->getAccessibleChild(nIndex) ); m_aChildList.erase(m_aChildList.begin() + nIndex); } |