diff --git a/mozilla/xpfe/appshell/public/nsINativeAppSupport.idl b/mozilla/xpfe/appshell/public/nsINativeAppSupport.idl index 6305162bf01..48915973806 100644 --- a/mozilla/xpfe/appshell/public/nsINativeAppSupport.idl +++ b/mozilla/xpfe/appshell/public/nsINativeAppSupport.idl @@ -121,11 +121,17 @@ * invoking the Hide() method on the nsISplashScreen * interface maintained by the app shell service. * - * cacheBrowserWindow - Takes an about-to-be-closed navigator window - * and "caches it" for later use. It returns an - * indicator of whether the window was actually - * cached. If that result is false, then the - * caller should close the window normally. + * startServerMode - Method that "starts" server mode. Typically, this + * will create a hidden Navigator window (and then close + * it) in order to fill the cache, load shared libraries, + * etc. Note that this method does not set the + * isServerMode attribute, nor does setting that attribute + * "start" server mode (at least in the same sense as is + * meant by this method). Basically, native code will + * set isServerMode to tell nsAppRunner; nsAppRunner will + * then call this method (implemented back in the same + * native code) at the appropriate time for any additional + * server-mode startup to be completed. * * This interface has these attributes: * isServerMode - Boolean attribute indicating whether the application @@ -154,5 +160,5 @@ interface nsINativeAppSupport : nsISupports { // Server mode. attribute boolean isServerMode; - boolean cacheBrowserWindow(in nsIDOMWindow aWindow); + void startServerMode(); }; diff --git a/mozilla/xpfe/appshell/src/nsAppShellService.cpp b/mozilla/xpfe/appshell/src/nsAppShellService.cpp index 9f802af489b..40f80f74fac 100644 --- a/mozilla/xpfe/appshell/src/nsAppShellService.cpp +++ b/mozilla/xpfe/appshell/src/nsAppShellService.cpp @@ -810,7 +810,16 @@ nsAppShellService::UnregisterTopLevelWindow(nsIXULWindow* aWindow) if (!hiddenWin) Quit(); #else - Quit(); + // Check to see if we're in server mode, first. + if ( mNativeAppSupport ) { + PRBool serverMode = PR_FALSE; + mNativeAppSupport->GetIsServerMode( &serverMode ); + if ( serverMode ) { + // Then don't quit. + return NS_OK; + } + } + Quit(); #endif } return rv; diff --git a/mozilla/xpfe/bootstrap/nsAppRunner.cpp b/mozilla/xpfe/bootstrap/nsAppRunner.cpp index f6a38ac571a..ae33b0432ce 100644 --- a/mozilla/xpfe/bootstrap/nsAppRunner.cpp +++ b/mozilla/xpfe/bootstrap/nsAppRunner.cpp @@ -256,8 +256,7 @@ static nsresult OpenWindow(const char *urlstr, const PRUnichar *args) static nsresult OpenChromeURL( const char * urlstr, PRInt32 height = NS_SIZETOCONTENT, - PRInt32 width = NS_SIZETOCONTENT, - nsIDOMWindow **aResult = nsnull ) + PRInt32 width = NS_SIZETOCONTENT ) { #ifdef DEBUG_CMD_LINE printf("OpenChromeURL(%s,%d,%d)\n",urlstr,height,width); @@ -278,20 +277,6 @@ OpenChromeURL( const char * urlstr, nsIWebBrowserChrome::CHROME_ALL, width, height, getter_AddRefs(newWindow)); - // Check if caller wants resulting window. - if(aResult) { - // Always return 0 if we don't have a window. - *aResult = nsnull; - // If window open was OK, then pass result as nsIDOMWindow. - if (NS_SUCCEEDED(rv) && newWindow) { - nsCOMPtr docShell; - if (NS_SUCCEEDED(newWindow->GetDocShell(getter_AddRefs(docShell)))) { - nsCOMPtr newDOMWin = do_GetInterface(docShell); - *aResult = newDOMWin; - NS_IF_ADDREF(*aResult); - } - } - } return rv; } @@ -636,7 +621,7 @@ static nsresult DoOnShutdown() } -static nsresult OpenBrowserWindow(PRInt32 height, PRInt32 width, nsIDOMWindow **aResult) +static nsresult OpenBrowserWindow(PRInt32 height, PRInt32 width) { nsresult rv; nsCOMPtr handler(do_GetService(NS_BROWSERSTARTUPHANDLER_CONTRACTID, &rv)); @@ -646,7 +631,7 @@ static nsresult OpenBrowserWindow(PRInt32 height, PRInt32 width, nsIDOMWindow ** rv = handler->GetChromeUrlForTask(getter_Copies(chromeUrlForTask)); if (NS_FAILED(rv)) return rv; - rv = OpenChromeURL(chromeUrlForTask, height, width, aResult); + rv = OpenChromeURL(chromeUrlForTask, height, width); if (NS_FAILED(rv)) return rv; return rv; @@ -707,6 +692,22 @@ static nsresult Ensure1Window( nsICmdLineService* cmdLineArgs) windowEnumerator->HasMoreElements(&more); if ( !more ) { + // If starting up in server mode, then we do things differently. + nsCOMPtr appShellService(do_GetService(kAppShellServiceCID)); + if (appShellService) { + nsCOMPtr nativeApp; + appShellService->GetNativeAppSupport(getter_AddRefs(nativeApp)); + if (nativeApp) { + PRBool serverMode = PR_FALSE; + nativeApp->GetIsServerMode(&serverMode); + if (serverMode) { + // Create special Nav window. + nativeApp->StartServerMode(); + return NS_OK; + } + } + } + // No window exists so lets create a browser one PRInt32 height = NS_SIZETOCONTENT; PRInt32 width = NS_SIZETOCONTENT; @@ -728,26 +729,7 @@ static nsresult Ensure1Window( nsICmdLineService* cmdLineArgs) if ((const char*)tempString) PR_sscanf(tempString, "%d", &height); - nsCOMPtr browserWin; - rv = OpenBrowserWindow(height, width, getter_AddRefs(browserWin)); - - // See if we're in running in server mode. - if (NS_SUCCEEDED(rv) && browserWin) { - nsCOMPtr appShellService(do_GetService(kAppShellServiceCID)); - if (appShellService) { - nsCOMPtr nativeApp; - appShellService->GetNativeAppSupport(getter_AddRefs(nativeApp)); - if (nativeApp) { - PRBool serverMode = PR_FALSE; - nativeApp->GetIsServerMode(&serverMode); - if (serverMode) { - // Then cache (i.e., hide) this browser window. - PRBool cached = PR_FALSE; - nativeApp->CacheBrowserWindow(browserWin, &cached); - } - } - } - } + rv = OpenBrowserWindow(height, width); } } return rv; diff --git a/mozilla/xpfe/bootstrap/nsNativeAppSupportBase.cpp b/mozilla/xpfe/bootstrap/nsNativeAppSupportBase.cpp index bf42be1a669..a755b6ea48e 100644 --- a/mozilla/xpfe/bootstrap/nsNativeAppSupportBase.cpp +++ b/mozilla/xpfe/bootstrap/nsNativeAppSupportBase.cpp @@ -93,9 +93,7 @@ nsNativeAppSupportBase::GetIsServerMode(PRBool *aIsServerMode) { } NS_IMETHODIMP -nsNativeAppSupportBase::CacheBrowserWindow(nsIDOMWindow *aWindow, PRBool *aResult) { - NS_ENSURE_ARG( aResult ); - *aResult = PR_FALSE; +nsNativeAppSupportBase::StartServerMode() { return NS_OK; } diff --git a/mozilla/xpfe/bootstrap/nsNativeAppSupportWin.cpp b/mozilla/xpfe/bootstrap/nsNativeAppSupportWin.cpp index ea63724200d..bcf5a5ba932 100644 --- a/mozilla/xpfe/bootstrap/nsNativeAppSupportWin.cpp +++ b/mozilla/xpfe/bootstrap/nsNativeAppSupportWin.cpp @@ -253,8 +253,7 @@ public: NS_IMETHOD Start( PRBool *aResult ); NS_IMETHOD Stop( PRBool *aResult ); NS_IMETHOD Quit(); - NS_IMETHOD SetIsServerMode( PRBool aIsServerMode ); - NS_IMETHOD CacheBrowserWindow( nsIDOMWindow *aWindow, PRBool *aResult ); + NS_IMETHOD StartServerMode(); // The "old" Start method (renamed). NS_IMETHOD StartDDE(); @@ -280,10 +279,9 @@ private: static PRBool InitTopicStrings(); static int FindTopic( HSZ topic ); static nsresult GetCmdLineArgs( LPBYTE request, nsICmdLineService **aResult ); - static nsresult OpenWindow( const char *urlstr, const char *args, nsIDOMWindow **aResult = 0 ); + static nsresult OpenWindow( const char *urlstr, const char *args ); static nsresult OpenBrowserWindow( const char *args ); - static nsresult ReParent( nsIDOMWindowInternal *window, HWND newParent ); - static nsCOMPtr mCachedWin; + static nsresult ReParent( nsISupports *window, HWND newParent ); static int mConversations; enum { topicOpenURL, @@ -604,7 +602,6 @@ const char * const topicNames[] = { "WWW_OpenURL", "WWW_UnRegisterViewer" }; // Static member definitions. -nsCOMPtr nsNativeAppSupportWin::mCachedWin = 0; int nsNativeAppSupportWin::mConversations = 0; HSZ nsNativeAppSupportWin::mApplication = 0; HSZ nsNativeAppSupportWin::mTopics[nsNativeAppSupportWin::topicCount] = { 0 }; @@ -945,7 +942,7 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t switch ( uType ) { case XTYP_CONNECT: // Make sure its for our service/topic. - if ( FindTopic( hsz1 ) < topicCount ) { + if ( FindTopic( hsz1 ) != -1 ) { // We support this connection. result = (HDDEDATA)1; } @@ -1066,7 +1063,7 @@ nsCString nsNativeAppSupportWin::ParseDDEArg( HSZ args, int index ) { static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); -static HWND hwndForDOMWindow( nsIDOMWindowInternal * ); +static HWND hwndForDOMWindow( nsISupports * ); void nsNativeAppSupportWin::ActivateLastWindow() { nsCOMPtr med( do_GetService( kWindowMediatorCID ) ); @@ -1156,6 +1153,8 @@ nsNativeAppSupportWin::HandleRequest( LPBYTE request ) { NS_SUCCEEDED( appShell->GetNativeAppSupport( getter_AddRefs( native ) ) ) && native ) { native->SetIsServerMode( PR_FALSE ); + // This closes app if there are no top-level windows. + appShell->UnregisterTopLevelWindow( 0 ); } } else { #if MOZ_DEBUG_DDE @@ -1339,14 +1338,10 @@ nsNativeAppSupportWin::GetCmdLineArgs( LPBYTE request, nsICmdLineService **aResu } nsresult -nsNativeAppSupportWin::OpenWindow( const char*urlstr, const char *args, nsIDOMWindow **aResult ) { +nsNativeAppSupportWin::OpenWindow( const char*urlstr, const char *args ) { nsresult rv = NS_ERROR_FAILURE; - if ( aResult ) { - *aResult = 0; - } - nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); nsCOMPtr sarg(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); if (sarg) @@ -1356,11 +1351,6 @@ nsNativeAppSupportWin::OpenWindow( const char*urlstr, const char *args, nsIDOMWi nsCOMPtr newWindow; rv = wwatch->OpenWindow(0, urlstr, "_blank", "chrome,dialog=no,all", sarg, getter_AddRefs(newWindow)); - if ( aResult ) { - // Caller wants resulting window. - *aResult = newWindow; - NS_IF_ADDREF( *aResult ); - } #if MOZ_DEBUG_DDE } else { printf("Get WindowWatcher (or create string) failed\n"); @@ -1388,7 +1378,7 @@ static LRESULT CALLBACK focusFilterProc( HWND hwnd, UINT uMsg, WPARAM wParam, LP } } -HWND hwndForDOMWindow( nsIDOMWindowInternal *window ) { +HWND hwndForDOMWindow( nsISupports *window ) { nsCOMPtr ppScriptGlobalObj( do_QueryInterface(window) ); if ( !ppScriptGlobalObj ) { return 0; @@ -1410,7 +1400,7 @@ HWND hwndForDOMWindow( nsIDOMWindowInternal *window ) { } nsresult -nsNativeAppSupportWin::ReParent( nsIDOMWindowInternal *window, HWND newParent ) { +nsNativeAppSupportWin::ReParent( nsISupports *window, HWND newParent ) { HWND hMainFrame = hwndForDOMWindow( window ); if ( !hMainFrame ) { return NS_ERROR_FAILURE; @@ -1513,14 +1503,6 @@ nsNativeAppSupportWin::OpenBrowserWindow( const char *args ) { if ( !navWin ) { // Have to open a new one. break; - } else { - // Check if we're using the cached (hidden) window. - if ( mCachedWin == navWin ) { - // Drop window from cache. - mCachedWin = 0; - // Show it. - ReParent( navWin, 0 ); - } } // Get content window. navWin->GetContent( getter_AddRefs( content ) ); @@ -1555,33 +1537,56 @@ nsNativeAppSupportWin::OpenBrowserWindow( const char *args ) { return OpenWindow( "chrome://navigator/content", args ); } +// This opens a special browser window for purposes of priming the pump for +// server mode (getting stuff into the caching, loading .dlls, etc.). The +// window will have these attributes: +// - Load about:blank (no home page) +// - No toolbar (so there's no sidebar panels loaded, either) +// - Pass magic arg to cause window to close in onload handler. NS_IMETHODIMP -nsNativeAppSupportWin::SetIsServerMode( PRBool aIsServerMode ) { - // Pas to base class implementation. - nsresult rv = nsNativeAppSupportBase::SetIsServerMode( aIsServerMode ); - if ( NS_SUCCEEDED(rv) && !aIsServerMode && mCachedWin ) { - // Server mode is now off. Discard cached window. - mCachedWin->Close(); - mCachedWin = 0; +nsNativeAppSupportWin::StartServerMode() { + // Create some of the objects we'll need. + nsCOMPtr ww(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + nsCOMPtr arg1(do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID)); + nsCOMPtr arg2(do_CreateInstance(NS_SUPPORTS_WSTRING_CONTRACTID)); + if ( !ww || !arg1 || !arg2 ) { + return NS_OK; } - return rv; -} -NS_IMETHODIMP -nsNativeAppSupportWin::CacheBrowserWindow(nsIDOMWindow *aWindow, PRBool *aResult) { - NS_ENSURE_ARG( aResult ); - *aResult = PR_FALSE; - // Cache this window if we don't already have one. - if ( !mCachedWin ) { - NS_ENSURE_ARG( aWindow ); - nsresult rv = NS_OK; - mCachedWin = do_QueryInterface( aWindow, &rv ); - if ( NS_SUCCEEDED( rv ) ) { - // We cached this window; tell caller so they don't close it. - *aResult = PR_TRUE; - // Re-parent it to hide it. - ReParent( mCachedWin, (HWND)MessageWindow() ); - } + // Create the array for the arguments. + nsCOMPtr argArray; + NS_NewISupportsArray( getter_AddRefs( argArray ) ); + if ( !argArray ) { + return NS_OK; } + + // arg1 is the url to load. + // arg2 is the string that tells navigator.js to auto-close. + arg1->SetData( NS_LITERAL_STRING( "about:blank" ).get() ); + arg2->SetData( NS_LITERAL_STRING( "turbo=yes" ).get() ); + + // Put args into array. + if ( NS_FAILED( argArray->AppendElement( arg1 ) ) || + NS_FAILED( argArray->AppendElement( arg2 ) ) ) { + return NS_OK; + } + + // Now open the window. + nsCOMPtr newWindow; + ww->OpenWindow( 0, + "chrome://navigator/content", + "_blank", + "chrome,dialog=no,toolbar=no", + argArray, + getter_AddRefs( newWindow ) ); + + if ( !newWindow ) { + return NS_OK; + } + + // Hide this window by re-parenting it (to ensure it doesn't appear). + ReParent( newWindow, (HWND)MessageWindow() ); + return NS_OK; } + diff --git a/mozilla/xpfe/browser/resources/content/navigator.js b/mozilla/xpfe/browser/resources/content/navigator.js index 0863a895944..559468a52d5 100644 --- a/mozilla/xpfe/browser/resources/content/navigator.js +++ b/mozilla/xpfe/browser/resources/content/navigator.js @@ -278,6 +278,7 @@ function Startup() contentArea.addEventListener("load", loadEventHandlers, true); contentArea.addEventListener("focus", contentAreaFrameFocus, true); + var turboMode = false; // set default character set if provided if ("arguments" in window && window.arguments.length > 1 && window.arguments[1]) { if (window.arguments[1].indexOf("charset=") != -1) { @@ -286,6 +287,8 @@ function Startup() //we should "inherit" the charset menu setting in a new window appCore.setDefaultCharacterSet(arrayArgComponents[1]); //XXXjag see bug 67442 } + } else if (window.arguments[1].indexOf("turbo=yes") != -1) { + turboMode = true; } } @@ -314,7 +317,7 @@ function Startup() if (!isPageCycling) { var uriToLoad; - if (!appCore.cmdLineURLUsed) { + if (!appCore.cmdLineURLUsed && !turboMode) { var cmdLineService = Components.classes["@mozilla.org/appshell/commandLineService;1"] .getService(Components.interfaces.nsICmdLineService); uriToLoad = cmdLineService.URLToLoad; @@ -337,6 +340,17 @@ function Startup() loadURI(uriToLoad); } + // Close the window now, if it's for turbo mode startup. + if ( turboMode ) { + // Set "command line used" flag. If we don't do this, then when a cmd line url + // for a "real* invocation comes in, we will override it with the "cmd line url" + // from the turbo-mode process (i.e., the home page). + appCore.cmdLineURLUsed = true; + // For some reason, window.close() directly doesn't work, so do it in the future. + window.setTimeout( "window.close()", 100 ); + return; + } + // Focus the content area if the caller instructed us to. if ("arguments" in window && window.arguments.length >= 3 && window.arguments[2] == true) _content.focus(); @@ -364,42 +378,6 @@ function BrowserFlushBookmarksAndHistory() { } } -function BrowserCanClose() { - // Check for "server mode." - try { - var appShellSvc = Components.classes["@mozilla.org/appshell/appShellService;1"] - .getService(Components.interfaces.nsIAppShellService); - var nativeSupport = appShellSvc.nativeAppSupport; - if (nativeSupport && nativeSupport.isServerMode) { - // Give native app a chance to cache this window. - if (nativeSupport.cacheBrowserWindow(window)) { - // Window is "cached" so don't close it. - - // But flush bookmarks and history, as if we did close it. - BrowserFlushBookmarksAndHistory(); - - // Reset session history. - var webNav = getWebNavigation(); - if (webNav) { - try { - webNav.sessionHistory.PurgeHistory( webNav.sessionHistory.count ); - } catch(ex) { - } - } - - // Go to blank page. - loadURI( "about:blank" ); - - // This stops the close. - return false; - } - } - } catch (ex) { - } - // Ok to close window. - return true; -} - function Shutdown() { var browser = getBrowser(); diff --git a/mozilla/xpfe/browser/resources/content/navigator.xul b/mozilla/xpfe/browser/resources/content/navigator.xul index 68c2b087a6b..678838000c7 100644 --- a/mozilla/xpfe/browser/resources/content/navigator.xul +++ b/mozilla/xpfe/browser/resources/content/navigator.xul @@ -45,7 +45,7 @@ Contributor(s): ______________________________________. --> - + diff --git a/mozilla/xpfe/components/startup/public/nsINativeAppSupport.idl b/mozilla/xpfe/components/startup/public/nsINativeAppSupport.idl index 6305162bf01..48915973806 100644 --- a/mozilla/xpfe/components/startup/public/nsINativeAppSupport.idl +++ b/mozilla/xpfe/components/startup/public/nsINativeAppSupport.idl @@ -121,11 +121,17 @@ * invoking the Hide() method on the nsISplashScreen * interface maintained by the app shell service. * - * cacheBrowserWindow - Takes an about-to-be-closed navigator window - * and "caches it" for later use. It returns an - * indicator of whether the window was actually - * cached. If that result is false, then the - * caller should close the window normally. + * startServerMode - Method that "starts" server mode. Typically, this + * will create a hidden Navigator window (and then close + * it) in order to fill the cache, load shared libraries, + * etc. Note that this method does not set the + * isServerMode attribute, nor does setting that attribute + * "start" server mode (at least in the same sense as is + * meant by this method). Basically, native code will + * set isServerMode to tell nsAppRunner; nsAppRunner will + * then call this method (implemented back in the same + * native code) at the appropriate time for any additional + * server-mode startup to be completed. * * This interface has these attributes: * isServerMode - Boolean attribute indicating whether the application @@ -154,5 +160,5 @@ interface nsINativeAppSupport : nsISupports { // Server mode. attribute boolean isServerMode; - boolean cacheBrowserWindow(in nsIDOMWindow aWindow); + void startServerMode(); }; diff --git a/mozilla/xpfe/global/resources/content/globalOverlay.js b/mozilla/xpfe/global/resources/content/globalOverlay.js index 3478fc6466e..a2661bdc092 100644 --- a/mozilla/xpfe/global/resources/content/globalOverlay.js +++ b/mozilla/xpfe/global/resources/content/globalOverlay.js @@ -17,6 +17,24 @@ function goQuitApplication() var windowManager = Components.classes['@mozilla.org/rdf/datasource;1?name=window-mediator'].getService(); var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator); var enumerator = windowManagerInterface.getEnumerator( null ); + var appShell = Components.classes['@mozilla.org/appshell/appShellService;1'].getService(); + appShell = appShell.QueryInterface( Components.interfaces.nsIAppShellService ); + + // Get current server mode setting and turn it off while windows close. + var serverMode = false; + var nativeAppSupport = null; + try + { + nativeAppSupport = appShell.nativeAppSupport; + if ( nativeAppSupport ) + { + serverMode = nativeAppSupport.isServerMode; + nativeAppSupport.isServerMode = false; + } + } + catch ( ex ) + { + } while ( enumerator.hasMoreElements() ) { @@ -31,13 +49,18 @@ function goQuitApplication() { // dump(" try to close \n" ); if ( !domWindow.tryToClose() ) + { + // Restore server mode if it was set on entry. + if ( serverMode ) + { + nativeAppSupport.isServerMode = true; + } return false; + } } }; // call appshell exit - var appShell = Components.classes['@mozilla.org/appshell/appShellService;1'].getService(); - appShell = appShell.QueryInterface( Components.interfaces.nsIAppShellService ); appShell.Quit(); return true; }