sw/source/core/access/acccontext.cxx | 4 +++- sw/source/core/access/accmap.cxx | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-)
New commits: commit d325edf88c8dbcdaf324b8e3585a314c9351cf60 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Aug 31 07:25:14 2022 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Wed Aug 31 08:08:02 2022 +0200 tdf#150676 sw a11y: Remove item from selection list on dispose As reported in tdf#150676, selecting a table (or also just simple text paragraphs) in Writer, then deleting the selection would result in the following warning when using the gtk3 VCL plugin: warn:legacy.osl:100403:100403:sw/source/core/access/acccontext.cxx:442: fire event for disposed frame? This is because the code responsible for sending a11y events for selection updates gets called after the a11y objects of the previous selection have been disposed already and wants to send an event that the object has been unselected: > 1 SwAccessibleContext::FireAccessibleEvent acccontext.cxx 444 0x7f4ffc5be7a2 > 2 SwAccessibleContext::FireStateChangedEvent acccontext.cxx 475 0x7f4ffc5be8c2 > 3 SwAccessibleContext::SetSelectedState acccontext.cxx 1508 0x7f4ffc5c3752 > 4 SwAccessibleMap::InvalidateShapeInParaSelection accmap.cxx 1428 0x7f4ffc5ea0fd > 5 SwAccessibleMap::InvalidateCursorPosition accmap.cxx 2671 0x7f4ffc5f119d > 6 SwViewShellImp::InvalidateAccessibleCursorPosition viewimp.cxx 415 0x7f4ffd515c32 > 7 SwCursorShell::UpdateCursor crsrsh.cxx 2029 0x7f4ffc745e06 > 8 SwCursorShell::EndAction crsrsh.cxx 278 0x7f4ffc73d4a7 > 9 SwActContext::~SwActContext edws.cxx 169 0x7f4ffccd45d4 > 10 SwWrtShell::DelRight delete.cxx 322 0x7f4ffdc5a454 > 11 SwBaseShell::ExecDelete basesh.cxx 229 0x7f4ffd9e304d > 12 SfxStubSwBaseShellExecDelete swslots.hxx 2173 0x7f4ffd9e2784 > 13 SfxDispatcher::Call_Impl dispatch.cxx 254 0x7f5039ab6f72 > 14 SfxDispatcher::Execute_ dispatch.cxx 753 0x7f5039aba37c > 15 SfxBindings::Execute_Impl bindings.cxx 1060 0x7f5039aa62b7 > 16 SfxDispatchController_Impl::dispatch unoctitm.cxx 701 0x7f5039b7a55e > 17 SfxOfficeDispatch::dispatch unoctitm.cxx 263 0x7f5039b7840d > 18 svt::(anonymous namespace)::AsyncAccelExec::impl_ts_asyncCallback acceleratorexecute.cxx 481 0x7f5036a40cfc > 19 svt::(anonymous namespace)::AsyncAccelExec::LinkStubimpl_ts_asyncCallback acceleratorexecute.cxx 473 0x7f5036a40c1d > 20 Link<LinkParamNone *, void>::Call link.hxx 111 0x7f50336ac77f > ... To prevent that, remove the entry from the map of selected frames as well right when the object gets disposed. If necessary, sending the corresponding event that the item has been unselected should probably be done here, but it currently seems to be of little value to me when the object gets deleted anyway, so this commit doesn't add sending an additional event here. While at it, convert the `OSL_ENSURE` to a `SAL_WARN`. Warning in case `FireAccessibleEvent` gets called on an already disposed object generally seems reasonable to me. Change-Id: I879ba4e6399ffdc61e38093c5a9bd2ae620888e7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139039 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/sw/source/core/access/acccontext.cxx b/sw/source/core/access/acccontext.cxx index 40ede783d9db..f9edaa89c893 100644 --- a/sw/source/core/access/acccontext.cxx +++ b/sw/source/core/access/acccontext.cxx @@ -439,9 +439,11 @@ void SwAccessibleContext::InvalidateFocus_() void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent ) { - OSL_ENSURE( GetFrame(), "fire event for disposed frame?" ); if( !GetFrame() ) + { + SAL_WARN("sw.a11y", "SwAccessibleContext::FireAccessibleEvent called for already disposed frame?"); return; + } if( !rEvent.Source.is() ) { diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 6722253a8a6b..7b8808ed7fea 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -2093,6 +2093,13 @@ void SwAccessibleMap::RemoveContext( const SwFrame *pFrame ) mpFrameMap->erase( aIter ); + if (mpSelectedFrameMap) + { + SwAccessibleContextMap_Impl::iterator aSelectedIter = mpSelectedFrameMap->find(pFrame); + if (aSelectedIter != mpSelectedFrameMap->end()) + mpSelectedFrameMap->erase(aSelectedIter); + } + // Remove reference to old caret object. Though mxCursorContext // is a weak reference and cleared automatically, clearing it // directly makes sure to not keep a non-functional object.