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
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.

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

@ -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;

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

@ -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;

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

@ -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;

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

@ -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();