moving modal dialog code to one central location, where things won't be allocated and released in separate methods

This commit is contained in:
danm%netscape.com 1999-05-10 18:31:42 +00:00
Родитель 70e2ddfa1f
Коммит 2177440c9e
5 изменённых файлов: 108 добавлений и 126 удалений

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

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

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

@ -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<nsArgCallbacks>( 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<nsIEventQueue> 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<nsIWebShellWindow> parent;
DOMWindowToWebShellWindow(aParent, &parent);
appShell->CreateDialogWindow(parent, urlObj, PR_TRUE, window,
nsnull, nsnull, 615, 480);
nsServiceManager::ReleaseService(kAppShellServiceCID, appShell);
if (window != nsnull) {
nsCOMPtr<nsIWidget> 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<nsIWebShellWindow> *webWindow) const {
*webWindow = 0;
if (!DOMWindow)
return; // with webWindow unchanged -- its constructor gives it a null ptr
return;
nsCOMPtr<nsIScriptGlobalObject> globalScript(do_QueryInterface(DOMWindow));
nsCOMPtr<nsIWebShell> webshell, rootWebshell;

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

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

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

@ -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<nsIEventQueue> 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<nsIWidget> 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)
*/

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

@ -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<nsIEventQueue> outerQueue;
nsCOMPtr<nsIEventQueue> 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<nsIURL> 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<nsIWebShellWindow> newWindow;
nsCOMPtr<nsIWebShellWindow> 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;
}