diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-05-07 22:08:21 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-05-08 17:37:41 +0100 |
commit | a738606d48d6678aaabf68a6ba748f79d5c6b9b8 (patch) | |
tree | 38f8184d4691c43e3a9e4beb7a1989ec1e7c1b4d | |
parent | 5c430093a301b31174a81ad4437f0361c86cfe3c (diff) |
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
-rw-r--r-- | include/tools/link.hxx | 1 | ||||
-rw-r--r-- | include/vcl/svapp.hxx | 4 | ||||
-rw-r--r-- | include/vcl/window.hxx | 2 | ||||
-rw-r--r-- | vcl/inc/svdata.hxx | 1 | ||||
-rw-r--r-- | vcl/source/app/svapp.cxx | 12 | ||||
-rw-r--r-- | vcl/source/window/event.cxx | 11 |
6 files changed, 27 insertions, 4 deletions
diff --git a/include/tools/link.hxx b/include/tools/link.hxx index 55dfbae51887..4c2c32c4dfc3 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 a576a2c479b8..78f758c6058f 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 3209906ff085..9c2526db8220 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 932ebe516212..a54f6ccab113 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 5a397f430965..32949fb7734f 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 162f3572d8cc..4a8d7e2a9633 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 ) ) { |