зеркало из https://github.com/mozilla/pjs.git
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:
Родитель
f195d6e51c
Коммит
b5164d7cc3
|
@ -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();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче