зеркало из https://github.com/mozilla/gecko-dev.git
fixing 77675, windows stealing focus from each other. r=bryner, sr=hyatt
This commit is contained in:
Родитель
88259b1073
Коммит
2a7349540e
|
@ -64,6 +64,7 @@ class nsIObserver;
|
|||
class nsISupportsArray;
|
||||
class nsIScriptLoader;
|
||||
class nsString;
|
||||
class nsIFocusController;
|
||||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
|
@ -261,6 +262,14 @@ public:
|
|||
*/
|
||||
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
|
||||
|
|
|
@ -98,7 +98,8 @@
|
|||
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIFocusController.h"
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
#include "nsIBoxObject.h"
|
||||
|
@ -1410,12 +1411,31 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
#endif
|
||||
|
||||
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;
|
||||
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
|
||||
nsDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager)
|
||||
{
|
||||
|
|
|
@ -392,6 +392,14 @@ public:
|
|||
*/
|
||||
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
|
||||
* content is changed, appended, inserted or removed the observers are
|
||||
|
@ -572,6 +580,7 @@ protected:
|
|||
nsSupportsHashtable mContentWrapperHash;
|
||||
|
||||
nsCOMPtr<nsICSSLoader> mCSSLoader;
|
||||
nsWeakPtr mFocusController;
|
||||
|
||||
private:
|
||||
// These are not implemented and not supported.
|
||||
|
|
|
@ -624,9 +624,6 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
|||
{
|
||||
EnsureDocument(aPresContext);
|
||||
|
||||
if (gLastFocusedDocument != mDocument)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
||||
mDocument->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
||||
|
||||
|
@ -635,22 +632,23 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
|||
// focused sub-window and sub-element for this top-level
|
||||
// window.
|
||||
nsCOMPtr<nsIFocusController> focusController;
|
||||
nsCOMPtr<nsIDOMWindowInternal> rootWindow;
|
||||
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
|
||||
if(ourWindow) {
|
||||
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
|
||||
mDocument->GetFocusController(getter_AddRefs(focusController));
|
||||
if (focusController) {
|
||||
// Suppress the command dispatcher.
|
||||
focusController->SetSuppressFocus(PR_TRUE, "Deactivate Suppression");
|
||||
}
|
||||
}
|
||||
|
||||
// Now fire blurs. We have to fire a blur on the focused window
|
||||
// and on the focused element if there is one.
|
||||
if (gLastFocusedDocument && gLastFocusedPresContext) {
|
||||
if (gLastFocusedDocument && gLastFocusedDocument == mDocument) {
|
||||
if (gLastFocusedContent) {
|
||||
// Blur the element.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> focusedElement;
|
||||
focusController->GetFocusedElement(getter_AddRefs(focusedElement));
|
||||
nsCOMPtr<nsIContent> focusedContent = do_QueryInterface(focusedElement);
|
||||
|
||||
gLastFocusedDocument->GetShellAt(0, getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIPresContext> oldPresContext;
|
||||
|
@ -663,7 +661,8 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
|||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
oldPresContext->GetEventStateManager(getter_AddRefs(esm));
|
||||
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);
|
||||
NS_IF_RELEASE(gLastFocusedContent);
|
||||
}
|
||||
|
@ -678,6 +677,16 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
|
|||
mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
if (ourGlobal)
|
||||
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
|
||||
mCurrentTarget = nsnull;
|
||||
|
|
|
@ -1428,12 +1428,31 @@ nsXULDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
|
|||
#endif
|
||||
|
||||
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;
|
||||
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
|
||||
nsXULDocument::GetNameSpaceManager(nsINameSpaceManager*& aManager)
|
||||
{
|
||||
|
@ -6315,31 +6334,3 @@ XULElementFactoryImpl::CreateInstanceByTag(nsINodeInfo *aNodeInfo,
|
|||
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 GetFocusController(nsIFocusController** aFocusController);
|
||||
|
||||
virtual void AddObserver(nsIDocumentObserver* aObserver);
|
||||
|
||||
virtual PRBool RemoveObserver(nsIDocumentObserver* aObserver);
|
||||
|
@ -548,6 +550,8 @@ protected:
|
|||
nsCOMPtr<nsIDOMNode> mTooltipNode; // [OWNER] element triggering the tooltip
|
||||
nsCOMPtr<nsINodeInfoManager> mNodeInfoManager; // [OWNER] list of names in the document
|
||||
|
||||
nsWeakPtr mFocusController;
|
||||
|
||||
/**
|
||||
* Context stack, which maintains the state of the Builder and allows
|
||||
* it to be interrupted.
|
||||
|
@ -794,8 +798,6 @@ protected:
|
|||
private:
|
||||
// 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
|
||||
nsFocusController::Create(nsIFocusController** aResult)
|
||||
|
@ -401,13 +402,13 @@ nsFocusController::SetSuppressFocus(PRBool aSuppressFocus, char* aReason)
|
|||
if(aSuppressFocus) {
|
||||
++mSuppressFocus;
|
||||
#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
|
||||
}
|
||||
else if(mSuppressFocus > 0) {
|
||||
--mSuppressFocus;
|
||||
#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
|
||||
}
|
||||
else
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
class nsIDOMElement;
|
||||
class nsIDOMWindow;
|
||||
|
@ -36,7 +37,8 @@ class nsIController;
|
|||
class nsIControllers;
|
||||
|
||||
class nsFocusController : public nsIFocusController,
|
||||
public nsIDOMFocusListener
|
||||
public nsIDOMFocusListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
static NS_IMETHODIMP Create(nsIFocusController** aResult);
|
||||
|
|
|
@ -320,10 +320,10 @@ void nsMacEventDispatchHandler::SetDeactivated(nsWindow *aDeactivatedWidget)
|
|||
if (mActiveWidget)
|
||||
{
|
||||
//printf(" nsMacEventDispatchHandler::SetDeactivated sends NS_DEACTIVATE\n");
|
||||
DispatchGuiEvent(mActiveWidget, NS_DEACTIVATE);
|
||||
mActiveWidget->RemoveDeleteObserver(this);
|
||||
mActiveWidget = nsnull;
|
||||
}
|
||||
DispatchGuiEvent(aDeactivatedWidget, NS_DEACTIVATE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
Загрузка…
Ссылка в новой задаче