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.

Reply via email to