vcl/source/window/event.cxx |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

New commits:
commit 3471299f1976499ab5f85fc6580b9633f4737399
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Thu Oct 13 13:51:43 2022 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Thu Oct 13 20:30:30 2022 +0200

    tdf#151352 crash closing form while TOTD dialog is displayed
    
    regression from
        commit 8d485ec0cd35ee1ae7684f2b6ca96c0f0c6f9dac
        Author: Noel Grandin <noel.gran...@collabora.co.uk>
        Date:   Sat May 29 08:34:28 2021 +0200
        IsDisposed->isDisposed in vcl/../window
    
    Change-Id: I51889f2451f03797f5b89019e6df32a64acda707
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141292
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/vcl/source/window/event.cxx b/vcl/source/window/event.cxx
index 51e133f82fa0..22845912fb36 100644
--- a/vcl/source/window/event.cxx
+++ b/vcl/source/window/event.cxx
@@ -224,7 +224,11 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
 
     Application::ImplCallEventListeners( aEvent );
 
-    if ( xWindow->isDisposed() )
+    // if we have ObjectDying, then the bIsDisposed flag has already been set,
+    // but we still need to let listeners know.
+    const bool bIgnoreDisposed = nEvent == VclEventId::ObjectDying;
+
+    if ( !bIgnoreDisposed && xWindow->isDisposed() )
         return;
 
     // If maEventListeners is empty, the XVCLWindow has not yet been 
initialized.
@@ -240,9 +244,9 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
         mpWindowImpl->mnEventListenersIteratingCount++;
         auto& rWindowImpl = *mpWindowImpl;
         comphelper::ScopeGuard aGuard(
-            [&rWindowImpl, &xWindow]()
+            [&rWindowImpl, &xWindow, &bIgnoreDisposed]()
             {
-                if (!xWindow->isDisposed())
+                if (bIgnoreDisposed || !xWindow->isDisposed())
                 {
                     rWindowImpl.mnEventListenersIteratingCount--;
                     if (rWindowImpl.mnEventListenersIteratingCount == 0)
@@ -252,7 +256,7 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
         );
         for ( const Link<VclWindowEvent&,void>& rLink : aCopy )
         {
-            if (xWindow->isDisposed()) break;
+            if (!bIgnoreDisposed && xWindow->isDisposed()) break;
             // check this hasn't been removed in some re-enterancy scenario 
fdo#47368
             if( rWindowImpl.maEventListenersDeleted.find(rLink) == 
rWindowImpl.maEventListenersDeleted.end() )
                 rLink.Call( aEvent );
@@ -262,7 +266,7 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
     while ( xWindow )
     {
 
-        if ( xWindow->isDisposed() )
+        if ( !bIgnoreDisposed && xWindow->isDisposed() )
             return;
 
         auto& rWindowImpl = *xWindow->mpWindowImpl;
@@ -273,9 +277,9 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
             // we use an iterating counter/flag and a set of deleted Link's to 
avoid O(n^2) behaviour
             rWindowImpl.mnChildEventListenersIteratingCount++;
             comphelper::ScopeGuard aGuard(
-                [&rWindowImpl, &xWindow]()
+                [&rWindowImpl, &xWindow, &bIgnoreDisposed]()
                 {
-                    if (!xWindow->isDisposed())
+                    if (bIgnoreDisposed || !xWindow->isDisposed())
                     {
                         rWindowImpl.mnChildEventListenersIteratingCount--;
                         if (rWindowImpl.mnChildEventListenersIteratingCount == 
0)
@@ -285,7 +289,7 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
             );
             for ( const Link<VclWindowEvent&,void>& rLink : aCopy )
             {
-                if (xWindow->isDisposed())
+                if (!bIgnoreDisposed && xWindow->isDisposed())
                     return;
                 // Check this hasn't been removed in some re-enterancy 
scenario fdo#47368.
                 if( rWindowImpl.maChildEventListenersDeleted.find(rLink) == 
rWindowImpl.maChildEventListenersDeleted.end() )
@@ -293,7 +297,7 @@ void Window::CallEventListeners( VclEventId nEvent, void* 
pData )
             }
         }
 
-        if ( xWindow->isDisposed() )
+        if ( !bIgnoreDisposed && xWindow->isDisposed() )
             return;
 
         xWindow = xWindow->GetParent();

Reply via email to