Bug 75599; enabling the infamous '-turbo' cmd line switch; makes nsINativeAppSupport scriptable, adds Win32 code to handle -turbo switch; and tweaks window close logic in navigator.js to 'cache' a browser window; r=cathleen, sr=alecf
git-svn-id: svn://10.0.0.236/trunk@95812 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -8,4 +8,3 @@ nsIWebShellWindow.h
|
||||
nsIDOMXPConnectFactory.h
|
||||
nsINetSupportDialogService.h
|
||||
nsISplashScreen.h
|
||||
nsINativeAppSupport.h
|
||||
|
||||
@@ -7,4 +7,5 @@ nsICmdLineService.idl
|
||||
nsIWindowMediator.idl
|
||||
nsIXULWindow.idl
|
||||
nsIUserInfo.idl
|
||||
nsINativeAppSupport.idl
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ EXPORTS = \
|
||||
nsAppShellCIDs.h \
|
||||
nsIDOMXPConnectFactory.h \
|
||||
nsISplashScreen.h \
|
||||
nsINativeAppSupport.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
@@ -45,6 +44,7 @@ XPIDLSRCS = \
|
||||
nsIXULWindow.idl \
|
||||
nsIUserInfo.idl \
|
||||
nsITimingService.idl \
|
||||
nsINativeAppSupport.idl \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),mac)
|
||||
|
||||
@@ -33,13 +33,13 @@ XPIDLSRCS = \
|
||||
.\nsIXULWindow.idl \
|
||||
.\nsIUserInfo.idl \
|
||||
.\nsITimingService.idl \
|
||||
.\nsINativeAppSupport.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsIWebShellWindow.h \
|
||||
nsAppShellCIDs.h \
|
||||
nsISplashScreen.h \
|
||||
nsINativeAppSupport.h \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
@@ -20,15 +20,8 @@
|
||||
* Contributor(s):
|
||||
* Bill Law <law@netscape.com>
|
||||
*/
|
||||
#ifndef nsINativeAppSupport_h__
|
||||
#define nsINativeAppSupport_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsISplashScreen.h"
|
||||
|
||||
// 5fdf8480-1f98-11d4-8077-00600811a9c3
|
||||
#define NS_INATIVEAPPSUPPORT_IID \
|
||||
{ 0x5fdf8480, 0x1f98, 0x11d4, { 0x80, 0x77, 0x00, 0x60, 0x08, 0x11, 0xa9, 0xc3 } }
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/* nsINativeAppSupport
|
||||
*
|
||||
@@ -48,10 +41,15 @@
|
||||
* interface is instantiated by somewhat unconventional means.
|
||||
*
|
||||
* To create the implementor of this interface, you call the function
|
||||
* NS_CreateNativeAppSupport.
|
||||
* NS_CreateNativeAppSupport. This is done in the startup code
|
||||
* in mozilla/xpfe/bootstrap.
|
||||
*
|
||||
* You can use this interface by obtaining an instance via the
|
||||
* "nativeAppSupport" attribute of the nsIAppShellService
|
||||
* interface/service.
|
||||
*
|
||||
* The interface provides these functions:
|
||||
* Start - You call this to inform the native app support that the
|
||||
* start - You call this to inform the native app support that the
|
||||
* application is starting. In addition, it serves as a
|
||||
* query as to whether the application should continue to
|
||||
* run. In that respect, it is rougly equivalent to the
|
||||
@@ -69,7 +67,7 @@
|
||||
* successfully passed to the instance of the
|
||||
* application acting as a DDE server.
|
||||
*
|
||||
* Stop - You call this to inform the native app support that the
|
||||
* stop - You call this to inform the native app support that the
|
||||
* application *wishes* to terminate. If the returned boolean
|
||||
* value is PR_FALSE, then the application should continue
|
||||
* (as if there were still additional top-level windows open).
|
||||
@@ -80,7 +78,7 @@
|
||||
* acting as DDE clients, then this function will
|
||||
* return PR_FALSE.
|
||||
*
|
||||
* Quit - Like Stop, but this method *forces* termination (or more
|
||||
* quit - Like Stop, but this method *forces* termination (or more
|
||||
* precisely, indicates that the application is about to be
|
||||
* terminated regardless of what a call to Stop might have
|
||||
* returned.
|
||||
@@ -112,31 +110,49 @@
|
||||
* is quitting. For this reason, the call to Quit
|
||||
* should be deferred as long as possible.
|
||||
*
|
||||
* ShowSplashScreen - Causes the platform-specific splash screen to be
|
||||
* showSplashScreen - Causes the platform-specific splash screen to be
|
||||
* displayed. This is a replacement for the old
|
||||
* method of invoking the Show() method on the
|
||||
* nsISplashScreen interface obtained by calling
|
||||
* NS_CreateSplashScreen.
|
||||
*
|
||||
* HideSplashScreen - Causes the splash screen to be removed (if it is
|
||||
* hideSplashScreen - Causes the splash screen to be removed (if it is
|
||||
* being shown). This replaces the old method of
|
||||
* 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.
|
||||
*
|
||||
* This interface has these attributes:
|
||||
* isServerMode - Boolean attribute indicating whether the application
|
||||
* is running in "server mode." Server mode means the
|
||||
* application was started to pre-load shared-libraries,
|
||||
* initialize services, and open a hidden Navigator window
|
||||
* in order to quickly surface that window when the user
|
||||
* launches the application in the normal mode. This
|
||||
* mode is currently Win32-only (and may really only make
|
||||
* sense there) and is intended to be initiated from the
|
||||
* Windows startup folder at system initialization.
|
||||
*/
|
||||
class nsINativeAppSupport : public nsISupports {
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR( NS_INATIVEAPPSUPPORT_IID )
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(5fdf8480-1f98-11d4-8077-00600811a9c3)]
|
||||
interface nsINativeAppSupport : nsISupports {
|
||||
// Startup/shutdown.
|
||||
NS_IMETHOD Start( PRBool *result ) = 0;
|
||||
NS_IMETHOD Stop( PRBool *result ) = 0;
|
||||
NS_IMETHOD Quit() = 0;
|
||||
boolean start();
|
||||
boolean stop();
|
||||
void quit();
|
||||
|
||||
// Splash screen functions.
|
||||
NS_IMETHOD ShowSplashScreen() = 0;
|
||||
NS_IMETHOD HideSplashScreen() = 0;
|
||||
void showSplashScreen();
|
||||
void hideSplashScreen();
|
||||
|
||||
}; // class nsINativeAppSupport
|
||||
|
||||
#endif // nsINativeAppSupport_h__
|
||||
// Server mode.
|
||||
attribute boolean isServerMode;
|
||||
boolean cacheBrowserWindow(in nsIDOMWindow aWindow);
|
||||
};
|
||||
@@ -32,6 +32,7 @@
|
||||
//Interfaces Needed
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsISplashScreen.h"
|
||||
|
||||
class nsAppShellService : public nsIAppShellService,
|
||||
public nsIObserver,
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
// Interfaces Needed
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIDocShell.h"
|
||||
|
||||
// for X remote support
|
||||
#ifdef MOZ_ENABLE_XREMOTE
|
||||
@@ -255,7 +256,8 @@ static nsresult OpenWindow(const char *urlstr, const PRUnichar *args)
|
||||
static nsresult
|
||||
OpenChromeURL( const char * urlstr,
|
||||
PRInt32 height = NS_SIZETOCONTENT,
|
||||
PRInt32 width = NS_SIZETOCONTENT )
|
||||
PRInt32 width = NS_SIZETOCONTENT,
|
||||
nsIDOMWindow **aResult = nsnull )
|
||||
{
|
||||
#ifdef DEBUG_CMD_LINE
|
||||
printf("OpenChromeURL(%s,%d,%d)\n",urlstr,height,width);
|
||||
@@ -276,6 +278,20 @@ 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<nsIDocShell> docShell;
|
||||
if (NS_SUCCEEDED(newWindow->GetDocShell(getter_AddRefs(docShell)))) {
|
||||
nsCOMPtr<nsIDOMWindow> newDOMWin = do_GetInterface(docShell);
|
||||
*aResult = newDOMWin;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -620,7 +636,7 @@ static nsresult DoOnShutdown()
|
||||
}
|
||||
|
||||
|
||||
static nsresult OpenBrowserWindow(PRInt32 height, PRInt32 width)
|
||||
static nsresult OpenBrowserWindow(PRInt32 height, PRInt32 width, nsIDOMWindow **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICmdLineHandler> handler(do_GetService(NS_BROWSERSTARTUPHANDLER_CONTRACTID, &rv));
|
||||
@@ -630,7 +646,7 @@ static nsresult OpenBrowserWindow(PRInt32 height, PRInt32 width)
|
||||
rv = handler->GetChromeUrlForTask(getter_Copies(chromeUrlForTask));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = OpenChromeURL(chromeUrlForTask, height, width );
|
||||
rv = OpenChromeURL(chromeUrlForTask, height, width, aResult);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return rv;
|
||||
@@ -712,7 +728,26 @@ static nsresult Ensure1Window( nsICmdLineService* cmdLineArgs)
|
||||
if ((const char*)tempString)
|
||||
PR_sscanf(tempString, "%d", &height);
|
||||
|
||||
rv = OpenBrowserWindow(height, width);
|
||||
nsCOMPtr<nsIDOMWindow> browserWin;
|
||||
rv = OpenBrowserWindow(height, width, getter_AddRefs(browserWin));
|
||||
|
||||
// See if we're in running in server mode.
|
||||
if (NS_SUCCEEDED(rv) && browserWin) {
|
||||
nsCOMPtr<nsIAppShellService> appShellService(do_GetService(kAppShellServiceCID));
|
||||
if (appShellService) {
|
||||
nsCOMPtr<nsINativeAppSupport> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "nsINativeAppSupport.h"
|
||||
#include "nsISplashScreen.h"
|
||||
|
||||
nsresult NS_CreateSplashScreen( nsISplashScreen **aResult );
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
|
||||
nsNativeAppSupportBase::nsNativeAppSupportBase()
|
||||
: mRefCnt( 0 ),
|
||||
mSplash( 0 ) {
|
||||
mSplash( 0 ),
|
||||
mServerMode( PR_FALSE ) {
|
||||
}
|
||||
|
||||
nsNativeAppSupportBase::~nsNativeAppSupportBase() {
|
||||
NS_IF_RELEASE( mSplash );
|
||||
}
|
||||
|
||||
// Start answer defaults to OK.
|
||||
@@ -57,7 +57,7 @@ nsNativeAppSupportBase::Quit() {
|
||||
NS_IMETHODIMP
|
||||
nsNativeAppSupportBase::ShowSplashScreen() {
|
||||
if ( !mSplash ) {
|
||||
nsresult rv = CreateSplashScreen( &mSplash );
|
||||
nsresult rv = CreateSplashScreen( getter_AddRefs( mSplash ) );
|
||||
}
|
||||
if ( mSplash ) {
|
||||
mSplash->Show();
|
||||
@@ -70,14 +70,35 @@ NS_IMETHODIMP
|
||||
nsNativeAppSupportBase::HideSplashScreen() {
|
||||
// See if there is a splash screen object.
|
||||
if ( mSplash ) {
|
||||
// Unhook it.
|
||||
nsCOMPtr<nsISplashScreen> splash = mSplash;
|
||||
mSplash = 0;
|
||||
// Hide it.
|
||||
mSplash->Hide();
|
||||
// Release it.
|
||||
NS_RELEASE( mSplash );
|
||||
splash->Hide();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeAppSupportBase::SetIsServerMode(PRBool aIsServerMode) {
|
||||
mServerMode = aIsServerMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeAppSupportBase::GetIsServerMode(PRBool *aIsServerMode) {
|
||||
NS_ENSURE_ARG( aIsServerMode );
|
||||
*aIsServerMode = mServerMode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNativeAppSupportBase::CacheBrowserWindow(nsIDOMWindow *aWindow, PRBool *aResult) {
|
||||
NS_ENSURE_ARG( aResult );
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Default implementation doesn't have a splash screen.
|
||||
NS_IMETHODIMP
|
||||
nsNativeAppSupportBase::CreateSplashScreen( nsISplashScreen **splash ) {
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
*/
|
||||
#include "nsNativeAppSupport.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
// nsNativeAppSupportBase
|
||||
//
|
||||
// This is a default implementation of the nsINativeAppSupport interface
|
||||
@@ -39,11 +41,7 @@ public:
|
||||
~nsNativeAppSupportBase();
|
||||
|
||||
// nsINativeAppSupport methods.
|
||||
NS_IMETHOD Start( PRBool *result );
|
||||
NS_IMETHOD Stop( PRBool *result );
|
||||
NS_IMETHOD Quit();
|
||||
NS_IMETHOD ShowSplashScreen();
|
||||
NS_IMETHOD HideSplashScreen();
|
||||
NS_DECL_NSINATIVEAPPSUPPORT
|
||||
|
||||
NS_IMETHOD CreateSplashScreen( nsISplashScreen **splash );
|
||||
|
||||
@@ -53,6 +51,7 @@ public:
|
||||
NS_IMETHOD QueryInterface( const nsIID &iid, void**p );
|
||||
|
||||
nsrefcnt mRefCnt;
|
||||
nsISplashScreen *mSplash;
|
||||
nsCOMPtr<nsISplashScreen> mSplash;
|
||||
PRBool mServerMode;
|
||||
}; // class nsSplashScreenWin
|
||||
|
||||
|
||||
@@ -32,6 +32,11 @@
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIAppShellService.h"
|
||||
#include <windows.h>
|
||||
#include <ddeml.h>
|
||||
#include <stdlib.h>
|
||||
@@ -242,6 +247,8 @@ 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 );
|
||||
|
||||
// The "old" Start method (renamed).
|
||||
NS_IMETHOD StartDDE();
|
||||
@@ -249,7 +256,7 @@ public:
|
||||
// Utility function to handle a Win32-specific command line
|
||||
// option: "-console", which dynamically creates a Windows
|
||||
// console.
|
||||
static void CheckConsole();
|
||||
void CheckConsole();
|
||||
|
||||
private:
|
||||
static HDDEDATA CALLBACK HandleDDENotification( UINT uType,
|
||||
@@ -262,7 +269,10 @@ private:
|
||||
ULONG dwData2 );
|
||||
static void HandleRequest( LPBYTE request );
|
||||
static nsresult GetCmdLineArgs( LPBYTE request, nsICmdLineService **aResult );
|
||||
static nsresult OpenWindow( const char *urlstr, const char *args );
|
||||
static nsresult OpenWindow( const char *urlstr, const char *args, nsIDOMWindow **aResult = 0 );
|
||||
static nsresult OpenBrowserWindow( const char *args );
|
||||
static nsresult ReParent( nsIDOMWindowInternal *window, HWND newParent );
|
||||
static nsCOMPtr<nsIDOMWindowInternal> mCachedWin;
|
||||
static int mConversations;
|
||||
static HSZ mApplication, mTopic;
|
||||
static DWORD mInstance;
|
||||
@@ -493,6 +503,18 @@ nsNativeAppSupportWin::CheckConsole() {
|
||||
}
|
||||
// Don't bother doing this more than once.
|
||||
break;
|
||||
} else if ( strcmp( "-turbo", __argv[i] ) == 0
|
||||
||
|
||||
strcmp( "/turbo", __argv[i] ) == 0
|
||||
||
|
||||
strcmp( "-server", __argv[i] ) == 0
|
||||
||
|
||||
strcmp( "/server", __argv[i] ) == 0 ) {
|
||||
// Start in server mode (and suppress splash screen).
|
||||
SetIsServerMode( PR_TRUE );
|
||||
__argv[i] = "-nosplash"; // Bit of a hack, but it works!
|
||||
// Ignore other args.
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -503,9 +525,12 @@ nsNativeAppSupportWin::CheckConsole() {
|
||||
nsresult
|
||||
NS_CreateNativeAppSupport( nsINativeAppSupport **aResult ) {
|
||||
if ( aResult ) {
|
||||
*aResult = new nsNativeAppSupportWin;
|
||||
if ( *aResult ) {
|
||||
NS_ADDREF( *aResult );
|
||||
nsNativeAppSupportWin *pNative = new nsNativeAppSupportWin;
|
||||
if ( pNative ) {
|
||||
*aResult = pNative;
|
||||
NS_ADDREF( *aResult );
|
||||
// Check for dynamic console creation request.
|
||||
pNative->CheckConsole();
|
||||
} else {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@@ -513,8 +538,6 @@ NS_CreateNativeAppSupport( nsINativeAppSupport **aResult ) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
// Check for dynamic console creation request.
|
||||
nsNativeAppSupportWin::CheckConsole();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -553,6 +576,7 @@ NS_CreateSplashScreen( nsISplashScreen **aResult ) {
|
||||
#define MOZ_DDE_EXEC_TIMEOUT 15000
|
||||
|
||||
// Static member definitions.
|
||||
nsCOMPtr<nsIDOMWindowInternal> nsNativeAppSupportWin::mCachedWin = 0;
|
||||
int nsNativeAppSupportWin::mConversations = 0;
|
||||
HSZ nsNativeAppSupportWin::mApplication = 0;
|
||||
HSZ nsNativeAppSupportWin::mTopic = 0;
|
||||
@@ -613,7 +637,7 @@ struct MessageWindow {
|
||||
0 ) ), // create struct
|
||||
NS_ERROR_FAILURE );
|
||||
|
||||
#ifdef MOZ_DEBUG_DDE
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Message window = 0x%08X\n", (int)mHandle );
|
||||
#endif
|
||||
|
||||
@@ -632,7 +656,7 @@ struct MessageWindow {
|
||||
if ( msg == WM_COPYDATA ) {
|
||||
// This is an incoming request.
|
||||
COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lp;
|
||||
#ifdef MOZ_DEBUG_DDE
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Incoming request: %s\n", (const char*)cds->lpData );
|
||||
#endif
|
||||
(void)nsNativeAppSupportWin::HandleRequest( (LPBYTE)cds->lpData );
|
||||
@@ -668,9 +692,9 @@ nsNativeAppSupportWin::Start( PRBool *aResult ) {
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
// Grab mutex first.
|
||||
int retval;
|
||||
UINT id = ID_DDE_APPLICATION_NAME;
|
||||
retval = LoadString( (HINSTANCE) NULL, id, (LPTSTR) nameBuffer, sizeof(nameBuffer) );
|
||||
int retval;
|
||||
UINT id = ID_DDE_APPLICATION_NAME;
|
||||
retval = LoadString( (HINSTANCE) NULL, id, (LPTSTR) nameBuffer, sizeof(nameBuffer) );
|
||||
if ( retval == 0 ) {
|
||||
// No app name; just keep running.
|
||||
*aResult = PR_TRUE;
|
||||
@@ -917,7 +941,7 @@ nsNativeAppSupportWin::HandleRequest( LPBYTE request ) {
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Launching browser on url [%s]...\n", (const char*)arg );
|
||||
#endif
|
||||
(void)OpenWindow( "chrome://navigator/content/", arg );
|
||||
(void)OpenBrowserWindow( arg );
|
||||
}
|
||||
else if (NS_SUCCEEDED(args->GetCmdLineValue("-chrome", getter_Copies(arg))) &&
|
||||
(const char*)arg ) {
|
||||
@@ -941,6 +965,16 @@ nsNativeAppSupportWin::HandleRequest( LPBYTE request ) {
|
||||
printf( "Launching mail...\n" );
|
||||
#endif
|
||||
(void)OpenWindow( "chrome://messenger/content/", "" );
|
||||
} else if ( NS_SUCCEEDED( args->GetCmdLineValue( "-kill", getter_Copies(arg))) &&
|
||||
(const char*)arg ) {
|
||||
// Turn off server mode.
|
||||
nsCOMPtr<nsIAppShellService> appShell = do_GetService( "@mozilla.org/appshell/appShellService;1" );
|
||||
nsCOMPtr<nsINativeAppSupport> native;
|
||||
if ( appShell &&
|
||||
NS_SUCCEEDED( appShell->GetNativeAppSupport( getter_AddRefs( native ) ) ) &&
|
||||
native ) {
|
||||
native->SetIsServerMode( PR_FALSE );
|
||||
}
|
||||
} else {
|
||||
#if MOZ_DEBUG_DDE
|
||||
printf( "Unknown request [%s]\n", (char*) request );
|
||||
@@ -957,9 +991,9 @@ nsNativeAppSupportWin::HandleRequest( LPBYTE request ) {
|
||||
if (defaultArgs) {
|
||||
nsCString url;
|
||||
url.AssignWithConversion( defaultArgs );
|
||||
OpenWindow("chrome://navigator/content/", (const char*)url);
|
||||
OpenBrowserWindow((const char*)url);
|
||||
} else {
|
||||
OpenWindow("chrome://navigator/content/", "about:blank");
|
||||
OpenBrowserWindow("about:blank");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,10 +1157,14 @@ nsNativeAppSupportWin::GetCmdLineArgs( LPBYTE request, nsICmdLineService **aResu
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeAppSupportWin::OpenWindow( const char*urlstr, const char *args ) {
|
||||
nsNativeAppSupportWin::OpenWindow( const char*urlstr, const char *args, nsIDOMWindow **aResult ) {
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if ( aResult ) {
|
||||
*aResult = 0;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
|
||||
nsCOMPtr<nsISupportsString> sarg(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (sarg)
|
||||
@@ -1136,10 +1174,134 @@ nsNativeAppSupportWin::OpenWindow( const char*urlstr, const char *args ) {
|
||||
nsCOMPtr<nsIDOMWindow> newWindow;
|
||||
rv = wwatch->OpenWindow(0, urlstr, "_blank", "chrome,dialog=no,all",
|
||||
sarg, getter_AddRefs(newWindow));
|
||||
#ifdef MOZ_DEBUG_DDE
|
||||
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");
|
||||
#endif
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static char procPropertyName[] = "MozillaProcProperty";
|
||||
|
||||
// Subclass procedure used to filter out WM_SETFOCUS messages while reparenting.
|
||||
static LRESULT CALLBACK focusFilterProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
|
||||
if ( uMsg == WM_SETFOCUS ) {
|
||||
// Don't let Mozilla's window procedure see this.
|
||||
return 0;
|
||||
} else {
|
||||
// Pass on all other messages to Mozilla's window proc.
|
||||
HANDLE oldProc = ::GetProp( hwnd, procPropertyName );
|
||||
if ( oldProc ) {
|
||||
return ::CallWindowProc( (WNDPROC)oldProc, hwnd, uMsg, wParam, lParam );
|
||||
} else {
|
||||
// Last resort is the default window proc.
|
||||
return ::DefWindowProc( hwnd, uMsg, wParam, lParam );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeAppSupportWin::ReParent( nsIDOMWindowInternal *window, HWND newParent ) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> ppScriptGlobalObj( do_QueryInterface(window) );
|
||||
if ( !ppScriptGlobalObj ) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> ppDocShell;
|
||||
ppScriptGlobalObj->GetDocShell( getter_AddRefs( ppDocShell ) );
|
||||
if ( !ppDocShell ) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIBaseWindow> ppBaseWindow( do_QueryInterface( ppDocShell ) );
|
||||
if ( !ppBaseWindow ) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> ppWidget;
|
||||
ppBaseWindow->GetMainWidget( getter_AddRefs( ppWidget ) );
|
||||
HWND hMainFrame = (HWND)ppWidget->GetNativeData( NS_NATIVE_WIDGET );
|
||||
if ( !hMainFrame ) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Filter out WM_SETFOCUS messages while reparenting to
|
||||
// other than the desktop.
|
||||
//
|
||||
// For some reason, Windows generates one and it causes
|
||||
// our focus/activation code to assert.
|
||||
LONG oldProc = 0;
|
||||
if ( newParent ) {
|
||||
// Subclass the window.
|
||||
oldProc = ::SetWindowLong( hMainFrame,
|
||||
GWL_WNDPROC,
|
||||
(LONG)(WNDPROC)focusFilterProc );
|
||||
|
||||
// Store old procedure in window so it is available within
|
||||
// focusFilterProc.
|
||||
::SetProp( hMainFrame, procPropertyName, (HANDLE)oldProc );
|
||||
}
|
||||
|
||||
// Reset the parent.
|
||||
::SetParent( hMainFrame, newParent );
|
||||
|
||||
// Restore old procedure.
|
||||
if ( newParent ) {
|
||||
::SetWindowLong( hMainFrame, GWL_WNDPROC, oldProc );
|
||||
::RemoveProp( hMainFrame, procPropertyName );
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNativeAppSupportWin::OpenBrowserWindow( const char *args ) {
|
||||
nsresult rv = NS_OK;
|
||||
// Check if we have a cached (hidden) window.
|
||||
if ( mCachedWin ) {
|
||||
nsCOMPtr<nsIDOMWindowInternal> win = mCachedWin;
|
||||
// Drop window from cache.
|
||||
mCachedWin = 0;
|
||||
// Show it.
|
||||
ReParent( win, 0 );
|
||||
} else {
|
||||
// No cached window, open a new one.
|
||||
rv = OpenWindow( "chrome://navigator/content", args );
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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() );
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -348,6 +348,58 @@ function Startup()
|
||||
}
|
||||
}
|
||||
|
||||
function BrowserFlushBookmarksAndHistory() {
|
||||
// Flush bookmakrs and history (used when window closes or is cached).
|
||||
try {
|
||||
// If bookmarks are dirty, flush 'em to disk
|
||||
var bmks = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
|
||||
.getService(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
bmks.Flush();
|
||||
|
||||
// give history a chance at flushing to disk also
|
||||
var history = Components.classes["@mozilla.org/browser/global-history;1"]
|
||||
.getService(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
history.Flush();
|
||||
} catch(ex) {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
@@ -364,21 +416,7 @@ function Shutdown()
|
||||
window.XULBrowserWindow.destroy();
|
||||
window.XULBrowserWindow = null;
|
||||
|
||||
try {
|
||||
// If bookmarks are dirty, flush 'em to disk
|
||||
var bmks = Components.classes["@mozilla.org/browser/bookmarks-service;1"]
|
||||
.getService(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
bmks.Flush();
|
||||
} catch (ex) {
|
||||
}
|
||||
|
||||
try {
|
||||
// give history a chance at flushing to disk also
|
||||
var history = Components.classes["@mozilla.org/browser/global-history;1"]
|
||||
.getService(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
history.Flush();
|
||||
} catch (ex) {
|
||||
}
|
||||
BrowserFlushBookmarksAndHistory();
|
||||
|
||||
// unregister us as a pref listener
|
||||
pref.removeObserver(window.buttonPrefListener.domain,
|
||||
|
||||
@@ -45,7 +45,7 @@ Contributor(s): ______________________________________. -->
|
||||
<window id="main-window" xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="Startup()" onunload="Shutdown()"
|
||||
onload="Startup()" onunload="Shutdown()" onclose="return BrowserCanClose()"
|
||||
contenttitlesetting="true"
|
||||
title="&mainWindow.title;"
|
||||
titlemodifier="&mainWindow.titlemodifier;"
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
<command id="Browser:Open" oncommand="BrowserOpenWindow();"/>
|
||||
<command id="Browser:Print" oncommand="BrowserPrint();"/>
|
||||
<command id="cmd_quit"/>
|
||||
<command id="cmd_close" oncommand="BrowserClose()"/>
|
||||
<command id="cmd_close" oncommand="if(BrowserCanClose()){BrowserClose();}"/>
|
||||
|
||||
<!-- Edit Menu -->
|
||||
<command id="cmd_undo"/>
|
||||
|
||||
158
mozilla/xpfe/components/startup/public/nsINativeAppSupport.idl
Normal file
158
mozilla/xpfe/components/startup/public/nsINativeAppSupport.idl
Normal file
@@ -0,0 +1,158 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Bill Law <law@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/* nsINativeAppSupport
|
||||
*
|
||||
* This "pseudo" (in the XPCOM sense) interface provides for
|
||||
* platform-specific general aplication support:
|
||||
* o It subsumes the old "NS_CanRun" and "NS_CreateSplashScreen"
|
||||
* functions that managed display of the application splash
|
||||
* screen at startup.
|
||||
* o It manages the details of the simple DDE communication
|
||||
* supported on the Win32 platform (it is the addition of this
|
||||
* item that prompted the creation of this interface.
|
||||
*
|
||||
* Due to the nature of the beast, this interface is not a full-blown
|
||||
* XPCOM component. The primary reason is that objects that implement
|
||||
* this interface generally must be operational *before* XPCOM (or any
|
||||
* of the rest of Mozilla) are initialized. As a result, this
|
||||
* interface is instantiated by somewhat unconventional means.
|
||||
*
|
||||
* To create the implementor of this interface, you call the function
|
||||
* NS_CreateNativeAppSupport. This is done in the startup code
|
||||
* in mozilla/xpfe/bootstrap.
|
||||
*
|
||||
* You can use this interface by obtaining an instance via the
|
||||
* "nativeAppSupport" attribute of the nsIAppShellService
|
||||
* interface/service.
|
||||
*
|
||||
* The interface provides these functions:
|
||||
* start - You call this to inform the native app support that the
|
||||
* application is starting. In addition, it serves as a
|
||||
* query as to whether the application should continue to
|
||||
* run. In that respect, it is rougly equivalent to the
|
||||
* NS_CanStart function, which it replaces.
|
||||
*
|
||||
* If the returned boolean result is PR_FALSE, then the
|
||||
* application should exit without further processing. In
|
||||
* such cases, the returned nsresult indicates whether the
|
||||
* reason to exit is due to an error or not.
|
||||
*
|
||||
* Win32 Note: In the case of starting a second instance
|
||||
* of this executable, this function will return
|
||||
* PR_FALSE and nsresult==NS_OK. This means that
|
||||
* the command line arguments have been
|
||||
* successfully passed to the instance of the
|
||||
* application acting as a DDE server.
|
||||
*
|
||||
* stop - You call this to inform the native app support that the
|
||||
* application *wishes* to terminate. If the returned boolean
|
||||
* value is PR_FALSE, then the application should continue
|
||||
* (as if there were still additional top-level windows open).
|
||||
*
|
||||
* Win32 Note: If this is the instance of the application
|
||||
* acting as the DDE server, and there are current
|
||||
* DDE conversations active with other instances
|
||||
* acting as DDE clients, then this function will
|
||||
* return PR_FALSE.
|
||||
*
|
||||
* quit - Like Stop, but this method *forces* termination (or more
|
||||
* precisely, indicates that the application is about to be
|
||||
* terminated regardless of what a call to Stop might have
|
||||
* returned.
|
||||
*
|
||||
* This method is intended to be called when the user selects
|
||||
* the "Quit" option (close all windows and exit).
|
||||
*
|
||||
* Win32 Note: Stop is problematic in the case of "Quit" (close
|
||||
* all windows and exit the application) because
|
||||
* either we don't Quit or (potentially) we lose
|
||||
* requests coming from other instances of the
|
||||
* application. The strategy is to give preference
|
||||
* to the user's explicit Quit request. In the
|
||||
* unlikely event that a request is pending from
|
||||
* another instance of the application, then such
|
||||
* requests are essentially ignored. This is
|
||||
* roughly equivalent to handling that request by
|
||||
* opening a new window, followed by immediately
|
||||
* closing it. Since this is the same as if the
|
||||
* request came in immediately before the Quit
|
||||
* call (versus immediately after it), no harm.
|
||||
*
|
||||
* There is an exposure here: Upon return from this
|
||||
* function, any DDE connect request (for Mozilla)
|
||||
* will fail and other instances of the application
|
||||
* will start up as a DDE server. In that case,
|
||||
* those instances may do things that conflict with
|
||||
* the subsequent shutting down of the instance that
|
||||
* is quitting. For this reason, the call to Quit
|
||||
* should be deferred as long as possible.
|
||||
*
|
||||
* showSplashScreen - Causes the platform-specific splash screen to be
|
||||
* displayed. This is a replacement for the old
|
||||
* method of invoking the Show() method on the
|
||||
* nsISplashScreen interface obtained by calling
|
||||
* NS_CreateSplashScreen.
|
||||
*
|
||||
* hideSplashScreen - Causes the splash screen to be removed (if it is
|
||||
* being shown). This replaces the old method of
|
||||
* 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.
|
||||
*
|
||||
* This interface has these attributes:
|
||||
* isServerMode - Boolean attribute indicating whether the application
|
||||
* is running in "server mode." Server mode means the
|
||||
* application was started to pre-load shared-libraries,
|
||||
* initialize services, and open a hidden Navigator window
|
||||
* in order to quickly surface that window when the user
|
||||
* launches the application in the normal mode. This
|
||||
* mode is currently Win32-only (and may really only make
|
||||
* sense there) and is intended to be initiated from the
|
||||
* Windows startup folder at system initialization.
|
||||
*/
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(5fdf8480-1f98-11d4-8077-00600811a9c3)]
|
||||
interface nsINativeAppSupport : nsISupports {
|
||||
// Startup/shutdown.
|
||||
boolean start();
|
||||
boolean stop();
|
||||
void quit();
|
||||
|
||||
// Splash screen functions.
|
||||
void showSplashScreen();
|
||||
void hideSplashScreen();
|
||||
|
||||
// Server mode.
|
||||
attribute boolean isServerMode;
|
||||
boolean cacheBrowserWindow(in nsIDOMWindow aWindow);
|
||||
};
|
||||
Reference in New Issue
Block a user