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
Родитель f195d6e51c
Коммит b5164d7cc3
5 изменённых файлов: 39 добавлений и 9 удалений

Просмотреть файл

@ -773,6 +773,11 @@ handle_gdk_event (GdkEvent *event, gpointer data)
// It was an event on one of our superwindows // It was an event on one of our superwindows
nsWindow *window = (nsWindow *)gtk_object_get_data (object, "nsWindow"); 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(); GtkWidget *current_grab = gtk_grab_get_current();
// if there's a grab in progress, make sure to send it right to that widget. // if there's a grab in progress, make sure to send it right to that widget.

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -165,6 +165,22 @@ nsWindow::~nsWindow()
UnqueueDraw(); 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 PRBool nsWindow::IsChild() const
{ {
return PR_FALSE; return PR_FALSE;
@ -1028,6 +1044,9 @@ nsWindow::InstallFocusOutSignal(GtkWidget * aWidget)
void void
nsWindow::HandleGDKEvent(GdkEvent *event) nsWindow::HandleGDKEvent(GdkEvent *event)
{ {
if (mIsDestroying)
return;
switch (event->any.type) switch (event->any.type)
{ {
case GDK_MOTION_NOTIFY: case GDK_MOTION_NOTIFY:
@ -2543,6 +2562,9 @@ nsWindow::HandleXlibExposeEvent(XEvent *event)
void void
nsWindow::HandleXlibButtonEvent(XButtonEvent * aButtonEvent) nsWindow::HandleXlibButtonEvent(XButtonEvent * aButtonEvent)
{ {
if (mIsDestroying)
return;
nsMouseEvent event; nsMouseEvent event;
PRUint32 eventType = 0; PRUint32 eventType = 0;

Просмотреть файл

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