vclref: re-work mbInDtor handling, add IsDisposed method and more.
Change-Id: I4b522e0df372d61d8bb7bbcd4b0629c4412cae06
diff --git a/include/vcl/window.hxx b/include/vcl/window.hxx
index 09589f5..7d104a4 100644
--- a/include/vcl/window.hxx
+++ b/include/vcl/window.hxx
@@ -421,7 +421,6 @@ private:
::OutputDevice* mpOutputDevice;
mutable int mnRefCnt; // reference count
bool mbInDtor = false; // true: We're still in Window-Dtor
#ifdef DBG_UTIL
friend const char* ::ImplDbgCheckWindow( const void* pObj );
@@ -772,6 +771,7 @@ public:
bool IsMenuFloatingWindow() const;
bool IsToolbarFloatingWindow() const;
bool IsTopWindow() const;
bool IsDisposed() const;
SystemWindow* GetSystemWindow() const;
void EnableAllResize( bool bEnable = true );
diff --git a/vcl/inc/window.h b/vcl/inc/window.h
index 4eb3c6b..ab9c90a 100644
--- a/vcl/inc/window.h
+++ b/vcl/inc/window.h
@@ -355,7 +355,6 @@ public:
mbCompoundControlHasFocus:1,
mbPaintDisabled:1,
mbAllResize:1,
mbInDtor:1,
mbInDispose:1,
mbExtTextInput:1,
mbInFocusHdl:1,
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 1c4eba9..4c3ba1c 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1633,7 +1633,12 @@ void Application::setDeInitHook(Link const & hook) {
void ImplDelData::AttachToWindow( const vcl::Window* pWindow )
{
if( pWindow )
const_cast<vcl::Window*>(pWindow)->ImplAddDel( this );
{
if( pWindow->IsDisposed() )
mbDel = true;
else
const_cast<vcl::Window*>(pWindow)->ImplAddDel( this );
}
}
// define dtor for ImplDelData
diff --git a/vcl/source/window/event.cxx b/vcl/source/window/event.cxx
index da38fde..d4e4601 100644
--- a/vcl/source/window/event.cxx
+++ b/vcl/source/window/event.cxx
@@ -221,6 +221,9 @@ void Window::CallEventListeners( sal_uLong nEvent, void* pData )
{
pWindow->ImplAddDel( &aDelData );
if ( aDelData.IsDead() )
return;
pWindow->mpWindowImpl->maChildEventListeners.Call( &aEvent );
if ( aDelData.IsDead() )
diff --git a/vcl/source/window/mouse.cxx b/vcl/source/window/mouse.cxx
index bc16a6e..3691a0a 100644
--- a/vcl/source/window/mouse.cxx
+++ b/vcl/source/window/mouse.cxx
@@ -198,7 +198,7 @@ static bool IsWindowFocused(const WindowImpl& rWinImpl)
void Window::ImplGrabFocus( sal_uInt16 nFlags )
{
// #143570# no focus for destructing windows
if( mpWindowImpl->mbInDtor )
if( !mpWindowImpl || mpWindowImpl->mbInDispose )
return;
// some event listeners do really bad stuff
@@ -283,7 +283,9 @@ void Window::ImplGrabFocus( sal_uInt16 nFlags )
pParent = pParent->mpWindowImpl->mpParent;
}
if ( ( pSVData->maWinData.mpFocusWin != this && ! mpWindowImpl->mbInDtor ) || ( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
if ( ( pSVData->maWinData.mpFocusWin != this &&
mpWindowImpl && !mpWindowImpl->mbInDispose ) ||
( bAsyncFocusWaiting && !bHasFocus && !bMustNotGrabFocus ) )
{
// EndExtTextInput if it is not the same window
if ( pSVData->maWinData.mpExtTextInputWin &&
diff --git a/vcl/source/window/stacking.cxx b/vcl/source/window/stacking.cxx
index 9d81501..5b58e2a 100644
--- a/vcl/source/window/stacking.cxx
+++ b/vcl/source/window/stacking.cxx
@@ -632,7 +632,7 @@ void Window::EnableAlwaysOnTop( bool bEnable )
bool Window::IsTopWindow() const
{
if ( mpWindowImpl->mbInDtor )
if ( !mpWindowImpl || mpWindowImpl->mbInDispose )
return false;
// topwindows must be frames or they must have a borderwindow which is a frame
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 9aa378f..ac250c6 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -131,9 +131,14 @@ namespace
}
#endif
bool Window::IsDisposed() const
{
return !mpWindowImpl;
}
void Window::dispose()
{
if (!mpWindowImpl)
if (IsDisposed())
return;
assert( !mpWindowImpl->mbInDispose && "vcl::Window - already in dispose()" );
@@ -571,8 +576,6 @@ void Window::dispose()
Window::~Window()
{
DBG_ASSERT( !mbInDtor, "~Window - already in DTOR!" );
mbInDtor = true;
vcl::LazyDeletor<vcl::Window>::Undelete( this );
dispose();
}
@@ -1197,8 +1200,6 @@ void Window::ImplInitWindowData( WindowType nType )
mpOutputDevice = (OutputDevice*)this;
mnRefCnt = 0;
mbInDtor = false; // true: We're still in Window-Dtor
mpWindowImpl = new WindowImpl( nType );
meOutDevType = OUTDEV_WINDOW;
@@ -1363,6 +1364,12 @@ void Window::ImplSetReallyVisible()
void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompatibility ok
{
if ( IsDisposed() )
{
pDel->mbDel = true;
return;
}
DBG_ASSERT( !pDel->mpWindow, "Window::ImplAddDel(): cannot add ImplDelData twice !" );
if( !pDel->mpWindow )
{
@@ -1375,6 +1382,10 @@ void Window::ImplAddDel( ImplDelData* pDel ) // TODO: make "const" when incompat
void Window::ImplRemoveDel( ImplDelData* pDel ) // TODO: make "const" when incompatibility ok
{
pDel->mpWindow = NULL; // #112873# pDel is not associated with a Window anymore
if ( IsDisposed() )
return;
if ( mpWindowImpl->mpFirstDel == pDel )
mpWindowImpl->mpFirstDel = pDel->mpNext;
else
diff --git a/vcl/source/window/window2.cxx b/vcl/source/window/window2.cxx
index b8abd0a..d60d15d 100644
--- a/vcl/source/window/window2.cxx
+++ b/vcl/source/window/window2.cxx
@@ -1215,22 +1215,22 @@ bool Window::IsControlBackground() const
bool Window::IsInPaint() const
{
return mpWindowImpl->mbInPaint;
return mpWindowImpl ? mpWindowImpl->mbInPaint : false;
}
vcl::Window* Window::GetParent() const
{
return mpWindowImpl->mpRealParent;
return mpWindowImpl ? mpWindowImpl->mpRealParent : NULL;
}
bool Window::IsVisible() const
{
return mpWindowImpl->mbVisible;
return mpWindowImpl ? mpWindowImpl->mbVisible : false;
}
bool Window::IsReallyVisible() const
{
return mpWindowImpl->mbReallyVisible;
return mpWindowImpl ? mpWindowImpl->mbReallyVisible : false;
}
bool Window::IsReallyShown() const
@@ -1370,8 +1370,8 @@ bool Window::IsCreatedWithToolkit() const
void Window::SetCreatedWithToolkit( bool b )
{
mpWindowImpl->mbCreatedWithToolkit = b;
}
const Pointer& Window::GetPointer() const
{
return mpWindowImpl->maPointer;
@@ -1442,6 +1442,9 @@ void Window::InvalidateSizeCache()
void Window::queue_resize(StateChangedType eReason)
{
if (IsDisposed())
return;
bool bSomeoneCares = queue_ungrouped_resize(this);
if (eReason != StateChangedType::VISIBLE)