partial nsWindowMediator embedding analogue (not yet hooked up to build) r=sfraser,valeski

This commit is contained in:
danm%netscape.com 2001-02-04 00:32:43 +00:00
parent e240f6ab6e
commit ac3d61825f
11 changed files with 899 additions and 0 deletions

View File

@ -0,0 +1,52 @@
#!nmake
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications, Inc. Portions created by Netscape are
# Copyright (C) 2001, Mozilla. All Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
MODULE=embedcomponents
MAKE_OBJ_TYPE=DLL
DLLNAME=embedcomponents
DLL=.\$(OBJDIR)\$(DLLNAME).dll
LCFLAGS = -DWIN32_LEAN_AND_MEAN
CPP_OBJS = \
.\$(OBJDIR)\nsModule.obj \
$(NULL)
LLIBS = \
$(LIBNSPR) \
$(DIST)\lib\xpcom.lib \
$(DIST)\lib\windowwatcher_s.lib \
$(NULL)
INCS = $(INCS) \
-I$(DEPTH)\embedding\components\windowwatcher\src \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin\components
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
clobber::
$(RM) $(DIST)\bin\components\$(DLLNAME).dll
$(RM) $(DIST)\lib\$(DLLNAME).lib

View File

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsIGenericFactory.h"
#include "nsWindowWatcher.h"
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowWatcher, Init)
static nsModuleComponentInfo components[] = {
{ "Window Watcher", NS_WINDOWWATCHER_CID, NS_WINDOWWATCHER_CONTRACTID, nsWindowWatcherConstructor }
};
NS_IMPL_NSGETMODULE("windowwatcher", components)

View File

@ -0,0 +1,28 @@
#!nmake
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications, Inc. Portions created by Netscape are
# Copyright (C) 2001, Mozilla. All Rights Reserved.
#
# Contributor(s):
DEPTH=..\..
DIRS= \
windowwatcher \
build \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,25 @@
#!nmake
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications, Inc. Portions created by Netscape are
# Copyright (C) 2001, Mozilla. All Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..
DIRS=public src
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,2 @@
nsIWindowWatcher.idl
nsPIWindowWatcher.idl

View File

@ -0,0 +1,31 @@
#!nmake
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications, Inc. Portions created by Netscape are
# Copyright (C) 2001, Mozilla. All Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..\..
MODULE=windowwatcher
XPIDLSRCS = \
.\nsIWindowWatcher.idl \
.\nsPIWindowWatcher.idl \
$(NULL)
include <$(DEPTH)\config\rules.mak>

View File

