[Libreoffice-commits] core.git: 2 commits - include/tools include/vcl vcl/inc vcl/source

Michael Meeks michael.meeks at collabora.com
Fri May 8 09:31:08 PDT 2015


 include/tools/link.hxx         |    1 +
 include/vcl/svapp.hxx          |    4 +++-
 include/vcl/window.hxx         |    2 +-
 vcl/inc/svdata.hxx             |    1 +
 vcl/source/app/svapp.cxx       |   12 +++++++++++-
 vcl/source/window/event.cxx    |   11 ++++++++++-
 vcl/source/window/floatwin.cxx |    2 +-
 7 files changed, 28 insertions(+), 5 deletions(-)

New commits:
commit 127625e8efc64dfbc3f2c53db84a3c919823b0a5
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Fri May 8 17:35:54 2015 +0100

    vcl: hold reference during user event posting for floatwin.
    
    Change-Id: Ibb0f717ae21cd80386b26e078ee7eb2a873b4092

diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index 1060021..0e2f5cc 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -590,7 +590,7 @@ void FloatingWindow::ImplCallPopupModeEnd()
 
     // call Handler asynchronously.
     if ( mpImplData && !mnPostId )
-        mnPostId = Application::PostUserEvent( LINK( this, FloatingWindow, ImplEndPopupModeHdl ) );
+        mnPostId = Application::PostUserEvent( LINK( this, FloatingWindow, ImplEndPopupModeHdl ), NULL, true );
 }
 
 void FloatingWindow::PopupModeEnd()
commit a738606d48d6678aaabf68a6ba748f79d5c6b9b8
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Thu May 7 22:08:21 2015 +0100

    PostUserEvent - instrument to allow holding a VclPtr reference.
    
    This helps avoid things dying during emission in a robust manner.
    Bit of an unpleasant 3rd optional parameter; better names appreciated.
    
    Change-Id: I27571823f9d96caef1d07602785a02390d3a3591

diff --git a/include/tools/link.hxx b/include/tools/link.hxx
index 55dfbae..4c2c32c 100644
--- a/include/tools/link.hxx
+++ b/include/tools/link.hxx
@@ -153,6 +153,7 @@ public:
     { return function_ == other.function_ && instance_ == other.instance_; };
 
     bool operator !=(Link const & other) const { return !operator ==(other); };
+    void *GetInstance() const { return instance_; }
 
 private:
     Stub * function_;
diff --git a/include/vcl/svapp.hxx b/include/vcl/svapp.hxx
index a576a2c..78f758c 100644
--- a/include/vcl/svapp.hxx
+++ b/include/vcl/svapp.hxx
@@ -865,10 +865,12 @@ public:
 
      @param     rLink           Link to event callback function
      @param     pCaller         Pointer to data sent to the event by the caller. Optional.
+     @param     bReferenceLink  If true - hold a VclPtr<> reference on the Link's instance.
 
      @return the event ID used to post the event.
     */
-    static ImplSVEvent * PostUserEvent( const Link<>& rLink, void* pCaller = NULL );
+    static ImplSVEvent * PostUserEvent( const Link<>& rLink, void* pCaller = NULL,
+                                        bool bReferenceLink = false );
 
     /** Remove user event based on event ID
 
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 3209906..9c2526d 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -728,7 +728,7 @@ public:
     void                                AddChildEventListener( const Link<>& rEventListener );
     void                                RemoveChildEventListener( const Link<>& rEventListener );
 
-    ImplSVEvent *                       PostUserEvent( const Link<>& rLink, void* pCaller = NULL );
+    ImplSVEvent *                       PostUserEvent( const Link<>& rLink, void* pCaller = NULL, bool bReferenceLink = false );
     void                                RemoveUserEvent( ImplSVEvent * nUserEvent );
 
     void                                IncrementLockCount();
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx
index 932ebe5..a54f6cc 100644
--- a/vcl/inc/svdata.hxx
+++ b/vcl/inc/svdata.hxx
@@ -400,6 +400,7 @@ struct ImplSVEvent
 {
     void*               mpData;
     Link<>*             mpLink;
+    VclPtr<vcl::Window> mpInstanceRef;
     VclPtr<vcl::Window> mpWindow;
     ImplDelData         maDelData;
     bool                mbCall;
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 5a397f4..32949fb 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -897,13 +897,23 @@ void Application::RemoveMouseAndKeyEvents( vcl::Window* pWin )
     }
 }
 
-ImplSVEvent * Application::PostUserEvent( const Link<>& rLink, void* pCaller )
+ImplSVEvent * Application::PostUserEvent( const Link<>& rLink, void* pCaller,
+                                          bool bReferenceLink )
 {
     ImplSVEvent* pSVEvent = new ImplSVEvent;
     pSVEvent->mpData    = pCaller;
     pSVEvent->mpLink    = new Link<>( rLink );
     pSVEvent->mpWindow  = NULL;
     pSVEvent->mbCall    = true;
+    if (bReferenceLink)
+    {
+        // Double check that this is indeed a vcl::Window instance.
+        assert(dynamic_cast<vcl::Window *>(
+                        reinterpret_cast<vcl::Window *>(rLink.GetInstance())) ==
+               reinterpret_cast<vcl::Window *>(rLink.GetInstance()));
+        pSVEvent->mpInstanceRef = reinterpret_cast<vcl::Window *>(rLink.GetInstance());
+    }
+
     vcl::Window* pDefWindow = ImplGetDefaultWindow();
     if ( pDefWindow == 0 || !pDefWindow->ImplGetFrame()->PostEvent( pSVEvent ) )
     {
diff --git a/vcl/source/window/event.cxx b/vcl/source/window/event.cxx
index 162f357..4a8d7e2 100644
--- a/vcl/source/window/event.cxx
+++ b/vcl/source/window/event.cxx
@@ -263,13 +263,22 @@ void Window::RemoveChildEventListener( const Link<>& rEventListener )
     mpWindowImpl->maChildEventListeners.removeListener( rEventListener );
 }
 
-ImplSVEvent * Window::PostUserEvent( const Link<>& rLink, void* pCaller )
+ImplSVEvent * Window::PostUserEvent( const Link<>& rLink, void* pCaller, bool bReferenceLink )
 {
     ImplSVEvent* pSVEvent = new ImplSVEvent;
     pSVEvent->mpData    = pCaller;
     pSVEvent->mpLink    = new Link<>( rLink );
     pSVEvent->mpWindow  = this;
     pSVEvent->mbCall    = true;
+    if (bReferenceLink)
+    {
+        // Double check that this is indeed a vcl::Window instance.
+        assert(dynamic_cast<vcl::Window *>(
+                        reinterpret_cast<vcl::Window *>(rLink.GetInstance())) ==
+               reinterpret_cast<vcl::Window *>(rLink.GetInstance()));
+        pSVEvent->mpInstanceRef = reinterpret_cast<vcl::Window *>(rLink.GetInstance());
+    }
+
     ImplAddDel( &(pSVEvent->maDelData) );
     if ( !mpWindowImpl->mpFrame->PostEvent( pSVEvent ) )
     {


More information about the Libreoffice-commits mailing list