diff --git a/xpfe/AppCores/src/nsBrowserAppCore.cpp b/xpfe/AppCores/src/nsBrowserAppCore.cpp index c6b2c6d0be6..904cddbe3c5 100644 --- a/xpfe/AppCores/src/nsBrowserAppCore.cpp +++ b/xpfe/AppCores/src/nsBrowserAppCore.cpp @@ -1787,14 +1787,11 @@ nsBrowserAppCore::ExecuteScript(nsIScriptContext * aContext, const nsString& aSc - NS_IMETHODIMP nsBrowserAppCore::DoDialog() { - /* (adapted from nsToolkitCore. No one's using this function, are they!?) - */ + // (adapted from nsToolkitCore) nsresult rv; - nsIAppShellService *appShell; nsIWebShellWindow *window; window = nsnull; @@ -1804,19 +1801,11 @@ nsBrowserAppCore::DoDialog() if (NS_FAILED(rv)) return rv; - rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID, - (nsISupports**) &appShell); + NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv); if (NS_FAILED(rv)) return rv; - appShell->CreateDialogWindow(mWebShellWin, urlObj, PR_TRUE, window, - nsnull, nsnull, 615, 480); - nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); -// window->Resize(300, 200, PR_TRUE); (until Resize gets moved into nsIWebShellWindow) - - if (window != nsnull) - window->ShowModal(); - + rv = appShell->RunModalDialog(mWebShellWin, urlObj, window, nsnull, nsnull, 300, 200); return rv; } diff --git a/xpfe/AppCores/src/nsToolkitCore.cpp b/xpfe/AppCores/src/nsToolkitCore.cpp index 5f3c4c176f5..20ee14ffb1b 100644 --- a/xpfe/AppCores/src/nsToolkitCore.cpp +++ b/xpfe/AppCores/src/nsToolkitCore.cpp @@ -43,7 +43,6 @@ class nsIScriptContext; static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID); -static NS_DEFINE_IID(kIAppShellServiceIID, NS_IAPPSHELL_SERVICE_IID); static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID); @@ -142,7 +141,6 @@ NS_IMETHODIMP nsToolkitCore::ShowDialog(const nsString& aUrl, nsIDOMWindow* aParent) { nsresult rv; - nsIAppShellService *appShell; nsIWebShellWindow *window; window = nsnull; @@ -152,8 +150,7 @@ nsToolkitCore::ShowDialog(const nsString& aUrl, nsIDOMWindow* aParent) { if (NS_FAILED(rv)) return rv; - rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID, - (nsISupports**) &appShell); + NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv); if (NS_FAILED(rv)) return rv; @@ -161,7 +158,6 @@ nsToolkitCore::ShowDialog(const nsString& aUrl, nsIDOMWindow* aParent) { DOMWindowToWebShellWindow(aParent, &parent); appShell->CreateDialogWindow(parent, urlObj, PR_TRUE, window, nsnull, nsnull, 615, 480); - nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); if (window != nsnull) window->Show(PR_TRUE); @@ -173,7 +169,6 @@ NS_IMETHODIMP nsToolkitCore::ShowWindow(const nsString& aUrl, nsIDOMWindow* aParent) { nsresult rv; - nsIAppShellService *appShell; nsIWebShellWindow *window; window = nsnull; @@ -183,8 +178,7 @@ nsToolkitCore::ShowWindow(const nsString& aUrl, nsIDOMWindow* aParent) { if (NS_FAILED(rv)) return rv; - rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID, - (nsISupports**) &appShell); + NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv); if (NS_FAILED(rv)) return rv; @@ -192,7 +186,6 @@ nsToolkitCore::ShowWindow(const nsString& aUrl, nsIDOMWindow* aParent) { DOMWindowToWebShellWindow(aParent, &parent); appShell->CreateTopLevelWindow(parent, urlObj, PR_TRUE, window, nsnull, nsnull, 615, 480); - nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); if (window != nsnull) window->Show(PR_TRUE); @@ -284,7 +277,6 @@ nsToolkitCore::ShowWindowWithArgs(const nsString& aUrl, const nsString& aArgs) { nsresult rv; - nsIAppShellService *appShell; nsIWebShellWindow *window; window = nsnull; @@ -294,8 +286,7 @@ nsToolkitCore::ShowWindowWithArgs(const nsString& aUrl, if (NS_FAILED(rv)) return rv; - rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID, - (nsISupports**) &appShell); + NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv); if (NS_FAILED(rv)) return rv; @@ -305,7 +296,6 @@ nsToolkitCore::ShowWindowWithArgs(const nsString& aUrl, cb = nsDontQueryInterface( new nsArgCallbacks( aArgs ) ); appShell->CreateTopLevelWindow(parent, urlObj, PR_TRUE, window, nsnull, cb, 615, 650); - nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); if (window != nsnull) window->Show(PR_TRUE); @@ -317,7 +307,6 @@ NS_IMETHODIMP nsToolkitCore::ShowModalDialog(const nsString& aUrl, nsIDOMWindow* aParent) { nsresult rv; - nsIAppShellService *appShell; nsIWebShellWindow *window; window = nsnull; @@ -327,50 +316,13 @@ nsToolkitCore::ShowModalDialog(const nsString& aUrl, nsIDOMWindow* aParent) { if (NS_FAILED(rv)) return rv; - rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID, - (nsISupports**) &appShell); + NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv); if (NS_FAILED(rv)) return rv; - // First push a nested event queue for event processing from netlib - // onto our UI thread queue stack. - nsIEventQueueService *eQueueService; - nsCOMPtr innerQueue; - if (NS_FAILED(rv = nsServiceManager::GetService(kEventQueueServiceCID, - kIEventQueueServiceIID, - (nsISupports **)&eQueueService))) { - NS_ERROR("Unable to obtain queue service."); - return rv; - } - -#ifdef XP_WIN32 // XXX: Won't work with any other platforms yet. - eQueueService->PushThreadEventQueue(); -#endif // XP_WIN32 - nsCOMPtr parent; DOMWindowToWebShellWindow(aParent, &parent); - appShell->CreateDialogWindow(parent, urlObj, PR_TRUE, window, - nsnull, nsnull, 615, 480); - nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); - - if (window != nsnull) { - nsCOMPtr parentWindowWidgetThing; - nsresult gotParent; - gotParent = parent ? parent->GetWidget(*getter_AddRefs(parentWindowWidgetThing)) : - NS_ERROR_FAILURE; - // Windows OS is the only one that needs the parent disabled, or cares - // arguably this should be done by the new window, within ShowModal... - if (NS_SUCCEEDED(gotParent)) - parentWindowWidgetThing->Enable(PR_FALSE); - window->ShowModal(); // XXX This method pops the queue itself. Ugh. There should really be one - // call for all of this. - if (NS_SUCCEEDED(gotParent)) - parentWindowWidgetThing->Enable(PR_TRUE); - } - - // Release the event queue - nsServiceManager::ReleaseService(kEventQueueServiceCID, eQueueService); - + rv = appShell->RunModalDialog(parent, urlObj, window, nsnull, nsnull, 615, 480); return rv; } @@ -390,8 +342,9 @@ void nsToolkitCore::DOMWindowToWebShellWindow( nsIDOMWindow *DOMWindow, nsCOMPtr *webWindow) const { + *webWindow = 0; if (!DOMWindow) - return; // with webWindow unchanged -- its constructor gives it a null ptr + return; nsCOMPtr globalScript(do_QueryInterface(DOMWindow)); nsCOMPtr webshell, rootWebshell; diff --git a/xpfe/appshell/public/nsIAppShellService.h b/xpfe/appshell/public/nsIAppShellService.h index da1257ac963..af00552d2ef 100644 --- a/xpfe/appshell/public/nsIAppShellService.h +++ b/xpfe/appshell/public/nsIAppShellService.h @@ -59,6 +59,11 @@ public: nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver, nsIXULWindowCallbacks *aCallbacks, PRInt32 aInitialWidth, PRInt32 aInitialHeight) = 0; + NS_IMETHOD RunModalDialog( nsIWebShellWindow * aParent, + nsIURL* aUrl, + nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver, + nsIXULWindowCallbacks *aCallbacks, + PRInt32 aInitialWidth, PRInt32 aInitialHeight) = 0; NS_IMETHOD CloseTopLevelWindow(nsIWebShellWindow* aWindow) = 0; NS_IMETHOD RegisterTopLevelWindow(nsIWebShellWindow* aWindow) = 0; NS_IMETHOD UnregisterTopLevelWindow(nsIWebShellWindow* aWindow) = 0; diff --git a/xpfe/appshell/src/nsAppShellService.cpp b/xpfe/appshell/src/nsAppShellService.cpp index 54d2a88f6c2..f306d0a62b3 100644 --- a/xpfe/appshell/src/nsAppShellService.cpp +++ b/xpfe/appshell/src/nsAppShellService.cpp @@ -90,6 +90,11 @@ public: nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver, nsIXULWindowCallbacks *aCallbacks, PRInt32 aInitialWidth, PRInt32 aInitialHeight); + NS_IMETHOD RunModalDialog( nsIWebShellWindow * aParent, + nsIURL* aUrl, + nsIWebShellWindow*& aResult, nsIStreamObserver* anObserver, + nsIXULWindowCallbacks *aCallbacks, + PRInt32 aInitialWidth, PRInt32 aInitialHeight); NS_IMETHOD CloseTopLevelWindow(nsIWebShellWindow* aWindow); NS_IMETHOD RegisterTopLevelWindow(nsIWebShellWindow* aWindow); NS_IMETHOD UnregisterTopLevelWindow(nsIWebShellWindow* aWindow); @@ -322,6 +327,62 @@ nsAppShellService::CreateDialogWindow(nsIWebShellWindow * aParent, } +/* CreateDialogWindow, run it modally, and destroy it. To make initial control + settings or get information out of the dialog before dismissal, use + event handlers. This wrapper method is desirable because of the + complications creeping in to the modal window story: there's a lot of setup. + See the code. +*/ +NS_IMETHODIMP +nsAppShellService::RunModalDialog( + nsIWebShellWindow *aParent, nsIURL* aUrl, + nsIWebShellWindow*& aResult, nsIStreamObserver *anObserver, + nsIXULWindowCallbacks *aCallbacks, + PRInt32 aInitialWidth, PRInt32 aInitialHeight) +{ + + nsresult rv; + nsIWebShellWindow *window; + + window = nsnull; + +#ifdef XP_PC // XXX: Won't work with any other platforms yet. + // First push a nested event queue for event processing from netlib + // onto our UI thread queue stack. + // nsCOMPtr innerQueue; + NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv); + if (NS_FAILED(rv)) { + NS_ERROR("RunModalDialog unable to obtain eventqueue service."); + return rv; + } + eQueueService->PushThreadEventQueue(); +#endif + + rv = CreateDialogWindow(aParent, aUrl, PR_TRUE, window, anObserver, nsnull, + aInitialWidth, aInitialHeight); + + if (NS_SUCCEEDED(rv)) { + nsCOMPtr parentWindowWidgetThing; + nsresult gotParent; + gotParent = aParent ? aParent->GetWidget(*getter_AddRefs(parentWindowWidgetThing)) : + NS_ERROR_FAILURE; + // Windows OS wants the parent disabled for modality + if (NS_SUCCEEDED(gotParent)) + parentWindowWidgetThing->Enable(PR_FALSE); + window->ShowModal(); + if (NS_SUCCEEDED(gotParent)) + parentWindowWidgetThing->Enable(PR_TRUE); + } + + // Release the event queue +#ifdef XP_PC // XXX Won't work on other platforms yet + eQueueService->PopThreadEventQueue(); +#endif + + return rv; +} + + /* * Register a new top level window (created elsewhere) */ diff --git a/xpfe/appshell/src/nsWebShellWindow.cpp b/xpfe/appshell/src/nsWebShellWindow.cpp index 288df21ada9..79ecef7f064 100644 --- a/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/xpfe/appshell/src/nsWebShellWindow.cpp @@ -899,45 +899,37 @@ NS_IMETHODIMP nsWebShellWindow::NewWebShell(PRUint32 aChromeMask, PRBool aVisible, nsIWebShell *&aNewWebShell) { -#ifdef XP_WIN32 // XXX: Won't work on any other platforms yet. Sigh. - // We need to create a new top level window and then enter a nested - // loop. Eventually the new window will be told that it has loaded, - // at which time we know it is safe to spin out of the nested loop - // and allow the opening code to proceed. +#ifdef XP_PC // XXX: Won't work on any other platforms yet. Sigh. + // We need to create a new top level window and then enter a nested + // loop. Eventually the new window will be told that it has loaded, + // at which time we know it is safe to spin out of the nested loop + // and allow the opening code to proceed. - // First push a nested event queue for event processing from netlib - // onto our UI thread queue stack. - nsresult rv; - nsIAppShellService *appShell; - nsIEventQueueService *eQueueService; - nsCOMPtr outerQueue; - nsCOMPtr innerQueue; - if (NS_FAILED(rv = nsServiceManager::GetService(kEventQueueServiceCID, - kIEventQueueServiceIID, - (nsISupports **)&eQueueService))) { - NS_ERROR("Unable to obtain queue service."); - return rv; - } - - eQueueService->PushThreadEventQueue(); + // First push a nested event queue for event processing from netlib + // onto our UI thread queue stack. + nsresult rv; + NS_WITH_SERVICE(nsIEventQueueService, eQueueService, kEventQueueServiceCID, &rv); + if (NS_FAILED(rv)) { + NS_ERROR("Unable to obtain queue service."); + return rv; + } + eQueueService->PushThreadEventQueue(); nsCOMPtr urlObj; rv = NS_NewURL(getter_AddRefs(urlObj), "chrome://navigator/content/"); if (NS_FAILED(rv)) return rv; - rv = nsServiceManager::GetService(kAppShellServiceCID, kIAppShellServiceIID, - (nsISupports**) &appShell); + NS_WITH_SERVICE(nsIAppShellService, appShell, kAppShellServiceCID, &rv); if (NS_FAILED(rv)) return rv; - nsCOMPtr newWindow; + nsCOMPtr newWindow; appShell->CreateTopLevelWindow(nsnull, urlObj, PR_FALSE, *getter_AddRefs(newWindow), nsnull, nsnull, 615, 480); - nsServiceManager::ReleaseService(kAppShellServiceCID, appShell); - // Spin into the modal loop. - nsIAppShell *subshell; + // Spin into the modal loop. + nsIAppShell *subshell; rv = nsComponentManager::CreateInstance(kAppShellCID, nsnull, kIAppShellIID, (void**)&subshell); if (NS_FAILED(rv)) return rv; @@ -946,10 +938,10 @@ nsWebShellWindow::NewWebShell(PRUint32 aChromeMask, PRBool aVisible, subshell->Spinup(); // Spin up // Specify that we want the window to remain locked until the chrome has loaded. - newWindow->LockUntilChromeLoad(); + newWindow->LockUntilChromeLoad(); - PRBool locked = PR_FALSE; - newWindow->GetLockedState(locked); + PRBool locked = PR_FALSE; + newWindow->GetLockedState(locked); while (NS_SUCCEEDED(rv) && locked) { void *data; PRBool isRealEvent; @@ -957,25 +949,24 @@ nsWebShellWindow::NewWebShell(PRUint32 aChromeMask, PRBool aVisible, rv = subshell->GetNativeEvent(isRealEvent, data); subshell->DispatchNativeEvent(isRealEvent, data); - newWindow->GetLockedState(locked); + newWindow->GetLockedState(locked); } - // Get rid of the nested UI thread queue used for netlib, and release the event queue service. - eQueueService->PopThreadEventQueue(); - nsServiceManager::ReleaseService(kEventQueueServiceCID, eQueueService); + // Get rid of the nested UI thread queue used for netlib, and release the event queue service. + eQueueService->PopThreadEventQueue(); subshell->Spindown(); NS_RELEASE(subshell); - // We're out of the nested loop. + // We're out of the nested loop. // During the layout of the new window, all content shells were located and placed - // into the new window's content shell array. Locate the "content area" content - // shell. - if (NS_FAILED(rv = newWindow->GetContentShellById("content", &aNewWebShell))) { - NS_ERROR("Unable to obtain a browser content shell."); - return rv; - } -#endif // XP_WIN32 + // into the new window's content shell array. Locate the "content area" content + // shell. + if (NS_FAILED(rv = newWindow->GetContentShellById("content", &aNewWebShell))) { + NS_ERROR("Unable to obtain a browser content shell."); + return rv; + } +#endif // XP_PC return NS_OK; } @@ -1031,9 +1022,6 @@ nsWebShellWindow::ShowModal() NS_IMETHODIMP nsWebShellWindow::ShowModalInternal() { - // XXX This sucks right now. The pushing of an event queue has to happen outside of this function - // before the CreateTopLevelWindow, and the popping has to happen here. This really needs to all be - // pulled out into a new function so that the flow can be cleaner. nsresult rv; nsIAppShell *subshell; @@ -1042,14 +1030,6 @@ nsWebShellWindow::ShowModalInternal() if (NS_FAILED(rv)) return rv; - nsIEventQueueService *eQueueService; - if (NS_FAILED(rv = nsServiceManager::GetService(kEventQueueServiceCID, - kIEventQueueServiceIID, - (nsISupports **)&eQueueService))) { - NS_ERROR("Unable to obtain queue service."); - return rv; - } - subshell->Create(0, nsnull); subshell->Spinup(); @@ -1069,16 +1049,10 @@ nsWebShellWindow::ShowModalInternal() } } -#ifdef XP_WIN32 // XXX Won't work on other platforms yet - eQueueService->PopThreadEventQueue(); -#endif // XP_WIN32 - subshell->Spindown(); NS_RELEASE(window); NS_RELEASE(subshell); - nsServiceManager::ReleaseService(kEventQueueServiceCID, eQueueService); - return rv; }