@ -0,0 +1,141 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla 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/MPL/
* 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.org code.
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 2001, Mozilla. All Rights Reserved.
* Contributor(s):
*/
/*
nsIWindowWatcher is the keeper of Gecko/DOM Windows. It maintains
opens and closes windows, and maintains a traversable list of open
windows.
Usage notes:
This component has an |activeWindow| property. Clients may expect
this property to be always current, so to properly integrate this component
the application will need to keep it current by setting the property
as the active window changes.
This component does automatically keep an accurate list of extant
windows; windows need not be added or removed by hand (and there's no
interface for doing so).
Windows referenced will not be refcounted; the implementation will
claim no ownership. Since it's the nature of this service to always
hold a ("weak") reference to an open window, this requirement removes
a potential reference loop. It should be safe because it's a
design requirement that clients explicitly maintain |activeWindow| and
|currentWindow|, and that windows remove themselves from the service
when they are closed.
*/
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsIObserver;
interface nsISimpleEnumerator;
[scriptable, uuid(002286a8-494b-43b3-8ddd-49e3fc50622b)]
/*
Subject to change without revision of CID until further notice.
Assumptions:
For now I'm assuming we'll use this component to track the current
"networking context." That is, the window currently being serviced by
the network libraries, and therefore the proper parent of any alerts
those libraries may need to pose. I'm not yet convinced that this will
actually work or be necessary.
The "networking context" must provide two things: an nsIDOMWindow
to provide a script context and a native window to act as a parent
for a networking dialog. This implies the nsIDOMWindow will be able
to walk up some chain to find its container native embedding window.
In fact, I believe I can always pull a JS context off that stack
of the things that people keep around when they're switching back and forth
between C++ and JS, so all I really need to create a window is a (native)
parent.
All windows must inform the Watcher when they're being closed (perhaps
automatically through the DOMWindow's destructor), so the Watcher can
trust all its windows to be real, so there's no need for the Watcher to
addref any of its windows. This means, for instance, that setCurrentContext
won't cause a leak if you don't unset it. It would be an error to fail
to set the current context before getting into a situation where one
might be necessary.
*/
interface nsIWindowWatcher : nsISupports {
/** Create a new window. It will automatically be added to our list
(via addWindow()).
@param aParent parent window, if any. null if not.
@param aURL window URL from JS window.open
@param aName window name from JS window.open
@param aFeatures window features from JS window.open
@return the new window
*/
nsIDOMWindow openWindow(in nsIDOMWindow aParent, in string aUrl,
in string aName, in string aFeatures);
/** Clients of this service can register themselves to be notified
when a window is opened or closed (added to or removed from this
service). This method adds an aObserver to the list of objects
to be notified.
@param aObserver the object to be notified when windows are
opened or closed. Its Observe method will be
called with the following parameters:
@param aSubject (parameter to aObserver::Observe) the window being
opened or closed, sent as an nsISupports
which can be QIed to an nsIDOMWindow.
@param aTopic (parameter to aObserver::Observe) a wstring, either
"domwindowopened" or "domwindowclosed".
@param someData (parameter to aObserver::Observe) not used.
*/
void registerNotification(in nsIObserver aObserver);
/** Clients of this service can register themselves to be notified
when a window is opened or closed (added to or removed from this
service). This method removes an aObserver from the list of objects
to be notified.
@param aObserver the observer to be removed.
*/
void unregisterNotification(in nsIObserver aObserver);
/** iterates over currently open windows in the order they were opened,
guaranteeing that each will be visited exactly once.
@return an enumerator which will itself return an nsISupports which
can be QIed to an nsIDOMWindow
*/
nsISimpleEnumerator getWindowEnumerator();
/** The Watcher serves as a global storage facility for the current active
(frontmost non-floating-palette-type) window, storing and returning
it on demand. Users must keep this attribute current, including after
the topmost window is closed. This attribute obviously can return null
if no windows are open, but should otherwise always return a valid
window.
*/
attribute nsIDOMWindow activeWindow;
};
%{C++
// {002286a8-494b-43b3-8ddd-49e3fc50622b}
#define NS_WINDOWWATCHER_IID \
{0x002286a8, 0x494b, 0x43b3, {0x8d, 0xdd, 0x49, 0xe3, 0xfc, 0x50, 0x62, 0x2b}}
%}

View File

@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla 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/MPL/
* 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.org code.
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 2001, Mozilla. All Rights Reserved.
* Contributor(s):
*/
#include "nsISupports.idl"
interface nsIDOMWindow;
interface nsISimpleEnumerator;
[uuid(d535806e-afaf-47d1-8d89-783ad088c62a)]
interface nsPIWindowWatcher : nsISupports
{
/** A window has been created. Add it to our list.
@param aWindow the window to add
*/
void addWindow(in nsIDOMWindow aWindow);
/** A window has been closed. Remove it from our list.
@param aWindow the window to remove
*/
void removeWindow(in nsIDOMWindow aWindow);
};
%{C++
// {d535806e-afaf-47d1-8d89-783ad088c62a}
#define NS_PWINDOWWATCHER_IID \
{0xd535806e, 0xafaf, 0x47d1, {0x8d, 0x89, 0x78, 0x3a, 0xd0, 0x88, 0xc6, 0x2a}}
%}

View File

@ -0,0 +1,36 @@
#!nmake
#
# The contents of this file are subject to the Mozilla 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/MPL/
#
# 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.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications, Inc. Portions created by Netscape are
# Copyright (C) 2001, Mozilla. All Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..\..
MODULE=embedcomponents
LIBRARY_NAME=windowwatcher_s
CPP_OBJS= \
.\$(OBJDIR)\nsWindowWatcher.obj \
$(NULL)
include <$(DEPTH)\config\rules.mak>
install:: $(LIBRARY)
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
clobber::
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib

View File

