hooking up 'close' xul event handler. bug 13695. r:hyatt@netscape.com

This commit is contained in:
danm%netscape.com 1999-12-01 22:38:06 +00:00
Родитель d25d8e587a
Коммит 8597b304fe
6 изменённых файлов: 106 добавлений и 48 удалений

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

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

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

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

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

@ -45,6 +45,8 @@ public:
nsMacEventDispatchHandler();
virtual ~nsMacEventDispatchHandler();
void DispatchGuiEvent(PRUint32 aEventType);
void SetFocus(nsWindow *aFocusedWidget);
void SetActivated(nsWindow *aActiveWidget);

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

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

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

@ -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<nsIDOMWindow> 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<nsIWebShellWindow> kungFuDeathGrip(this);
nsresult rv;
nsCOMPtr<nsIScriptContextOwner> contextOwner;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
contextOwner = do_QueryInterface(mWebShell);
if (contextOwner) {
if (NS_SUCCEEDED(contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject))) && globalObject) {
nsCOMPtr<nsIContentViewer> contentViewer;
if (NS_SUCCEEDED(mWebShell->GetContentViewer(getter_AddRefs(contentViewer)))) {
nsCOMPtr<nsIDocumentViewer> docViewer;
nsCOMPtr<nsIPresContext> 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
//----------------------------------------------------------------

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

@ -268,6 +268,7 @@ protected:
void SetTitleFromXUL();
void ShowAppropriateChrome();
void LoadContentAreas();
PRBool ExecuteCloseHandler();
virtual ~nsWebShellWindow();