use a comptr for the nsIRegion in nsWidget, fix a leak with lookandfeel objects in widget that both dbaron@fas.harvard.edu and I found at about the same time. and clean up more carefully and avoid processing events if we are destroyed or being destroyed to avoid those natsty lil crashes. fixes bug 20291 and 29342

This commit is contained in:
pavlov%netscape.com 2000-03-12 07:26:04 +00:00
parent 0487a8b1a3
commit 4c5654e663
5 changed files with 39 additions and 9 deletions

View File

@ -773,6 +773,11 @@ handle_gdk_event (GdkEvent *event, gpointer data)
// It was an event on one of our superwindows
nsWindow *window = (nsWindow *)gtk_object_get_data (object, "nsWindow");
// if we don't have a window here anymore, we are probably in the process of being or have been destroyed
if (!window)
return;
GtkWidget *current_grab = gtk_grab_get_current();
// if there's a grab in progress, make sure to send it right to that widget.

View File

@ -260,11 +260,8 @@ nsWidget::nsWidget()
mIsDragDest = PR_FALSE;
mIsToplevel = PR_FALSE;
if (NS_OK == nsComponentManager::CreateInstance(kRegionCID,
nsnull,
NS_GET_IID(nsIRegion),
(void**)&mUpdateArea))
{
mUpdateArea = do_CreateInstance(kRegionCID);
if (mUpdateArea) {
mUpdateArea->Init();
mUpdateArea->SetTo(0, 0, 0, 0);
}
@ -338,13 +335,11 @@ nsWidget::~nsWidget()
printf("nsWidget::~nsWidget:%p\n", this);
#endif
NS_IF_RELEASE(mUpdateArea);
// it's safe to always call Destroy() because it will only allow itself
// to be called once
Destroy();
if (!sWidgetCount--) {
if (!--sWidgetCount) {
NS_IF_RELEASE(sLookAndFeel);
}
@ -424,6 +419,10 @@ NS_IMETHODIMP nsWidget::Destroy(void)
if (mIsDestroying)
return NS_OK;
// we don't want people sending us events if we are the button motion target
if (sButtonMotionTarget == this)
sButtonMotionTarget = nsnull;
// ok, set our state
mIsDestroying = PR_TRUE;
@ -1642,6 +1641,9 @@ nsWidget::InstallRealizeSignal(GtkWidget * aWidget)
nsWidget::OnMotionNotifySignal(GdkEventMotion * aGdkMotionEvent)
{
if (mIsDestroying)
return;
nsMouseEvent event;
event.message = NS_MOUSE_MOVE;

View File

@ -487,7 +487,7 @@ protected:
// This is the composite update area (union of all the calls to
// Invalidate)
nsIRegion *mUpdateArea;
nsCOMPtr<nsIRegion> mUpdateArea;
PRBool mShown;

View File

@ -165,6 +165,22 @@ nsWindow::~nsWindow()
UnqueueDraw();
}
NS_IMETHODIMP nsWindow::Destroy(void)
{
// remove our pointer from the object so that we event handlers don't send us events
// after we are gone or in the process of going away
if (mSuperWin)
gtk_object_remove_data(GTK_OBJECT(mSuperWin), "nsWindow");
if (mShell)
gtk_object_remove_data(GTK_OBJECT(mShell), "nsWindow");
if (mMozArea)
gtk_object_remove_data(GTK_OBJECT(mMozArea), "nsWindow");
return nsWidget::Destroy();
}
PRBool nsWindow::IsChild() const
{
return PR_FALSE;
@ -1028,6 +1044,9 @@ nsWindow::InstallFocusOutSignal(GtkWidget * aWidget)
void
nsWindow::HandleGDKEvent(GdkEvent *event)
{
if (mIsDestroying)
return;
switch (event->any.type)
{
case GDK_MOTION_NOTIFY:
@ -2543,6 +2562,9 @@ nsWindow::HandleXlibExposeEvent(XEvent *event)
void
nsWindow::HandleXlibButtonEvent(XButtonEvent * aButtonEvent)
{
if (mIsDestroying)
return;
nsMouseEvent event;
PRUint32 eventType = 0;

View File

@ -86,6 +86,7 @@ public:
NS_IMETHOD SetCursor(nsCursor aCursor);
NS_IMETHOD SetFocus(void);
NS_IMETHOD GetAttention(void);
NS_IMETHOD Destroy();
void QueueDraw();
void UnqueueDraw();