@ -0,0 +1,432 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
//#define USEWEAKREFS // (haven't quite figured that out yet)
#include "nsAutoLock.h"
#include "nsWindowWatcher.h"
#include "nsIDOMWindow.h"
#include "nsIGenericFactory.h"
#include "nsIObserverService.h"
#ifdef USEWEAKREFS
#include "nsIWeakReference.h"
#endif
#define NOTIFICATION_OPENED NS_LITERAL_STRING("domwindowopened")
#define NOTIFICATION_CLOSED NS_LITERAL_STRING("domwindowclosed")
/****************************************************************
************************* winfowInfo ***************************
****************************************************************/
class nsWindowWatcher;
struct WindowInfo {
#ifdef USEWEAKREFS
WindowInfo(nsIDOMWindow* inWindow) {
mWindow = getter_AddRefs(NS_GetWeakReference(inWindow));
#else
WindowInfo(nsIDOMWindow* inWindow) :
mWindow(inWindow) {
#endif
ReferenceSelf();
}
~WindowInfo() {}
void InsertAfter(WindowInfo *inOlder);
void Unlink();
void ReferenceSelf();
#ifdef USEWEAKREFS
nsCOMPtr<nsIWeakReference> mWindow;
#else
nsCOMPtr<nsIDOMWindow> mWindow;
#endif
// each struct is in a circular, doubly-linked list
WindowInfo *mYounger, // next younger in sequence
*mOlder;
};
void WindowInfo::InsertAfter(WindowInfo *inOlder)
{
if (inOlder) {
mOlder = inOlder;
mYounger = inOlder->mYounger;
mOlder->mYounger = this;
if (mOlder->mOlder == mOlder)
mOlder->mOlder = this;
mYounger->mOlder = this;
if (mYounger->mYounger == mYounger)
mYounger->mYounger = this;
}
}
void WindowInfo::Unlink() {
mOlder->mYounger = mYounger;
mYounger->mOlder = mOlder;
ReferenceSelf();
}
void WindowInfo::ReferenceSelf() {
mYounger = this;
mOlder = this;
}
/****************************************************************
********************* nsWindowEnumerator ***********************
****************************************************************/
class nsWindowEnumerator : public nsISimpleEnumerator {
public:
nsWindowEnumerator(nsWindowWatcher *inWatcher);
~nsWindowEnumerator();
NS_IMETHOD HasMoreElements(PRBool *retval);
NS_IMETHOD GetNext(nsISupports **retval);
NS_DECL_ISUPPORTS
private:
friend class nsWindowWatcher;
WindowInfo *FindNext();
void WindowRemoved(WindowInfo *inInfo);
nsWindowWatcher *mWindowWatcher;
WindowInfo *mCurrentPosition;
};
NS_IMPL_ADDREF(nsWindowEnumerator);
NS_IMPL_RELEASE(nsWindowEnumerator);
NS_IMPL_QUERY_INTERFACE1(nsWindowEnumerator, nsISimpleEnumerator);
nsWindowEnumerator::nsWindowEnumerator(nsWindowWatcher *inWatcher)
: mWindowWatcher(inWatcher),
mCurrentPosition(inWatcher->mOldestWindow)
{
NS_INIT_REFCNT();
mWindowWatcher->AddEnumerator(this);
mWindowWatcher->AddRef();
}
nsWindowEnumerator::~nsWindowEnumerator()
{
mWindowWatcher->RemoveEnumerator(this);
mWindowWatcher->Release();
}
NS_IMETHODIMP
nsWindowEnumerator::HasMoreElements(PRBool *retval)
{
if (!retval)
return NS_ERROR_INVALID_ARG;
*retval = mCurrentPosition? PR_TRUE : PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
nsWindowEnumerator::GetNext(nsISupports **retval)
{
if (!retval)
return NS_ERROR_INVALID_ARG;
*retval = NULL;
#ifdef USEWEAKREFS
while (mCurrentPosition) {
CallQueryReferent(mCurrentPosition->mWindow, retval);
if (*retval) {
mCurrentPosition = FindNext();
break;
} else // window is gone!
mWindowWatcher->RemoveWindow(mCurrentPosition);
}
NS_IF_ADDREF(*retval);
#else
if (mCurrentPosition) {
CallQueryInterface(mCurrentPosition->mWindow, retval);
mCurrentPosition = FindNext();
}
#endif
return NS_OK;
}
WindowInfo *
nsWindowEnumerator::FindNext()
{
WindowInfo *info;
if (!mCurrentPosition)
return 0;
info = mCurrentPosition->mYounger;
return info == mWindowWatcher->mOldestWindow ? 0 : info;
}
// if a window is being removed adjust the iterator's current position
void nsWindowEnumerator::WindowRemoved(WindowInfo *inInfo) {
if (mCurrentPosition == inInfo)
mCurrentPosition = mCurrentPosition != inInfo->mYounger ?
inInfo->mYounger : 0;
}
/****************************************************************
*********************** nsWindowWatcher ************************
****************************************************************/
NS_IMPL_ADDREF(nsWindowWatcher);
NS_IMPL_RELEASE(nsWindowWatcher);
NS_IMPL_QUERY_INTERFACE2(nsWindowWatcher, nsIWindowWatcher, nsPIWindowWatcher)
nsWindowWatcher::nsWindowWatcher() :
mEnumeratorList(),
mOldestWindow(0),
mActiveWindow(0),
mListLock(0)
{
NS_INIT_REFCNT();
}
nsWindowWatcher::~nsWindowWatcher()
{
// delete data
while (mOldestWindow)
RemoveWindow(mOldestWindow);
if (mListLock)
PR_DestroyLock(mListLock);
}
nsresult
nsWindowWatcher::Init()
{
mListLock = PR_NewLock();
if (!mListLock)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
const char *aUrl,
const char *aName,
const char *aFeatures,
nsIDOMWindow **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsWindowWatcher::RegisterNotification(nsIObserver *aObserver)
{
// just a convenience method; it delegates to nsIObserverService
nsresult rv;
if (!aObserver)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
if (os) {
rv = os->AddObserver(aObserver, NOTIFICATION_OPENED);
if (NS_SUCCEEDED(rv))
rv = os->AddObserver(aObserver, NOTIFICATION_CLOSED);
}
return rv;
}
NS_IMETHODIMP
nsWindowWatcher::UnregisterNotification(nsIObserver *aObserver)
{
// just a convenience method; it delegates to nsIObserverService
nsresult rv;
if (!aObserver)
return NS_ERROR_INVALID_ARG;
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
if (os) {
os->RemoveObserver(aObserver, NOTIFICATION_OPENED);
os->RemoveObserver(aObserver, NOTIFICATION_CLOSED);
}
return rv;
}
NS_IMETHODIMP
nsWindowWatcher::GetWindowEnumerator(nsISimpleEnumerator** _retval)
{
if (!_retval)
return NS_ERROR_INVALID_ARG;
nsAutoLock lock(mListLock);
nsWindowEnumerator *enumerator = new nsWindowEnumerator(this);
if (enumerator)
return CallQueryInterface(enumerator, _retval);
return NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsWindowWatcher::GetActiveWindow(nsIDOMWindow * *aActiveWindow)
{
if (!aActiveWindow)
return NS_ERROR_INVALID_ARG;
*aActiveWindow = mActiveWindow;
NS_IF_ADDREF(mActiveWindow);
return NS_OK;
}
NS_IMETHODIMP
nsWindowWatcher::SetActiveWindow(nsIDOMWindow * aActiveWindow)
{
mActiveWindow = aActiveWindow;
return NS_OK;
}
NS_IMETHODIMP
nsWindowWatcher::AddWindow(nsIDOMWindow *aWindow)
{
nsresult rv;
if (!aWindow)
return NS_ERROR_INVALID_ARG;
// create window info struct and add to list of windows
WindowInfo* info = new WindowInfo(aWindow);
if (!info)
return NS_ERROR_OUT_OF_MEMORY;
nsAutoLock lock(mListLock);
if (mOldestWindow)
info->InsertAfter(mOldestWindow->mOlder);
else
mOldestWindow = info;
// a window being added to us signifies a newly opened window.
// send notifications.
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
if (os) {
nsCOMPtr<nsISupports> domwin(do_QueryInterface(aWindow));
rv = os->Notify(domwin, NOTIFICATION_OPENED, 0);
}
return rv;
}
NS_IMETHODIMP
nsWindowWatcher::RemoveWindow(nsIDOMWindow *aWindow)
{
// find the corresponding WindowInfo, remove it
WindowInfo *info,
*listEnd;
#ifdef USEWEAKREFS
nsresult rv;
PRBool found;
#endif
if (!aWindow)
return NS_ERROR_INVALID_ARG;
info = mOldestWindow;
listEnd = 0;
#ifdef USEWEAKREFS
rv = NS_OK;
found = PR_FALSE;
while (info != listEnd && NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDOMWindow> infoWindow(do_QueryReferent(info->mWindow));
if (!infoWindow)
rv = RemoveWindow(info);
else if (infoWindow.get() == aWindow) {
found = PR_TRUE;
rv = RemoveWindow(info);
}
info = info->mYounger;
listEnd = mOldestWindow;
}
return found ? rv : NS_ERROR_INVALID_ARG;
#else
while (info != listEnd) {
if (info->mWindow.get() == aWindow)
return RemoveWindow(info);
info = info->mYounger;
listEnd = mOldestWindow;
}
return NS_ERROR_INVALID_ARG;
#endif
}
NS_IMETHODIMP nsWindowWatcher::RemoveWindow(WindowInfo *inInfo)
{
PRInt32 ctr,
count = mEnumeratorList.Count();
nsresult rv;
{
// notify the enumerators
nsAutoLock lock(mListLock);
for (ctr = 0; ctr < count; ++ctr)
((nsWindowEnumerator*)mEnumeratorList[ctr])->WindowRemoved(inInfo);
// remove the element from the list
if (inInfo == mOldestWindow)
mOldestWindow = inInfo->mYounger == mOldestWindow ? 0 : inInfo->mYounger;
inInfo->Unlink();
}
// a window being removed from us signifies a newly closed window.
// send notifications.
nsCOMPtr<nsIObserverService> os(do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv));
if (os) {
#ifdef USEWEAKREFS
nsCOMPtr<nsISupports> domwin(do_QueryReferent(inInfo->mWindow));
if (domwin)
rv = os->Notify(domwin, NOTIFICATION_CLOSED, 0);
// else bummer. since the window is gone, there's nothing to notify with.
#else
nsCOMPtr<nsISupports> domwin(do_QueryInterface(inInfo->mWindow));
rv = os->Notify(domwin, NOTIFICATION_CLOSED, 0);
#endif
}
delete inInfo;
return NS_OK;
}
PRBool
nsWindowWatcher::AddEnumerator(nsWindowEnumerator* inEnumerator)
{
// (requires a lock; assumes it's called by someone holding the lock)
return mEnumeratorList.AppendElement(inEnumerator);
}
PRBool
nsWindowWatcher::RemoveEnumerator(nsWindowEnumerator* inEnumerator)
{
// (requires a lock; assumes it's called by someone holding the lock)
return mEnumeratorList.RemoveElement(inEnumerator);
}

View File

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef __nsWindowWatcher_h__
#define __nsWindowWatcher_h__
// {a21bfa01-f349-4394-a84c-8de5cf0737d0}
#define NS_WINDOWWATCHER_CID \
{0xa21bfa01, 0xf349, 0x4394, {0xa8, 0x4c, 0x8d, 0xe5, 0xcf, 0x7, 0x37, 0xd0}}
#define NS_WINDOWWATCHER_CONTRACTID \
"@mozilla.org/apputil/window-watcher;1"
#include "nsIWindowWatcher.h"
#include "nsPIWindowWatcher.h"
#include "nsVoidArray.h"
class nsWindowEnumerator;
struct WindowInfo;
struct PRLock;
class nsWindowWatcher :
public nsIWindowWatcher,
public nsPIWindowWatcher
{
friend class nsWindowEnumerator;
public:
nsWindowWatcher();
virtual ~nsWindowWatcher();
nsresult Init();
NS_DECL_ISUPPORTS
NS_DECL_NSIWINDOWWATCHER
NS_DECL_NSPIWINDOWWATCHER
private:
PRBool AddEnumerator(nsWindowEnumerator* inEnumerator);
PRBool RemoveEnumerator(nsWindowEnumerator* inEnumerator);
NS_IMETHOD RemoveWindow(WindowInfo *inInfo);
nsVoidArray mEnumeratorList;
WindowInfo *mOldestWindow;
nsIDOMWindow *mActiveWindow;
PRLock *mListLock;
};
#endif