summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2018-10-12 15:42:59 +0100
committerCaolán McNamara <caolanm@redhat.com>2018-10-16 09:54:13 +0200
commit8a2f7704cd0e43304e54bf2281232335cc0979a3 (patch)
treea8357d52e613dbff7bd4b6097f75be6871863ce6
parent7dc9fb33db45c269fece6cfec993b124491c68f6 (diff)
drop LazyDeletor
Change-Id: I7d2e00466f321994a46b0529d645e342f229c929 Reviewed-on: https://gerrit.libreoffice.org/61718 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--framework/source/uielement/toolbarmanager.cxx9
-rw-r--r--include/vcl/lazydelete.hxx152
-rw-r--r--include/vcl/window.hxx8
-rw-r--r--svtools/source/uno/popupwindowcontroller.cxx3
-rw-r--r--vcl/README.lifecycle2
-rw-r--r--vcl/source/app/svapp.cxx11
-rw-r--r--vcl/source/helper/lazydelete.cxx35
-rw-r--r--vcl/source/window/menu.cxx8
-rw-r--r--vcl/source/window/menubarwindow.cxx4
-rw-r--r--vcl/source/window/menufloatingwindow.cxx4
-rw-r--r--vcl/source/window/window.cxx14
-rw-r--r--vcl/source/window/window2.cxx4
12 files changed, 28 insertions, 226 deletions
diff --git a/framework/source/uielement/toolbarmanager.cxx b/framework/source/uielement/toolbarmanager.cxx
index 5ca1bb8daa69..1ee4797d889b 100644
--- a/framework/source/uielement/toolbarmanager.cxx
+++ b/framework/source/uielement/toolbarmanager.cxx
@@ -232,13 +232,10 @@ void ToolBarManager::Destroy()
delete static_cast< AddonsParams* >( m_pToolBar->GetItemData( nItemId ));
}
- // Hide toolbar as lazy delete can destroy the toolbar much later.
- m_pToolBar->Hide();
- // #i93173# delete toolbar lazily as we can still be in one of its handlers
// tdf#119390 this will reparent the toolbar, so focus is restored from a
// floating toolbar to the last focused control of the application window.
- m_pToolBar->doLazyDelete();
-
+ m_pToolBar->SetParentToDefaultWindow();
+ // #i93173# note we can still be in one of the toolbar's handlers
m_pToolBar->SetSelectHdl( Link<ToolBox *, void>() );
m_pToolBar->SetActivateHdl( Link<ToolBox *, void>() );
m_pToolBar->SetDeactivateHdl( Link<ToolBox *, void>() );
@@ -248,7 +245,7 @@ void ToolBarManager::Destroy()
m_pToolBar->SetStateChangedHdl( Link<StateChangedType const *, void>() );
m_pToolBar->SetDataChangedHdl( Link<DataChangedEvent const *, void>() );
- m_pToolBar.clear();
+ m_pToolBar.disposeAndClear();
SvtMiscOptions().RemoveListenerLink( LINK( this, ToolBarManager, MiscOptionsChanged ) );
}
diff --git a/include/vcl/lazydelete.hxx b/include/vcl/lazydelete.hxx
index 89c88cbf4cc2..f7d74573de66 100644
--- a/include/vcl/lazydelete.hxx
+++ b/include/vcl/lazydelete.hxx
@@ -35,158 +35,8 @@
namespace vcl
{
- /* Helpers for lazy object deletion
-
- With vcl it is often necessary to delete objects (especially Windows)
- in the right order as well as in a way ensuring that the deleted objects
- are not still on the stack (e.g. deleting a Window in its key handler). To
- make this easier a helper class is given here which takes care of both
- sorting as well as lazy deletion.
-
- The grisly details:
- LazyDelete is a class that LazyDeletor register to. When vcl's event
- loop (that is Application::Yield or Application::Reschedule) comes out
- of the last level, the LazyDelete::flush is called. This will cause
- LazyDelete to delete all registered LazyDeletor objects.
-
- LazyDeletor<T> is a one instance object that contains a list of
- <T> objects to be deleted in sorted order. It is derived from
- LazyDeletorBase as to be able to register itself in LazyDelete.
-
- The user calls the static method LazyDeletor<T>::Delete( T* ) with the
- object to be destroyed lazy. The static method creates the LazyDeletor<T>
- (which in turn registers itself in LazyDelete) if this is the first time
- a T* is to be destroyed lazy. It then inserts the object. When the LazyDeletor<T>
- gets delete it will delete the stored objects in a fashion
- that will ensure the correct order of deletion via the specialized is_less method
- (e.g. if a Window is a child of another Window and therefore should be destroyed
- first it is "less" in this sense)
-
- LazyDelete::flush will be called when the top of the nested event loop is
- reached again and will then destroy each registered LazyDeletor<T> which
- in turn destroys the objects needed to be destroyed lazily. After this
- the state is as before entering the event loop.
-
- Preconditions:
- - The class <T> of which objects are to be destroyed needs a virtual
- destructor or must be final, else the wrong type will be destroyed.
- - The destructor of <T> should call LazyDeletor<T>::Undelete( this ). This
- prevents duplicate deletion in case someone destroys the object prematurely.
- */
-
- class LazyDeletorBase;
- class VCL_DLLPUBLIC LazyDelete
- {
- public:
- /** flush all registered object lists
- */
- static void flush();
- /** register an object list to be destroyed
- */
- static void addDeletor( LazyDeletorBase* pDeletor );
- };
-
- class VCL_DLLPUBLIC LazyDeletorBase
- {
- friend void LazyDelete::flush();
- protected:
- LazyDeletorBase();
- virtual ~LazyDeletorBase();
- };
-
- class VCL_DLLPUBLIC LazyDeletor : public LazyDeletorBase
- {
- static LazyDeletor* s_pOneInstance;
-
- struct DeleteObjectEntry
- {
- VclPtr<vcl::Window> m_pObject;
- bool m_bDeleted;
-
- DeleteObjectEntry( vcl::Window* i_pObject ) :
- m_pObject( i_pObject ),
- m_bDeleted( false )
- {}
- };
-
- std::vector< DeleteObjectEntry > m_aObjects;
- typedef std::unordered_map< sal_IntPtr, unsigned int > PtrToIndexMap;
- PtrToIndexMap m_aPtrToIndex;
-
- /** strict weak ordering function to bring objects to be destroyed lazily
- in correct order, e.g. for Window objects children before parents
- */
- static bool is_less( vcl::Window const * left, vcl::Window const * right );
-
- LazyDeletor() { LazyDelete::addDeletor( this ); }
- virtual ~LazyDeletor() override
- {
- SAL_INFO("vcl.lazydelete", typeid(*this).name() << std::hex << this << " deleted");
- if( s_pOneInstance == this ) // sanity check
- s_pOneInstance = nullptr;
-
- // do the actual work
- unsigned int nCount = m_aObjects.size();
- std::vector< VclPtr < vcl::Window > > aRealDelete;
- aRealDelete.reserve( nCount );
- for( unsigned int i = 0; i < nCount; i++ )
- {
- if( ! m_aObjects[i].m_bDeleted )
- {
- aRealDelete.push_back( m_aObjects[i].m_pObject );
- }
- }
- // sort the vector of objects to be destroyed
- std::sort( aRealDelete.begin(), aRealDelete.end(), is_less );
- nCount = aRealDelete.size();
- for( unsigned int n = 0; n < nCount; n++ )
- {
- SAL_INFO("vcl.lazydelete", typeid(*this).name() << " deletes object " << aRealDelete[n] << " of type "
- << typeid(*aRealDelete[n]).name());
- // check if the object to be deleted is not already destroyed
- // as a side effect of a previous lazily destroyed object
- if( ! m_aObjects[ m_aPtrToIndex[ reinterpret_cast<sal_IntPtr>(aRealDelete[n].get()) ] ].m_bDeleted )
- aRealDelete[n].disposeAndClear();
- }
- }
-
- public:
- /** mark an object for lazy deletion
- */
- static void Delete( vcl::Window* i_pObject )
- {
- if( s_pOneInstance == nullptr )
- s_pOneInstance = new LazyDeletor();
-
- // is this object already in the list ?
- // if so mark it as not to be deleted; else insert it
- PtrToIndexMap::const_iterator dup = s_pOneInstance->m_aPtrToIndex.find( reinterpret_cast<sal_IntPtr>(i_pObject) );
- if( dup != s_pOneInstance->m_aPtrToIndex.end() )
- {
- s_pOneInstance->m_aObjects[ dup->second ].m_bDeleted = false;
- }
- else
- {
- s_pOneInstance->m_aPtrToIndex[ reinterpret_cast<sal_IntPtr>(i_pObject) ] = s_pOneInstance->m_aObjects.size();
- s_pOneInstance->m_aObjects.push_back( DeleteObjectEntry( i_pObject ) );
- }
- }
- /** unmark an object already marked for lazy deletion
- */
- static void Undelete( vcl::Window* i_pObject )
- {
- if( s_pOneInstance )
- {
- PtrToIndexMap::const_iterator it = s_pOneInstance->m_aPtrToIndex.find( reinterpret_cast<sal_IntPtr>(i_pObject) );
- if( it != s_pOneInstance->m_aPtrToIndex.end() )
- s_pOneInstance->m_aObjects[ it->second ].m_bDeleted = true;
- }
- }
- };
-
/*
- class DeleteOnDeinit matches a similar need as LazyDelete for static objects:
- you may not access vcl objects after DeInitVCL has been called this includes their destruction
+ You may not access vcl objects after DeInitVCL has been called this includes their destruction
therefore disallowing the existence of static vcl object like e.g. a static BitmapEx
To work around this use DeleteOnDeinit<BitmapEx> which will allow you to have a static object container,
that will have its contents destroyed on DeinitVCL. The single drawback is that you need to check on the
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 3227d6d6c038..e1c49f44de5a 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -1571,14 +1571,16 @@ public:
// a helper method for a Control's Draw method
void PaintToDevice( ::OutputDevice* pDevice, const Point& rPos, const Size& rSize );
- /* mark Window for deletion in top of event queue
+ /* tdf#119390 set parent to default window. Typically for use in advance of destroying
+ * a floating windows which has the current focus so focus will revert to the main
+ * document window and not the first widget in the current parent of the floating
+ * window.
*/
- void doLazyDelete();
+ void SetParentToDefaultWindow();
// Keyboard access functions
-
/** Query the states of keyboard indicators - Caps Lock, Num Lock and
Scroll Lock. Use the following mask to retrieve the state of each
indicator:
diff --git a/svtools/source/uno/popupwindowcontroller.cxx b/svtools/source/uno/popupwindowcontroller.cxx
index 9d5b5c98bbdc..14f1cfc382f5 100644
--- a/svtools/source/uno/popupwindowcontroller.cxx
+++ b/svtools/source/uno/popupwindowcontroller.cxx
@@ -81,7 +81,8 @@ void PopupWindowControllerImpl::SetFloatingWindow()
mpFloatingWindow->RemoveEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ) );
// tdf#119390 reparent the window, so focus is restored
// to the last focused control of the application window.
- mpFloatingWindow->doLazyDelete();
+ mpFloatingWindow->SetParentToDefaultWindow();
+ mpFloatingWindow.disposeAndClear();
}
mpFloatingWindow = mpPopupWindow;
mpPopupWindow.clear();
diff --git a/vcl/README.lifecycle b/vcl/README.lifecycle
index 732b1908d077..dc6286210780 100644
--- a/vcl/README.lifecycle
+++ b/vcl/README.lifecycle
@@ -189,7 +189,7 @@ ways and often both.
---------- What remains to be done ? ----------
- * Cleanup DogTags and LazyDelete.
+ * Cleanup DogTags
* Expand the VclPtr pattern to many other less
than safe VCL types.
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 2cd32996be86..a43b830ded2b 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -458,10 +458,9 @@ static bool ImplYield(bool i_bWait, bool i_bAllEvents)
SAL_INFO("vcl.schedule", "Enter ImplYield: " << (i_bWait ? "wait" : "no wait") <<
": " << (i_bAllEvents ? "all events" : "one event"));
- // TODO: there's a data race here on WNT only because ImplYield may be
- // called without SolarMutex; if we can get rid of LazyDelete (with VclPtr)
- // then the only remaining use of mnDispatchLevel is in OSX specific code
- // so that would effectively eliminate the race on WNT
+ // there's a data race here on WNT only because ImplYield may be
+ // called without SolarMutex; but the only remaining use of mnDispatchLevel
+ // is in OSX specific code
pSVData->maAppData.mnDispatchLevel++;
// do not wait for events if application was already quit; in that
@@ -473,10 +472,6 @@ static bool ImplYield(bool i_bWait, bool i_bAllEvents)
DBG_TESTSOLARMUTEX(); // must be locked on return from Yield
- // flush lazy deleted objects
- if( pSVData->maAppData.mnDispatchLevel == 0 )
- vcl::LazyDelete::flush();
-
SAL_INFO("vcl.schedule", "Leave ImplYield with return " << bProcessedEvent );
return bProcessedEvent;
}
diff --git a/vcl/source/helper/lazydelete.cxx b/vcl/source/helper/lazydelete.cxx
index 05e1eef56d92..05c6a316a789 100644
--- a/vcl/source/helper/lazydelete.cxx
+++ b/vcl/source/helper/lazydelete.cxx
@@ -25,41 +25,6 @@
namespace vcl {
-LazyDeletorBase::LazyDeletorBase()
-{
-}
-
-LazyDeletorBase::~LazyDeletorBase()
-{
-}
-
-// instantiate instance pointer for LazyDeletor<Window>
-LazyDeletor* LazyDeletor::s_pOneInstance = nullptr;
-
-// a list for all LazyeDeletor<T> singletons
-static std::vector< LazyDeletorBase* > lcl_aDeletors;
-
-void LazyDelete::addDeletor( LazyDeletorBase* i_pDel )
-{
- lcl_aDeletors.push_back( i_pDel );
-}
-
-void LazyDelete::flush()
-{
- DBG_TESTSOLARMUTEX(); // must be locked
-
- unsigned int nCount = lcl_aDeletors.size();
- for( unsigned int i = 0; i < nCount; i++ )
- delete lcl_aDeletors[i];
- lcl_aDeletors.clear();
-}
-
-// specialized is_less function for Window
-bool LazyDeletor::is_less( vcl::Window const * left, vcl::Window const * right )
-{
- return left != right && right->IsChild( left, true );
-}
-
DeleteOnDeinitBase::~DeleteOnDeinitBase()
{
ImplSVData* pSVData = ImplGetSVData();
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index 686694e8e0c0..699ba937ee95 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2952,8 +2952,8 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R
{
pWin->StopExecute();
pWin->doShutdown();
- pWindow->doLazyDelete();
- pWindow = nullptr;
+ pWindow->SetParentToDefaultWindow();
+ pWindow.disposeAndClear();
ImplClosePopupToolBox(pW);
ImplFlushPendingSelect();
return nSelectedId;
@@ -3013,8 +3013,8 @@ sal_uInt16 PopupMenu::ImplExecute( const VclPtr<vcl::Window>& pW, const tools::R
}
}
pWin->doShutdown();
- pWindow->doLazyDelete();
- pWindow = nullptr;
+ pWindow->SetParentToDefaultWindow();
+ pWindow.disposeAndClear();
ImplClosePopupToolBox(pW);
ImplFlushPendingSelect();
}
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index 6fbb4af4eac3..a4c33051046b 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -377,8 +377,8 @@ void MenuBarWindow::KillActivePopup()
}
pActivePopup->ImplGetFloatingWindow()->StopExecute();
pActivePopup->ImplGetFloatingWindow()->doShutdown();
- pActivePopup->pWindow->doLazyDelete();
- pActivePopup->pWindow = nullptr;
+ pActivePopup->pWindow->SetParentToDefaultWindow();
+ pActivePopup->pWindow.disposeAndClear();
}
pActivePopup = nullptr;
}
diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx
index 67d6d0ce3a8e..38bb20301bef 100644
--- a/vcl/source/window/menufloatingwindow.cxx
+++ b/vcl/source/window/menufloatingwindow.cxx
@@ -473,8 +473,8 @@ void MenuFloatingWindow::KillActivePopup( PopupMenu* pThisOnly )
{
pPopup->ImplGetFloatingWindow()->StopExecute();
pPopup->ImplGetFloatingWindow()->doShutdown();
- pPopup->pWindow->doLazyDelete();
- pPopup->pWindow = nullptr;
+ pPopup->pWindow->SetParentToDefaultWindow();
+ pPopup->pWindow.disposeAndClear();
Update();
}
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 7f229a94eddc..3c1c0aac5f27 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -571,8 +571,6 @@ void Window::dispose()
Window::~Window()
{
- // FIXME: we should kill all LazyDeletor usage.
- vcl::LazyDeletor::Undelete( this );
disposeOnce();
}
@@ -1758,16 +1756,10 @@ void Window::ImplNewInputContext()
pFocusWin->ImplGetFrame()->SetInputContext( &aNewContext );
}
-void Window::doLazyDelete()
+void Window::SetParentToDefaultWindow()
{
- SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(this);
- DockingWindow* pDockWin = dynamic_cast<DockingWindow*>(this);
- if( pSysWin || ( pDockWin && pDockWin->IsFloatingMode() ) )
- {
- Show( false );
- SetParent( ImplGetDefaultWindow() );
- }
- vcl::LazyDeletor::Delete( this );
+ Show(false);
+ SetParent(ImplGetDefaultWindow());
}
KeyIndicatorState Window::GetIndicatorState() const
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index a105df5f6e36..45bbfaf7ef9a 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -349,8 +349,8 @@ void Window::EndAutoScroll()
pSVData->maWinData.mpAutoScrollWin = nullptr;
pSVData->maWinData.mnAutoScrollFlags = StartAutoScrollFlags::NONE;
pSVData->maAppData.mpWheelWindow->ImplStop();
- pSVData->maAppData.mpWheelWindow->doLazyDelete();
- pSVData->maAppData.mpWheelWindow = nullptr;
+ pSVData->maAppData.mpWheelWindow->SetParentToDefaultWindow();
+ pSVData->maAppData.mpWheelWindow.disposeAndClear();
}
}