fixing 77675, windows stealing focus from each other. r=bryner, sr=hyatt

This commit is contained in:
saari%netscape.com 2001-07-20 08:14:44 +00:00
parent 88259b1073
commit 2a7349540e
9 changed files with 89 additions and 46 deletions

View File

@ -64,6 +64,7 @@ class nsIObserver;
class nsISupportsArray; class nsISupportsArray;
class nsIScriptLoader; class nsIScriptLoader;
class nsString; class nsString;
class nsIFocusController;
// IID for the nsIDocument interface // IID for the nsIDocument interface
#define NS_IDOCUMENT_IID \ #define NS_IDOCUMENT_IID \
@ -261,6 +262,14 @@ public:
*/ */
NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader) = 0; NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader) = 0;
/**
* Get the focus controller for this document
* This can usually be gotten through the ScriptGlobalObject, but
* it is set to null during document destruction, when we still might
* need to fire focus events.
*/
NS_IMETHOD GetFocusController(nsIFocusController** aFocusController) = 0;
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Document notification API's // Document notification API's

View File

@ -98,7 +98,8 @@
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "nsIDOMWindowInternal.h" #include "nsIDOMWindowInternal.h"
#include "nsPIDOMWindow.h"
#include "nsIFocusController.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIBoxObject.h" #include "nsIBoxObject.h"
@ -1410,12 +1411,31 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
#endif #endif
mContentWrapperHash.Reset(); mContentWrapperHash.Reset();
} else if (aScriptGlobalObject != mScriptGlobalObject) {
// Update our weak ref to the focus controller
nsCOMPtr<nsPIDOMWindow> domPrivate = do_QueryInterface(aScriptGlobalObject);
if (domPrivate) {
nsCOMPtr<nsIFocusController> fc;
domPrivate->GetRootFocusController(getter_AddRefs(fc));
mFocusController = getter_AddRefs(NS_GetWeakReference(fc));
}
} }
mScriptGlobalObject = aScriptGlobalObject; mScriptGlobalObject = aScriptGlobalObject;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsDocument::GetFocusController(nsIFocusController** aFocusController)
{
NS_ENSURE_ARG_POINTER(aFocusController);
nsCOMPtr<nsIFocusController> fc = do_QueryReferent(mFocusController);
*aFocusController = fc;
NS_IF_ADDREF(*aFocusController);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager) nsDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager)
{ {

View File

@ -392,6 +392,14 @@ public:
*/ */
NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader); NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader);
/**
* Get the focus controller for this document
* This can usually be gotten through the ScriptGlobalObject, but
* it is set to null during document destruction, when we still might
* need to fire focus events.
*/
NS_IMETHOD GetFocusController(nsIFocusController** aFocusController);
/** /**
* Add a new observer of document change notifications. Whenever * Add a new observer of document change notifications. Whenever
* content is changed, appended, inserted or removed the observers are * content is changed, appended, inserted or removed the observers are
@ -572,6 +580,7 @@ protected:
nsSupportsHashtable mContentWrapperHash; nsSupportsHashtable mContentWrapperHash;
nsCOMPtr<nsICSSLoader> mCSSLoader; nsCOMPtr<nsICSSLoader> mCSSLoader;
nsWeakPtr mFocusController;
private: private:
// These are not implemented and not supported. // These are not implemented and not supported.

View File

@ -624,9 +624,6 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
{ {
EnsureDocument(aPresContext); EnsureDocument(aPresContext);
if (gLastFocusedDocument != mDocument)
break;
nsCOMPtr<nsIScriptGlobalObject> ourGlobal; nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal)); mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
@ -635,22 +632,23 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
// focused sub-window and sub-element for this top-level // focused sub-window and sub-element for this top-level
// window. // window.
nsCOMPtr<nsIFocusController> focusController; nsCOMPtr<nsIFocusController> focusController;
nsCOMPtr<nsIDOMWindowInternal> rootWindow; mDocument->GetFocusController(getter_AddRefs(focusController));
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
if(ourWindow) {
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
if (focusController) { if (focusController) {
// Suppress the command dispatcher. // Suppress the command dispatcher.
focusController->SetSuppressFocus(PR_TRUE, "Deactivate Suppression"); focusController->SetSuppressFocus(PR_TRUE, "Deactivate Suppression");
} }
}
// Now fire blurs. We have to fire a blur on the focused window // Now fire blurs. We have to fire a blur on the focused window
// and on the focused element if there is one. // and on the focused element if there is one.
if (gLastFocusedDocument && gLastFocusedPresContext) { if (gLastFocusedDocument && gLastFocusedDocument == mDocument) {
if (gLastFocusedContent) { if (gLastFocusedContent) {
// Blur the element. // Blur the element.
nsCOMPtr<nsIPresShell> shell; nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMElement> focusedElement;
focusController->GetFocusedElement(getter_AddRefs(focusedElement));
nsCOMPtr<nsIContent> focusedContent = do_QueryInterface(focusedElement);
gLastFocusedDocument->GetShellAt(0, getter_AddRefs(shell)); gLastFocusedDocument->GetShellAt(0, getter_AddRefs(shell));
if (shell) { if (shell) {
nsCOMPtr<nsIPresContext> oldPresContext; nsCOMPtr<nsIPresContext> oldPresContext;
@ -663,7 +661,8 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
nsCOMPtr<nsIEventStateManager> esm; nsCOMPtr<nsIEventStateManager> esm;
oldPresContext->GetEventStateManager(getter_AddRefs(esm)); oldPresContext->GetEventStateManager(getter_AddRefs(esm));
esm->SetFocusedContent(gLastFocusedContent); esm->SetFocusedContent(gLastFocusedContent);
gLastFocusedContent->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); if(focusedContent)
focusedContent->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
esm->SetFocusedContent(nsnull); esm->SetFocusedContent(nsnull);
NS_IF_RELEASE(gLastFocusedContent); NS_IF_RELEASE(gLastFocusedContent);
} }
@ -678,6 +677,16 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
if (ourGlobal) if (ourGlobal)
ourGlobal->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); ourGlobal->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
else {
// If the document is being torn down, we can't fire a blur on
// the window, but we still need to tell the focus controller
// that it isn't active.
nsCOMPtr<nsIFocusController> fc;
gLastFocusedDocument->GetFocusController(getter_AddRefs(fc));
if (fc)
fc->SetActive(PR_FALSE);
}
// Now clear our our global variables // Now clear our our global variables
mCurrentTarget = nsnull; mCurrentTarget = nsnull;

View File

@ -1428,12 +1428,31 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
#endif #endif
mContentWrapperHash.Reset(); mContentWrapperHash.Reset();
} else if (mScriptGlobalObject != aScriptGlobalObject) {
// Update our weak ref to the focus controller
nsCOMPtr<nsPIDOMWindow> domPrivate = do_QueryInterface(aScriptGlobalObject);
if (domPrivate) {
nsCOMPtr<nsIFocusController> fc;
domPrivate->GetRootFocusController(getter_AddRefs(fc));
mFocusController = getter_AddRefs(NS_GetWeakReference(fc));
}
} }
mScriptGlobalObject = aScriptGlobalObject; mScriptGlobalObject = aScriptGlobalObject;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsXULDocument::GetFocusController(nsIFocusController** aFocusController)
{
NS_ENSURE_ARG_POINTER(aFocusController);
nsCOMPtr<nsIFocusController> fc = do_QueryReferent(mFocusController);
*aFocusController = fc;
NS_IF_ADDREF(*aFocusController);
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsXULDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager) nsXULDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager)
{ {
@ -6315,31 +6334,3 @@ XULElementFactoryImpl::CreateInstanceByTag(nsINodeInfo *aNodeInfo,
return nsXULElement::Create(aNodeInfo, aResult); return nsXULElement::Create(aNodeInfo, aResult);
} }
nsresult nsXULDocument::GetFocusController(nsIFocusController** aController)
{
NS_ENSURE_ARG_POINTER(aController);
nsresult rv;
// get the script global object
nsCOMPtr<nsIScriptGlobalObject> global;
rv = GetScriptGlobalObject(getter_AddRefs(global));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
// get the internal dom window
nsCOMPtr<nsIDOMWindowInternal> internalWin(do_QueryInterface(global, &rv));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(internalWin, NS_ERROR_FAILURE);
// get the private dom window
nsCOMPtr<nsPIDOMWindow> privateWin(do_QueryInterface(internalWin, &rv));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(privateWin, NS_ERROR_FAILURE);
// get the focus controller
rv = privateWin->GetRootFocusController(aController); // addref is here
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(*aController, NS_ERROR_FAILURE);
return rv;
}

View File

@ -231,6 +231,8 @@ public:
NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader); NS_IMETHOD GetScriptLoader(nsIScriptLoader** aScriptLoader);
NS_IMETHOD GetFocusController(nsIFocusController** aFocusController);
virtual void AddObserver(nsIDocumentObserver* aObserver); virtual void AddObserver(nsIDocumentObserver* aObserver);
virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver); virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver);
@ -548,6 +550,8 @@ protected:
nsCOMPtr<nsIDOMNode> mTooltipNode; // [OWNER] element triggering the tooltip nsCOMPtr<nsIDOMNode> mTooltipNode; // [OWNER] element triggering the tooltip
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager; // [OWNER] list of names in the document nsCOMPtr<nsINodeInfoManager> mNodeInfoManager; // [OWNER] list of names in the document
nsWeakPtr mFocusController;
/** /**
* Context stack, which maintains the state of the Builder and allows * Context stack, which maintains the state of the Builder and allows
* it to be interrupted. * it to be interrupted.
@ -794,8 +798,6 @@ protected:
private: private:
// helpers // helpers
nsresult GetFocusController(nsIFocusController** aController);
}; };

View File

@ -59,7 +59,8 @@ nsFocusController::~nsFocusController(void)
{ {
} }
NS_IMPL_ISUPPORTS3(nsFocusController, nsIFocusController, nsIDOMFocusListener, nsIDOMEventListener) NS_IMPL_ISUPPORTS4(nsFocusController, nsIFocusController,
nsIDOMFocusListener, nsIDOMEventListener, nsSupportsWeakReference)
NS_IMETHODIMP NS_IMETHODIMP
nsFocusController::Create(nsIFocusController** aResult) nsFocusController::Create(nsIFocusController** aResult)
@ -401,13 +402,13 @@ nsFocusController::SetSuppressFocus(PRBool aSuppressFocus, char* aReason)
if(aSuppressFocus) { if(aSuppressFocus) {
++mSuppressFocus; ++mSuppressFocus;
#ifdef DEBUG_hyatt #ifdef DEBUG_hyatt
printf("[%d] SuppressFocus incremented to %d. The reason is %s.\n", this, mSuppressFocus, aReason); printf("[%p] SuppressFocus incremented to %d. The reason is %s.\n", this, mSuppressFocus, aReason);
#endif #endif
} }
else if(mSuppressFocus > 0) { else if(mSuppressFocus > 0) {
--mSuppressFocus; --mSuppressFocus;
#ifdef DEBUG_hyatt #ifdef DEBUG_hyatt
printf("[%d] SuppressFocus decremented to %d. The reason is %s.\n", this, mSuppressFocus, aReason); printf("[%p] SuppressFocus decremented to %d. The reason is %s.\n", this, mSuppressFocus, aReason);
#endif #endif
} }
else else

View File

@ -29,6 +29,7 @@
#include "nsIDOMFocusListener.h" #include "nsIDOMFocusListener.h"
#include "nsIDOMElement.h" #include "nsIDOMElement.h"
#include "nsIDOMWindow.h" #include "nsIDOMWindow.h"
#include "nsWeakReference.h"
class nsIDOMElement; class nsIDOMElement;
class nsIDOMWindow; class nsIDOMWindow;
@ -36,7 +37,8 @@ class nsIController;
class nsIControllers; class nsIControllers;
class nsFocusController : public nsIFocusController, class nsFocusController : public nsIFocusController,
public nsIDOMFocusListener public nsIDOMFocusListener,
public nsSupportsWeakReference
{ {
public: public:
static NS_IMETHODIMP Create(nsIFocusController** aResult); static NS_IMETHODIMP Create(nsIFocusController** aResult);

View File

@ -320,10 +320,10 @@ void nsMacEventDispatchHandler::SetDeactivated(nsWindow *aDeactivatedWidget)
if (mActiveWidget) if (mActiveWidget)
{ {
//printf(" nsMacEventDispatchHandler::SetDeactivated sends NS_DEACTIVATE\n"); //printf(" nsMacEventDispatchHandler::SetDeactivated sends NS_DEACTIVATE\n");
DispatchGuiEvent(mActiveWidget, NS_DEACTIVATE);
mActiveWidget->RemoveDeleteObserver(this); mActiveWidget->RemoveDeleteObserver(this);
mActiveWidget = nsnull; mActiveWidget = nsnull;
} }
DispatchGuiEvent(aDeactivatedWidget, NS_DEACTIVATE);
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------