[Libreoffice-commits] core.git: slideshow/source

Michael Stahl mstahl at redhat.com
Wed Sep 16 13:16:20 PDT 2015


 slideshow/source/engine/slideview.cxx |   30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

New commits:
commit afce2eee1d163d942385c7b33db4901b3c71135d
Author: Michael Stahl <mstahl at redhat.com>
Date:   Wed Sep 16 21:49:47 2015 +0200

    slideshow: fix mysterious crash with the gtk3 vclplug
    
    For some reason with gtk3 events are handled a bit differently, and in
    particular after the PresenterSlideShowView::Resize() sets the
    mbIsForcedPaintPending = true, with gtk2 we get a
    notifySlideAnimationsEnded event and then a notifyViewChanged event that
    calls PresenterSlideShowView::clear() to reset the flag,
    but with gtk3 the flag isn't reset and then
    PresenterSlideShowView::ForceRepaint() destroys the SlideView,
    while there are still events in the EventQueue with pointers to it.
    
    Since i'm evidently too dumb to tell what of this event handling is
    working correctly and what is buggy, avoid the crash by checking
    that the SlideView is still alive in the event handlers.
    
    Change-Id: Ib88e61536c21e9787cef8a436341bfbd89914f4b

diff --git a/slideshow/source/engine/slideview.cxx b/slideshow/source/engine/slideview.cxx
index 4aa348f..c688442 100644
--- a/slideshow/source/engine/slideview.cxx
+++ b/slideshow/source/engine/slideview.cxx
@@ -1038,6 +1038,30 @@ void SlideView::disposing( lang::EventObject const& evt )
     dispose();
 }
 
+// silly wrapper to check that event handlers don't touch dead SlideView
+struct WeakRefWrapper
+{
+    SlideView & m_rObj;
+    uno::WeakReference<uno::XInterface> const m_wObj;
+    std::function<void (SlideView&)> const m_func;
+
+    WeakRefWrapper(SlideView & rObj, std::function<void (SlideView&)> const& func)
+        : m_rObj(rObj)
+        , m_wObj(static_cast<::cppu::OWeakObject*>(&rObj))
+        , m_func(func)
+    {
+    }
+
+    void operator()()
+    {
+        uno::Reference<uno::XInterface> const xObj(m_wObj);
+        if (xObj.is())
+        {
+            m_func(m_rObj);
+        }
+    }
+};
+
 // XModifyListener
 void SlideView::modified( const lang::EventObject& /*aEvent*/ )
     throw (uno::RuntimeException, std::exception)
@@ -1081,7 +1105,8 @@ void SlideView::modified( const lang::EventObject& /*aEvent*/ )
     // notify view change. Don't call EventMultiplexer directly, this
     // might not be the main thread!
     mrEventQueue.addEvent(
-        makeEvent( [this] () { this->mrEventMultiplexer.notifyViewChanged(this->mxView); },
+        makeEvent( WeakRefWrapper(*this,
+            [] (SlideView & rThis) { rThis.mrEventMultiplexer.notifyViewChanged(rThis.mxView); }),
                    "EventMultiplexer::notifyViewChanged"));
 }
 
@@ -1096,7 +1121,8 @@ void SlideView::windowPaint( const awt::PaintEvent& /*e*/ )
     // notify view clobbering. Don't call EventMultiplexer directly,
     // this might not be the main thread!
     mrEventQueue.addEvent(
-        makeEvent( [this] () { this->mrEventMultiplexer.notifyViewClobbered(this->mxView); },
+        makeEvent( WeakRefWrapper(*this,
+            [] (SlideView & rThis) { rThis.mrEventMultiplexer.notifyViewClobbered(rThis.mxView); }),
                    "EventMultiplexer::notifyViewClobbered") );
 }
 


More information about the Libreoffice-commits mailing list