diff --git a/mozilla/widget/macbuild/widget.mcp b/mozilla/widget/macbuild/widget.mcp index 3d0b8f2cde1..ab2b2508673 100644 Binary files a/mozilla/widget/macbuild/widget.mcp and b/mozilla/widget/macbuild/widget.mcp differ diff --git a/mozilla/widget/src/mac/nsMacEventHandler.cpp b/mozilla/widget/src/mac/nsMacEventHandler.cpp index 9dcf59d368a..5c16800253c 100644 --- a/mozilla/widget/src/mac/nsMacEventHandler.cpp +++ b/mozilla/widget/src/mac/nsMacEventHandler.cpp @@ -17,8 +17,9 @@ */ #include - #include "nsMacEventHandler.h" +#include "nsWindow.h" +#include "nsToolkit.h" #include "prinrval.h" // from MacHeaders.c @@ -45,6 +46,21 @@ nsMacEventHandler::nsMacEventHandler(nsWindow* aTopLevelWidget) nsMacEventHandler::~nsMacEventHandler() { + if (mLastWidgetPointed) + mLastWidgetPointed->RemoveDeleteObserver(this); + + if (mLastWidgetHit) + mLastWidgetHit->RemoveDeleteObserver(this); +} + + +void nsMacEventHandler::NotifyDelete(void* aDeletedObject) +{ + if (mLastWidgetPointed == aDeletedObject) + mLastWidgetPointed = nsnull; + + if (mLastWidgetHit == aDeletedObject) + mLastWidgetHit = nsnull; } @@ -367,7 +383,14 @@ PRBool nsMacEventHandler::HandleMouseDownEvent( // dispatch the event retVal = widgetHit->DispatchMouseEvent(mouseEvent); } + + if (mLastWidgetHit) + mLastWidgetHit->RemoveDeleteObserver(this); + mLastWidgetHit = widgetHit; + + if (mLastWidgetHit) + mLastWidgetHit->AddDeleteObserver(this); break; } } @@ -392,8 +415,10 @@ PRBool nsMacEventHandler::HandleMouseUpEvent( if ((widgetReleased != nsnull) && (widgetReleased != mLastWidgetHit)) retVal |= widgetReleased->DispatchMouseEvent(mouseEvent); - if (mLastWidgetHit != nsnull) + if (mLastWidgetHit) { + mLastWidgetHit->RemoveDeleteObserver(this); + retVal |= mLastWidgetHit->DispatchMouseEvent(mouseEvent); mLastWidgetHit = nsnull; } @@ -420,17 +445,22 @@ PRBool nsMacEventHandler::HandleMouseMoveEvent( { if (mLastWidgetPointed != nsnull) { + mLastWidgetPointed->RemoveDeleteObserver(this); + mouseEvent.widget = mLastWidgetPointed; mouseEvent.message = NS_MOUSE_EXIT; retVal |= mLastWidgetPointed->DispatchMouseEvent(mouseEvent); mLastWidgetPointed = nsnull; mouseEvent.widget = widgetPointed; } + if (widgetPointed != nsnull) { + widgetPointed->AddDeleteObserver(this); + + mLastWidgetPointed = widgetPointed; mouseEvent.message = NS_MOUSE_ENTER; retVal |= widgetPointed->DispatchMouseEvent(mouseEvent); - mLastWidgetPointed = widgetPointed; } } else diff --git a/mozilla/widget/src/mac/nsMacEventHandler.h b/mozilla/widget/src/mac/nsMacEventHandler.h index 93958fb29a9..08df3b78858 100644 --- a/mozilla/widget/src/mac/nsMacEventHandler.h +++ b/mozilla/widget/src/mac/nsMacEventHandler.h @@ -20,11 +20,13 @@ #include #include -#include "nsWindow.h" +#include "nsDeleteObserver.h" #include "nsCOMPtr.h" +#include "nsGUIEvent.h" +class nsWindow; -class nsMacEventHandler +class nsMacEventHandler : public nsDeleteObserver { public: nsMacEventHandler(nsWindow* aTopLevelWidget); @@ -46,6 +48,9 @@ protected: nsMouseEvent& aMouseEvent, PRUint32 aMessage); +public: + virtual void NotifyDelete(void* aDeletedObject); + protected: nsWindow* mTopLevelWidget; nsWindow* mLastWidgetHit; diff --git a/mozilla/widget/src/mac/nsToolkit.cpp b/mozilla/widget/src/mac/nsToolkit.cpp index 404fb6f04a8..3b9de7e7d1e 100644 --- a/mozilla/widget/src/mac/nsToolkit.cpp +++ b/mozilla/widget/src/mac/nsToolkit.cpp @@ -28,7 +28,7 @@ PLEventQueue* nsToolkit::sPLEventQueue = nsnull; extern "C" NS_EXPORT PLEventQueue* GetMacPLEventQueue() { return nsToolkit::GetEventQueue(); - } +} //================================================================= /* Constructor @@ -50,6 +50,12 @@ nsToolkit::nsToolkit(): Repeater() */ nsToolkit::~nsToolkit() { + if (mFocusedWidget) + { + mFocusedWidget->RemoveDeleteObserver(this); + mFocusedWidget = nsnull; + } + StopRepeating(); } @@ -71,16 +77,20 @@ void nsToolkit::SetFocus(nsWindow *aFocusWidget) // tell the old widget, it is not focused if (mFocusedWidget) { + mFocusedWidget->RemoveDeleteObserver(this); + guiEvent.message = NS_LOSTFOCUS; guiEvent.widget = mFocusedWidget; mFocusedWidget->DispatchWindowEvent(guiEvent); - mFocusedWidget = nil; + mFocusedWidget = nsnull; } // let the new one know if (aFocusWidget) { - mFocusedWidget = aFocusWidget; + mFocusedWidget = aFocusWidget; + mFocusedWidget->AddDeleteObserver(this); + guiEvent.message = NS_GOTFOCUS; guiEvent.widget = mFocusedWidget; mFocusedWidget->DispatchWindowEvent(guiEvent); @@ -124,3 +134,13 @@ void nsToolkit::RepeatAction(const EventRecord& /*inMacEvent*/) // Handle pending NSPR events PL_ProcessPendingEvents( sPLEventQueue ); } + + +//================================================================= +/* + */ +void nsToolkit::NotifyDelete(void* aDeletedObject) +{ + if (mFocusedWidget == aDeletedObject) + mFocusedWidget = nsnull; +} diff --git a/mozilla/widget/src/mac/nsToolkit.h b/mozilla/widget/src/mac/nsToolkit.h index e257bf5c27b..8c437691b66 100644 --- a/mozilla/widget/src/mac/nsToolkit.h +++ b/mozilla/widget/src/mac/nsToolkit.h @@ -21,10 +21,11 @@ #include "nsIToolkit.h" #include "nsRepeater.h" -struct PLEventQueue; -class nsWindow; +#include "nsDeleteObserver.h" +struct PLEventQueue; struct MethodInfo; +class nsWindow; /** * Wrapper around the thread running the message pump. @@ -32,7 +33,7 @@ struct MethodInfo; * execute within the same thread that created the widget under Win32. */ -class nsToolkit : public nsIToolkit, public Repeater +class nsToolkit : public nsIToolkit, public Repeater, public nsDeleteObserver { public: @@ -49,9 +50,10 @@ public: // Event Queue static PLEventQueue* GetEventQueue(){ return sPLEventQueue; } - // LPeriodical interface + // Repeater interface virtual void RepeatAction(const EventRecord& inMacEvent); - + // DeleteObserver + virtual void NotifyDelete(void* aDeletedObject); private: static nsWindow* mFocusedWidget; static PLEventQueue* sPLEventQueue; diff --git a/mozilla/widget/src/mac/nsWindow.cpp b/mozilla/widget/src/mac/nsWindow.cpp index be786fc6820..2a87014d2f7 100644 --- a/mozilla/widget/src/mac/nsWindow.cpp +++ b/mozilla/widget/src/mac/nsWindow.cpp @@ -20,6 +20,7 @@ #include "nsIFontMetrics.h" #include "nsIDeviceContext.h" #include "nsCOMPtr.h" +#include "nsToolkit.h" NS_IMPL_ADDREF(ChildWindow) @@ -37,7 +38,7 @@ ChildWindow::ChildWindow() : nsWindow() // nsWindow constructor // //------------------------------------------------------------------------- -nsWindow::nsWindow() : nsBaseWidget() +nsWindow::nsWindow() : nsBaseWidget() , nsDeleteObserved(this) { NS_INIT_REFCNT(); strcpy(gInstanceClassName, "nsWindow"); @@ -56,6 +57,7 @@ nsWindow::nsWindow() : nsBaseWidget() mWindowPtr = nsnull; mDrawing = PR_FALSE; mDestroyCalled = PR_FALSE; + mDestructorCalled = PR_FALSE; SetBackgroundColor(NS_RGB(255, 255, 255)); SetForegroundColor(NS_RGB(0, 0, 0)); @@ -69,9 +71,12 @@ nsWindow::nsWindow() : nsBaseWidget() //------------------------------------------------------------------------- nsWindow::~nsWindow() { - //Destroy(); + mDestructorCalled = PR_TRUE; - mEventCallback = nsnull; // prevent the widget from causing additional events +//¥¥¥ if (mToolkit && ((nsToolkit*)mToolkit)->GetFocus() == this ) +//¥¥¥ ((nsToolkit*)mToolkit)->SetFocus(nsnull); + + //Destroy(); if (mWindowRegion != nsnull) { @@ -80,7 +85,7 @@ nsWindow::~nsWindow() } NS_IF_RELEASE(mTempRenderingContext); - NS_IF_RELEASE(mMenuListener); + NS_IF_RELEASE(mMenuListener); } @@ -174,20 +179,12 @@ NS_IMETHODIMP nsWindow::Destroy() if (mDestroyCalled) return NS_OK; mDestroyCalled = PR_TRUE; - -#if 0 - // if the window being destroyed has the focus, lose it so that there isn't a dangling reference - if (mToolkit && ((nsToolkit*)mToolkit)->GetFocus() == this ) -#else - //¥¥¥TEMPORARY¥¥¥ - // We clear the focus when destroying a top level window. If we check whether - // this window has the focus (as we should - see above), the focus isn't cleared - // and we crash in the following case: open window A, open window B, select A, close A => crash - if (mToolkit && (mParent == nsnull)) -#endif - { - ((nsToolkit*)mToolkit)->SetFocus(nsnull); - } + +//¥¥¥ // if the window being destroyed has the focus, lose it so that there isn't a dangling reference +//¥¥¥ if (mToolkit && ((nsToolkit*)mToolkit)->GetFocus() == this ) +//¥¥¥ { +//¥¥¥ ((nsToolkit*)mToolkit)->SetFocus(nsnull); +//¥¥¥ } nsBaseWidget::OnDestroy(); nsBaseWidget::Destroy(); @@ -888,24 +885,25 @@ PRBool nsWindow::ConvertStatus(nsEventStatus aStatus) //------------------------------------------------------------------------- NS_IMETHODIMP nsWindow::DispatchEvent(nsGUIEvent* event, nsEventStatus& aStatus) { - nsIWidget* aWidget = event->widget; - NS_IF_ADDREF(aWidget); - aStatus = nsEventStatus_eIgnore; - - if (nsnull != mMenuListener){ - if(NS_MENU_EVENT == event->eventStructType) - aStatus = mMenuListener->MenuSelected( static_cast(*event) ); - } - if (mEventCallback) - aStatus = (*mEventCallback)(event); + if (! mDestructorCalled) + { + nsIWidget* aWidget = event->widget; + NS_IF_ADDREF(aWidget); + + if (nsnull != mMenuListener){ + if(NS_MENU_EVENT == event->eventStructType) + aStatus = mMenuListener->MenuSelected( static_cast(*event) ); + } + if (mEventCallback) + aStatus = (*mEventCallback)(event); - // Dispatch to event listener if event was not consumed - if ((aStatus != nsEventStatus_eIgnore) && (mEventListener != nsnull)) - aStatus = mEventListener->ProcessEvent(*event); - - NS_IF_RELEASE(aWidget); + // Dispatch to event listener if event was not consumed + if ((aStatus != nsEventStatus_eIgnore) && (mEventListener != nsnull)) + aStatus = mEventListener->ProcessEvent(*event); + NS_IF_RELEASE(aWidget); + } return NS_OK; } diff --git a/mozilla/widget/src/mac/nsWindow.h b/mozilla/widget/src/mac/nsWindow.h index 08bf8af8029..5c000ebad75 100644 --- a/mozilla/widget/src/mac/nsWindow.h +++ b/mozilla/widget/src/mac/nsWindow.h @@ -20,8 +20,7 @@ #include "nsISupports.h" #include "nsBaseWidget.h" - -#include "nsToolkit.h" +#include "nsDeleteObserver.h" #include "nsIWidget.h" #include "nsIEnumerator.h" @@ -45,7 +44,7 @@ //------------------------------------------------------------------------- // Generic object -class nsWindow : public nsBaseWidget +class nsWindow : public nsBaseWidget, public nsDeleteObserved { public: @@ -170,6 +169,7 @@ protected: RgnHandle mWindowRegion; // the region defining this window WindowPtr mWindowPtr; PRBool mDestroyCalled; + PRBool mDestructorCalled; PRBool mDrawing; nsIRenderingContext* mTempRenderingContext;