From 22cd501286fba6c158e63aff62ff44fec116eb11 Mon Sep 17 00:00:00 2001 From: "danm%netscape.com" Date: Wed, 1 Dec 1999 22:38:06 +0000 Subject: [PATCH] hooking up 'close' xul event handler. bug 13695. r:hyatt@netscape.com git-svn-id: svn://10.0.0.236/trunk@54951 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/widget/src/gtk/nsWindow.cpp | 17 ++++- mozilla/widget/src/mac/nsMacEventHandler.cpp | 75 ++++++++----------- mozilla/widget/src/mac/nsMacEventHandler.h | 2 + mozilla/widget/src/windows/nsWindow.cpp | 5 ++ .../xpfe/appshell/src/nsWebShellWindow.cpp | 54 ++++++++++++- mozilla/xpfe/appshell/src/nsWebShellWindow.h | 1 + 6 files changed, 106 insertions(+), 48 deletions(-) diff --git a/mozilla/widget/src/gtk/nsWindow.cpp b/mozilla/widget/src/gtk/nsWindow.cpp index 8ad8fafee13..a571ea262fe 100644 --- a/mozilla/widget/src/gtk/nsWindow.cpp +++ b/mozilla/widget/src/gtk/nsWindow.cpp @@ -886,7 +886,22 @@ nsWindow::OnDestroySignal(GtkWidget* aGtkWidget) gint handle_delete_event(GtkWidget *w, GdkEventAny *e, nsWindow *win) { NS_ADDREF(win); - win->Destroy(); + + // dispatch an "onclose" event. to delete immediately, call win->Destroy() + + nsGUIEvent event; + nsEventStatus status; + + event.message = NS_XUL_CLOSE; + event.widget = win; + event.eventStructType = NS_GUI_EVENT; + + event.time = 0; + event.point.x = 0; + event.point.y = 0; + + win->DispatchEvent(&event, status); + NS_RELEASE(win); return TRUE; } diff --git a/mozilla/widget/src/mac/nsMacEventHandler.cpp b/mozilla/widget/src/mac/nsMacEventHandler.cpp index 8308fcf74ba..382be637fb3 100644 --- a/mozilla/widget/src/mac/nsMacEventHandler.cpp +++ b/mozilla/widget/src/mac/nsMacEventHandler.cpp @@ -87,6 +87,26 @@ nsMacEventDispatchHandler::~nsMacEventDispatchHandler() } } +//------------------------------------------------------------------------- +// +//------------------------------------------------------------------------- +void nsMacEventDispatchHandler::DispatchGuiEvent(PRUint32 aEventType) +{ + if (mActiveWidget) + { + nsGUIEvent guiEvent; + guiEvent.eventStructType = NS_GUI_EVENT; + guiEvent.point.x = 0; + guiEvent.point.y = 0; + guiEvent.time = PR_IntervalNow(); + guiEvent.widget = nsnull; + guiEvent.nativeMsg = nsnull; + guiEvent.message = aEventType; + guiEvent.widget = mActiveWidget; + mActiveWidget->DispatchWindowEvent(guiEvent); + } +} + //------------------------------------------------------------------------- // //------------------------------------------------------------------------- @@ -96,22 +116,11 @@ void nsMacEventDispatchHandler::SetFocus(nsWindow *aFocusedWidget) if (aFocusedWidget == mActiveWidget) return; - nsGUIEvent guiEvent; - guiEvent.eventStructType = NS_GUI_EVENT; - guiEvent.point.x = 0; - guiEvent.point.y = 0; - guiEvent.time = PR_IntervalNow(); - guiEvent.widget = nsnull; - guiEvent.nativeMsg = nsnull; - // tell the old widget it is not focused if (mActiveWidget) { mActiveWidget->RemoveDeleteObserver(this); - - guiEvent.message = NS_LOSTFOCUS; - guiEvent.widget = mActiveWidget; - mActiveWidget->DispatchWindowEvent(guiEvent); + DispatchGuiEvent(NS_LOSTFOCUS); } mActiveWidget = aFocusedWidget; @@ -120,10 +129,7 @@ void nsMacEventDispatchHandler::SetFocus(nsWindow *aFocusedWidget) if (mActiveWidget) { mActiveWidget->AddDeleteObserver(this); - - guiEvent.message = NS_GOTFOCUS; - guiEvent.widget = mActiveWidget; - mActiveWidget->DispatchWindowEvent(guiEvent); + DispatchGuiEvent(NS_GOTFOCUS); } } @@ -141,18 +147,7 @@ void nsMacEventDispatchHandler::SetActivated(nsWindow *aActivatedWidget) if (mActiveWidget) { mActiveWidget->AddDeleteObserver(this); - - // Dispatch an NS_ACTIVATE event - nsGUIEvent guiEvent; - guiEvent.eventStructType = NS_GUI_EVENT; - guiEvent.point.x = 0; - guiEvent.point.y = 0; - guiEvent.time = PR_IntervalNow(); - guiEvent.widget = nsnull; - guiEvent.nativeMsg = nsnull; - guiEvent.message = NS_ACTIVATE; - guiEvent.widget = mActiveWidget; - mActiveWidget->DispatchWindowEvent(guiEvent); + DispatchGuiEvent(NS_ACTIVATE); } } @@ -164,18 +159,7 @@ void nsMacEventDispatchHandler::SetDeactivated(nsWindow *aDeactivatedWidget) // let the old one know it lost activation if (mActiveWidget) { - // Dispatch an NS_DEACTIVATE event - nsGUIEvent guiEvent; - guiEvent.eventStructType = NS_GUI_EVENT; - guiEvent.point.x = 0; - guiEvent.point.y = 0; - guiEvent.time = PR_IntervalNow(); - guiEvent.widget = nsnull; - guiEvent.nativeMsg = nsnull; - guiEvent.message = NS_DEACTIVATE; - guiEvent.widget = mActiveWidget; - mActiveWidget->DispatchWindowEvent(guiEvent); - + DispatchGuiEvent(NS_DEACTIVATE); mActiveWidget->RemoveDeleteObserver(this); mActiveWidget = nsnull; } @@ -372,7 +356,7 @@ PRBool nsMacEventHandler::HandleMenuCommand( menuEvent.nativeMsg = (void*)&aOSEvent; // nsMenuEvent - menuEvent.mMenuItem = nsnull; //¥TODO: initialize mMenuItem + menuEvent.mMenuItem = nsnull; //€TODO: initialize mMenuItem menuEvent.mCommand = aMenuResult; // dispatch the menu event @@ -421,7 +405,7 @@ PRBool nsMacEventHandler::HandleMenuCommand( // for processing. Create a Gecko event (using the appropriate message type) and pass // it along. // -// ¥¥¥THIS REALLY NEEDS TO BE CLEANED UP! TOO MUCH CODE COPIED FROM ConvertOSEventToMouseEvent +// €€€THIS REALLY NEEDS TO BE CLEANED UP! TOO MUCH CODE COPIED FROM ConvertOSEventToMouseEvent // PRBool nsMacEventHandler::DragEvent ( unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers ) { @@ -986,7 +970,7 @@ PRBool nsMacEventHandler::HandleActivateEvent(EventRecord& aOSEvent) (err==noErr)?"":"ERROR", err); #endif - //¥TODO: we should restore the focus to the the widget + //€TODO: we should restore the focus to the the widget // that had it when the window was deactivated nsWindow* focusedWidget = mTopLevelWidget; gEventDispatchHandler.SetActivated(focusedWidget); @@ -999,7 +983,7 @@ PRBool nsMacEventHandler::HandleActivateEvent(EventRecord& aOSEvent) } else { - //¥TODO: if the focusedWidget doesn't have a menubar, + //€TODO: if the focusedWidget doesn't have a menubar, // look all the way up to the window // until one of the parents has a menubar } @@ -1103,7 +1087,8 @@ PRBool nsMacEventHandler::HandleMouseDownEvent( if (nsnull != gRollupListener && (nsnull != gRollupWidget) ) { gRollupListener->Rollup(); } - mTopLevelWidget->Destroy(); + gEventDispatchHandler.DispatchGuiEvent(NS_XUL_CLOSE); +// mTopLevelWidget->Destroy(); break; } diff --git a/mozilla/widget/src/mac/nsMacEventHandler.h b/mozilla/widget/src/mac/nsMacEventHandler.h index 69a94c6946a..c0d7d5d9181 100644 --- a/mozilla/widget/src/mac/nsMacEventHandler.h +++ b/mozilla/widget/src/mac/nsMacEventHandler.h @@ -45,6 +45,8 @@ public: nsMacEventDispatchHandler(); virtual ~nsMacEventDispatchHandler(); + void DispatchGuiEvent(PRUint32 aEventType); + void SetFocus(nsWindow *aFocusedWidget); void SetActivated(nsWindow *aActiveWidget); diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index ed70d90914c..6e564b70704 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -2469,6 +2469,11 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT } break; + case WM_CLOSE: // close request + DispatchStandardEvent(NS_XUL_CLOSE); + result = PR_TRUE; // abort window closure + break; + case WM_DESTROY: // clean up. OnDestroy(); diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp index b610a003ba0..3a7f5f2b066 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp @@ -479,6 +479,15 @@ nsWebShellWindow::HandleEvent(nsGUIEvent *aEvent) result = nsEventStatus_eConsumeNoDefault; break; } + case NS_XUL_CLOSE: { + void* data; + nsWebShellWindow *win; + aEvent->widget->GetClientData(data); + win = NS_REINTERPRET_CAST(nsWebShellWindow *, data); + if (!win->ExecuteCloseHandler()) + win->Close(); + break; + } /* * Notify the ApplicationShellService that the window is being closed... */ @@ -1123,8 +1132,7 @@ nsWebShellWindow::ConvertWebShellToDOMWindow(nsIWebShell* aShell, nsIDOMWindow** nsCOMPtr newDOMWindow; newContextOwner = do_QueryInterface(aShell); - if (newContextOwner) - { + if (newContextOwner) { if (NS_FAILED(rv = newContextOwner->GetScriptGlobalObject(getter_AddRefs(newGlobalObject)))) { NS_ERROR("Unable to retrieve global object."); return rv; @@ -2398,6 +2406,48 @@ void nsWebShellWindow::LoadContentAreas() { } } +/** + * ExecuteCloseHandler - Run the close handler, if any. + * @return PR_TRUE iff we found a close handler to run. + */ +PRBool nsWebShellWindow::ExecuteCloseHandler() +{ + /* If the event handler closes this window -- a likely scenario -- + things get deleted out of order without this death grip. + (The problem may be the death grip in nsWindow::windowProc, + which forces this window's widget to remain alive longer + than it otherwise would.) */ + nsCOMPtr kungFuDeathGrip(this); + + nsresult rv; + nsCOMPtr contextOwner; + nsCOMPtr globalObject; + + contextOwner = do_QueryInterface(mWebShell); + if (contextOwner) { + if (NS_SUCCEEDED(contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject))) && globalObject) { + nsCOMPtr contentViewer; + if (NS_SUCCEEDED(mWebShell->GetContentViewer(getter_AddRefs(contentViewer)))) { + nsCOMPtr docViewer; + nsCOMPtr presContext; + docViewer = do_QueryInterface(contentViewer); + if (NS_SUCCEEDED(docViewer->GetPresContext(*getter_AddRefs(presContext)))) { + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_XUL_CLOSE; + rv = globalObject->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + if (NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault) + return PR_TRUE; + // else fall through and return PR_FALSE + } + } + } + } + + return PR_FALSE; +} // ExecuteCloseHandler + //---------------------------------------------------------------- //-- nsIDocumentObserver //---------------------------------------------------------------- diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.h b/mozilla/xpfe/appshell/src/nsWebShellWindow.h index 137cda8574c..8ed248d43c3 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.h +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.h @@ -268,6 +268,7 @@ protected: void SetTitleFromXUL(); void ShowAppropriateChrome(); void LoadContentAreas(); + PRBool ExecuteCloseHandler(); virtual ~nsWebShellWindow();