mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-13 03:24:26 +00:00
fixing 77675, windows stealing focus from each other. r=bryner, sr=hyatt
This commit is contained in:
parent
88259b1073
commit
2a7349540e
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
@ -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);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user