Cleaned up widget reference counting. In particular parent widgets

release their references to child widgets


git-svn-id: svn://10.0.0.236/trunk@7615 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
troy%netscape.com
1998-08-09 01:37:30 +00:00
parent 2701eafa8a
commit 786bb2438d
2 changed files with 66 additions and 48 deletions

View File

@@ -388,11 +388,16 @@ nsWindow::nsWindow(nsISupports *aOuter) : nsObject(aOuter)
//-------------------------------------------------------------------------
nsWindow::~nsWindow()
{
mIsDestroying = PR_TRUE;
if (gCurrentWindow == this) {
gCurrentWindow = nsnull;
}
mIsDestroying = PR_TRUE;
if (gCurrentWindow == this) {
gCurrentWindow = nsnull;
}
// If the widget was released without calling Destroy() then the native
// window still exists, and we need to destroy it
if (NULL != mWnd) {
Destroy();
}
}
@@ -472,7 +477,7 @@ void nsWindow::Create(nsIWidget *aParent,
// save the event callback function
mEventCallback = aHandleEventFunction;
// keep a reference to the toolkit object
// keep a reference to the device context
if (aContext) {
mContext = aContext;
NS_ADDREF(mContext);
@@ -573,7 +578,7 @@ void nsWindow::Create(nsNativeWidget aParent,
// save the event callback function
mEventCallback = aHandleEventFunction;
// keep a reference to the toolkit object
// keep a reference to the device context
if (aContext) {
mContext = aContext;
NS_ADDREF(mContext);
@@ -639,38 +644,29 @@ NS_IMETHODIMP nsWindow::SetClientData(void* aClientData)
//-------------------------------------------------------------------------
void nsWindow::Destroy()
{
//
// Switch to the "main gui thread" if necessary... This method must
// be executed on the "gui thread"...
//
if (mToolkit != nsnull && !mToolkit->IsGuiThread()) {
MethodInfo info(this, nsWindow::DESTROY);
mToolkit->CallMethod(&info);
return;
}
// Switch to the "main gui thread" if necessary... This method must
// be executed on the "gui thread"...
if (mToolkit != nsnull && !mToolkit->IsGuiThread()) {
MethodInfo info(this, nsWindow::DESTROY);
mToolkit->CallMethod(&info);
return;
}
//if we were in the middle deferred window positioning
if (mDeferredPositioner) {
VERIFY(::EndDeferWindowPos(mDeferredPositioner));
// disconnect from the parent
if (!mIsDestroying) {
nsIWidget *parent = GetParent();
if (parent) {
parent->RemoveChild(this);
NS_RELEASE(parent);
}
}
// destroy the nsWindow
if (mWnd) {
// destroy the nsWindow
mEventCallback = nsnull; // prevent the widget from causing additional events
VERIFY(::DestroyWindow(mWnd));
}
if (mPalette) {
VERIFY(::DeleteObject(mPalette));
mPalette = NULL;
}
// Destroy the tooltip control
if (mTooltip) {
VERIFY(::DestroyWindow(mTooltip));
}
NS_IF_RELEASE(mAppShell);
// destroy the HWND
if (mWnd) {
// prevent the widget from causing additional events
mEventCallback = nsnull;
VERIFY(::DestroyWindow(mWnd));
}
}
@@ -681,16 +677,24 @@ void nsWindow::Destroy()
//-------------------------------------------------------------------------
nsIWidget* nsWindow::GetParent(void)
{
nsIWidget* widget = NULL;
nsWindow* widget = NULL;
if (mWnd) {
HWND parent = ::GetParent(mWnd);
if (parent) {
widget = (nsIWidget*)((nsWindow *)::GetWindowLong(mWnd, GWL_USERDATA));
NS_ADDREF(widget);
widget = (nsWindow *)::GetWindowLong(mWnd, GWL_USERDATA);
if (widget) {
// If the widget is in the process of being destroyed then
// do NOT return it
if (widget->mIsDestroying) {
widget = NULL;
} else {
NS_ADDREF(widget);
}
}
}
}
return widget;
return (nsIWidget*)widget;
}
@@ -1766,14 +1770,32 @@ void nsWindow::OnDestroy()
// free GDI objects
if (mBrush) {
::DeleteObject(mBrush);
mBrush = nsnull;
VERIFY(::DeleteObject(mBrush));
mBrush = NULL;
}
if (mPalette) {
VERIFY(::DeleteObject(mPalette));
mPalette = NULL;
}
// release references to children, device context, and toolkit
// free tooltip window
if (mTooltip) {
VERIFY(::DestroyWindow(mTooltip));
mTooltip = NULL;
}
// if we were in the middle of deferred window positioning then
// free the memory for the multiple-window position structure
if (mDeferredPositioner) {
VERIFY(::EndDeferWindowPos(mDeferredPositioner));
mDeferredPositioner = NULL;
}
// release references to children, device context, toolkit, and app shell
NS_IF_RELEASE(mChildren);
NS_IF_RELEASE(mContext);
NS_IF_RELEASE(mToolkit);
NS_IF_RELEASE(mAppShell);
// dispatch the event
if (!mIsDestroying) {
@@ -2041,14 +2063,11 @@ nsWindow::Enumerator::Enumerator()
nsWindow::Enumerator::~Enumerator()
{
if (mChildrens) {
// XXX We add ref'd when adding the child widget, so we should release
// the reference now, but if we do we'll crash because of the way the
// view hierarchy is being destroyed...
#if 0
// We add ref'd when adding the child widgets, so we need to release
// the references now
for (int i = 0; (i < mArraySize) && (nsnull != mChildrens[i]); i++) {
NS_RELEASE(mChildrens[i]);
}
#endif
delete[] mChildrens;
}

View File

@@ -177,7 +177,6 @@ protected:
WNDPROC mPrevWndProc;
EVENT_CALLBACK mEventCallback;
nsIDeviceContext *mContext;
nsIFontMetrics *mFontMetrics;
nsIAppShell *mAppShell;
nsToolkit *mToolkit;