diff --git a/mozilla/content/events/src/nsEventStateManager.cpp b/mozilla/content/events/src/nsEventStateManager.cpp index 8ac3bea5be1..5d76500ace9 100644 --- a/mozilla/content/events/src/nsEventStateManager.cpp +++ b/mozilla/content/events/src/nsEventStateManager.cpp @@ -45,6 +45,8 @@ #include "nsIDOMSelection.h" #include "nsIFrameSelection.h" #include "nsIDeviceContext.h" +#include "nsIScriptContextOwner.h" +#include "nsIScriptGlobalObject.h" static NS_DEFINE_IID(kIEventStateManagerIID, NS_IEVENTSTATEMANAGER_IID); @@ -114,6 +116,9 @@ NS_IMPL_ADDREF(nsEventStateManager) NS_IMPL_RELEASE(nsEventStateManager) NS_IMPL_QUERY_INTERFACE(nsEventStateManager, kIEventStateManagerIID); +// This must be the same across instances +static nsCOMPtr mLastFocusedContent; + NS_IMETHODIMP nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, @@ -177,6 +182,112 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, GenerateDragDropEnterExit(aPresContext, aEvent); break; case NS_GOTFOCUS: + { + nsCOMPtr oldFocusedContent; + mCurrentTarget->GetContent(getter_AddRefs(oldFocusedContent)); + if(mLastFocusedContent == oldFocusedContent) + break; + + // ask focus target about its CSS user-focus style + PRBool surpressBlurAndFocus = PR_FALSE; + nsCOMPtr context; + mCurrentTarget->GetStyleContext(getter_AddRefs(context)); + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus based on user-focus: ignore; + surpressBlurAndFocus = PR_TRUE; + } + + if(!surpressBlurAndFocus) { + // TODO: fire blur only if the focus target is not a child of the currently focused node + // (it would just get focus again a second later) + PRBool isChild = PR_FALSE; + + if(!isChild){ + // Ask if the last focused content can accept blur + nsCOMPtr oldFocus = mLastFocusedContent; + if (oldFocus) { + nsIFocusableContent *focusChange; + if (NS_SUCCEEDED(oldFocus->QueryInterface(kIFocusableContentIID, (void **)&focusChange))) { + NS_RELEASE(focusChange); + + //fire blur only if target can accept focus + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_BLUR_CONTENT; + + if (!mDocument) { + nsCOMPtr presShell; + aPresContext.GetShell(getter_AddRefs(presShell)); + if (presShell) { + presShell->GetDocument(&mDocument); + } + } + + if (mDocument) { + mCurrentTarget = nsnull; + + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; + + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + } + } + } + } + + // Ask if target can accept focus + mCurrentTarget = aTargetFrame; + + //fire focus + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent focusevent; + focusevent.eventStructType = NS_EVENT; + focusevent.message = NS_FOCUS_CONTENT; + + if (!mDocument) { + nsCOMPtr presShell; + aPresContext.GetShell(getter_AddRefs(presShell)); + if (presShell) { + presShell->GetDocument(&mDocument); + } + } + + if (mDocument) { + nsCOMPtr newFoo; + mCurrentTarget->GetContent(getter_AddRefs(newFoo)); + mLastFocusedContent = newFoo; + + mCurrentTarget = nsnull; + // fire focus on window, not document + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; + + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, status); + } + } + } + break; + + case NS_LOSTFOCUS: + { + // Hold the blur, wait for the focus so we can query the style of the focus + // target as to what to do with the event. If appropriate we fire the blur + // at that time. + } + break; + + case NS_ACTIVATE: { nsIContent* newFocus; mCurrentTarget->GetContent(&newFocus); @@ -190,12 +301,12 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, } NS_RELEASE(newFocus); } - + //fire focus nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event; - event.eventStructType = NS_EVENT; - event.message = NS_FOCUS_CONTENT; + nsEvent focusevent; + focusevent.eventStructType = NS_EVENT; + focusevent.message = NS_FOCUS_CONTENT; if (!mDocument) { nsCOMPtr presShell; @@ -206,46 +317,70 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, } if (mDocument) { + mCurrentTarget->GetContent(getter_AddRefs(mLastFocusedContent)); + mCurrentTarget = nsnull; - mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + + // fire focus on window, not document + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; + + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, status); } + } break; - case NS_LOSTFOCUS: + + case NS_DEACTIVATE: { - nsIContent* oldFocus; - mCurrentTarget->GetContent(&oldFocus); - if (oldFocus) { + nsIContent* newFocus; + mCurrentTarget->GetContent(&newFocus); + if (newFocus) { nsIFocusableContent *focusChange; - if (NS_SUCCEEDED(oldFocus->QueryInterface(kIFocusableContentIID, + if (NS_SUCCEEDED(newFocus->QueryInterface(kIFocusableContentIID, (void **)&focusChange))) { NS_RELEASE(focusChange); - NS_RELEASE(oldFocus); + NS_RELEASE(newFocus); break; } - NS_RELEASE(oldFocus); + NS_RELEASE(newFocus); } + + //fire blur + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_BLUR_CONTENT; - //fire blur - nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event; - event.eventStructType = NS_EVENT; - event.message = NS_BLUR_CONTENT; + if (!mDocument) { + nsCOMPtr presShell; + aPresContext.GetShell(getter_AddRefs(presShell)); + if (presShell) { + presShell->GetDocument(&mDocument); + } + } + + if (mDocument) { + mCurrentTarget = nsnull; - if (!mDocument) { - nsCOMPtr presShell; - aPresContext.GetShell(getter_AddRefs(presShell)); - if (presShell) { - presShell->GetDocument(&mDocument); - } - } + // fire focus on window, not document + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; - if (mDocument) { - mCurrentTarget = nsnull; - mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); - } - } + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + } + + } break; + case NS_KEY_PRESS: case NS_KEY_DOWN: case NS_KEY_UP: @@ -444,25 +579,40 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext, if (focusable) { if (current.get() != mCurrentFocus) { nsCOMPtr content = do_QueryInterface(focusable); - if (ChangeFocus(content, PR_TRUE)) + if (ChangeFocus(content, mCurrentTarget, PR_TRUE)) focusChangeFailed = PR_FALSE; } else { focusChangeFailed = PR_FALSE; } } - if (focusChangeFailed) { + // ask focus target the magic question + PRBool surpressBlurAndFocus = PR_FALSE; + nsCOMPtr context; + + if(!mCurrentTarget) break; + mCurrentTarget->GetStyleContext(getter_AddRefs(context)); + if(!context) break; + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if(!styleStruct) break; + + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + surpressBlurAndFocus = PR_TRUE; + } + + if(!surpressBlurAndFocus) { if (nsnull != aEvent->widget) { aEvent->widget->SetFocus(); } - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + if (focusChangeFailed) { + SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + } } } - SetContentState(newFocus, NS_EVENT_STATE_ACTIVE); - } - } break; case NS_MOUSE_LEFT_BUTTON_UP: @@ -1093,17 +1243,34 @@ nsEventStateManager::DispatchKeyPressEvent(nsIPresContext& aPresContext, } PRBool -nsEventStateManager::ChangeFocus(nsIContent* aFocus, PRBool aSetFocus) +nsEventStateManager::ChangeFocus(nsIContent* aFocusContent, nsIFrame* aFocusFrame, PRBool aSetFocus) { - nsCOMPtr focusChange = do_QueryInterface(aFocus); + nsCOMPtr focusChange = do_QueryInterface(aFocusContent); if (focusChange) { - if (aSetFocus) { - focusChange->SetFocus(mPresContext); + + PRBool surpressBlurAndFocus = PR_FALSE; + nsCOMPtr context; + aFocusFrame->GetStyleContext(getter_AddRefs(context)); + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + surpressBlurAndFocus = PR_TRUE; } - else { + + if(!surpressBlurAndFocus) { + if (aSetFocus) { + + mLastFocusedContent = nsnull; + focusChange->SetFocus(mPresContext); + mLastFocusedContent = aFocusContent; + + + } else { focusChange->RemoveFocus(mPresContext); } + } return PR_TRUE; } //XXX Need to deal with Object tag @@ -1168,7 +1335,7 @@ nsEventStateManager::ShiftFocus(PRBool forward) return; } - ChangeFocus(next, PR_TRUE); + ChangeFocus(next, mCurrentTarget, PR_TRUE); NS_IF_RELEASE(mCurrentFocus); mCurrentFocus = next; @@ -1550,6 +1717,28 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo return NS_OK; } + + + PRBool surpressBlurAndFocus = PR_FALSE; + + + + if(mCurrentTarget) { + nsCOMPtr context; + mCurrentTarget->GetStyleContext(getter_AddRefs(context)); + if(!context) return NS_OK; + + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + surpressBlurAndFocus = PR_TRUE; + } + + } + + if(!surpressBlurAndFocus) { + nsIContent* targetBeforeEvent = mCurrentTargetContent; if (mCurrentFocus) { @@ -1560,7 +1749,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo // not receive the event. nsresult result = mCurrentFocus->GetDocument(*getter_AddRefs(doc)); if (NS_SUCCEEDED(result) && doc) { - ChangeFocus(mCurrentFocus, PR_FALSE); + ChangeFocus(mCurrentFocus, mCurrentTarget, PR_FALSE); //fire blur nsEventStatus status = nsEventStatus_eIgnore; @@ -1667,6 +1856,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo } + } + return NS_OK; } diff --git a/mozilla/content/events/src/nsEventStateManager.h b/mozilla/content/events/src/nsEventStateManager.h index 3365435e437..13239894b82 100644 --- a/mozilla/content/events/src/nsEventStateManager.h +++ b/mozilla/content/events/src/nsEventStateManager.h @@ -73,7 +73,7 @@ protected: NS_IMETHOD DispatchKeyPressEvent(nsIPresContext& aPresContext, nsKeyEvent *aEvent, nsEventStatus& aStatus); NS_IMETHOD SetClickCount(nsIPresContext& aPresContext, nsMouseEvent *aEvent, nsEventStatus& aStatus); NS_IMETHOD CheckForAndDispatchClick(nsIPresContext& aPresContext, nsMouseEvent *aEvent, nsEventStatus& aStatus); - PRBool ChangeFocus(nsIContent* aFocus, PRBool aSetFocus); + PRBool ChangeFocus(nsIContent* aFocus, nsIFrame* aFocusFrame, PRBool aSetFocus); void ShiftFocus(PRBool foward); nsIContent* GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool foward); PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward); diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index dd1b4ead4e4..62b0e1f3f88 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -2968,7 +2968,8 @@ GlobalWindowImpl::HandleDOMEvent(nsIPresContext& aPresContext, // Bubble to a chrome document if it exists // XXX Need a way to know if an event should really bubble or not. // For now filter out load and unload, since they cause problems. - if (aEvent->message != NS_PAGE_LOAD && aEvent->message != NS_PAGE_UNLOAD) { + if (aEvent->message != NS_PAGE_LOAD && aEvent->message != NS_PAGE_UNLOAD && aEvent->message != NS_FOCUS_CONTENT + && aEvent->message != NS_BLUR_CONTENT) { mChromeElement->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, NS_EVENT_FLAG_BUBBLE, aEventStatus); } } diff --git a/mozilla/layout/events/src/nsEventStateManager.cpp b/mozilla/layout/events/src/nsEventStateManager.cpp index 8ac3bea5be1..5d76500ace9 100644 --- a/mozilla/layout/events/src/nsEventStateManager.cpp +++ b/mozilla/layout/events/src/nsEventStateManager.cpp @@ -45,6 +45,8 @@ #include "nsIDOMSelection.h" #include "nsIFrameSelection.h" #include "nsIDeviceContext.h" +#include "nsIScriptContextOwner.h" +#include "nsIScriptGlobalObject.h" static NS_DEFINE_IID(kIEventStateManagerIID, NS_IEVENTSTATEMANAGER_IID); @@ -114,6 +116,9 @@ NS_IMPL_ADDREF(nsEventStateManager) NS_IMPL_RELEASE(nsEventStateManager) NS_IMPL_QUERY_INTERFACE(nsEventStateManager, kIEventStateManagerIID); +// This must be the same across instances +static nsCOMPtr mLastFocusedContent; + NS_IMETHODIMP nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, nsGUIEvent *aEvent, @@ -177,6 +182,112 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, GenerateDragDropEnterExit(aPresContext, aEvent); break; case NS_GOTFOCUS: + { + nsCOMPtr oldFocusedContent; + mCurrentTarget->GetContent(getter_AddRefs(oldFocusedContent)); + if(mLastFocusedContent == oldFocusedContent) + break; + + // ask focus target about its CSS user-focus style + PRBool surpressBlurAndFocus = PR_FALSE; + nsCOMPtr context; + mCurrentTarget->GetStyleContext(getter_AddRefs(context)); + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus based on user-focus: ignore; + surpressBlurAndFocus = PR_TRUE; + } + + if(!surpressBlurAndFocus) { + // TODO: fire blur only if the focus target is not a child of the currently focused node + // (it would just get focus again a second later) + PRBool isChild = PR_FALSE; + + if(!isChild){ + // Ask if the last focused content can accept blur + nsCOMPtr oldFocus = mLastFocusedContent; + if (oldFocus) { + nsIFocusableContent *focusChange; + if (NS_SUCCEEDED(oldFocus->QueryInterface(kIFocusableContentIID, (void **)&focusChange))) { + NS_RELEASE(focusChange); + + //fire blur only if target can accept focus + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_BLUR_CONTENT; + + if (!mDocument) { + nsCOMPtr presShell; + aPresContext.GetShell(getter_AddRefs(presShell)); + if (presShell) { + presShell->GetDocument(&mDocument); + } + } + + if (mDocument) { + mCurrentTarget = nsnull; + + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; + + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + } + } + } + } + + // Ask if target can accept focus + mCurrentTarget = aTargetFrame; + + //fire focus + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent focusevent; + focusevent.eventStructType = NS_EVENT; + focusevent.message = NS_FOCUS_CONTENT; + + if (!mDocument) { + nsCOMPtr presShell; + aPresContext.GetShell(getter_AddRefs(presShell)); + if (presShell) { + presShell->GetDocument(&mDocument); + } + } + + if (mDocument) { + nsCOMPtr newFoo; + mCurrentTarget->GetContent(getter_AddRefs(newFoo)); + mLastFocusedContent = newFoo; + + mCurrentTarget = nsnull; + // fire focus on window, not document + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; + + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, status); + } + } + } + break; + + case NS_LOSTFOCUS: + { + // Hold the blur, wait for the focus so we can query the style of the focus + // target as to what to do with the event. If appropriate we fire the blur + // at that time. + } + break; + + case NS_ACTIVATE: { nsIContent* newFocus; mCurrentTarget->GetContent(&newFocus); @@ -190,12 +301,12 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, } NS_RELEASE(newFocus); } - + //fire focus nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event; - event.eventStructType = NS_EVENT; - event.message = NS_FOCUS_CONTENT; + nsEvent focusevent; + focusevent.eventStructType = NS_EVENT; + focusevent.message = NS_FOCUS_CONTENT; if (!mDocument) { nsCOMPtr presShell; @@ -206,46 +317,70 @@ nsEventStateManager::PreHandleEvent(nsIPresContext& aPresContext, } if (mDocument) { + mCurrentTarget->GetContent(getter_AddRefs(mLastFocusedContent)); + mCurrentTarget = nsnull; - mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + + // fire focus on window, not document + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; + + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &focusevent, nsnull, NS_EVENT_FLAG_INIT, status); } + } break; - case NS_LOSTFOCUS: + + case NS_DEACTIVATE: { - nsIContent* oldFocus; - mCurrentTarget->GetContent(&oldFocus); - if (oldFocus) { + nsIContent* newFocus; + mCurrentTarget->GetContent(&newFocus); + if (newFocus) { nsIFocusableContent *focusChange; - if (NS_SUCCEEDED(oldFocus->QueryInterface(kIFocusableContentIID, + if (NS_SUCCEEDED(newFocus->QueryInterface(kIFocusableContentIID, (void **)&focusChange))) { NS_RELEASE(focusChange); - NS_RELEASE(oldFocus); + NS_RELEASE(newFocus); break; } - NS_RELEASE(oldFocus); + NS_RELEASE(newFocus); } + + //fire blur + nsEventStatus status = nsEventStatus_eIgnore; + nsEvent event; + event.eventStructType = NS_EVENT; + event.message = NS_BLUR_CONTENT; - //fire blur - nsEventStatus status = nsEventStatus_eIgnore; - nsEvent event; - event.eventStructType = NS_EVENT; - event.message = NS_BLUR_CONTENT; + if (!mDocument) { + nsCOMPtr presShell; + aPresContext.GetShell(getter_AddRefs(presShell)); + if (presShell) { + presShell->GetDocument(&mDocument); + } + } + + if (mDocument) { + mCurrentTarget = nsnull; - if (!mDocument) { - nsCOMPtr presShell; - aPresContext.GetShell(getter_AddRefs(presShell)); - if (presShell) { - presShell->GetDocument(&mDocument); - } - } + // fire focus on window, not document + nsCOMPtr contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner()); + if(!contextOwner) break; - if (mDocument) { - mCurrentTarget = nsnull; - mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); - } - } + nsCOMPtr globalObject; + contextOwner->GetScriptGlobalObject(getter_AddRefs(globalObject)); + if(!globalObject) break; + + globalObject->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status); + } + + } break; + case NS_KEY_PRESS: case NS_KEY_DOWN: case NS_KEY_UP: @@ -444,25 +579,40 @@ nsEventStateManager::PostHandleEvent(nsIPresContext& aPresContext, if (focusable) { if (current.get() != mCurrentFocus) { nsCOMPtr content = do_QueryInterface(focusable); - if (ChangeFocus(content, PR_TRUE)) + if (ChangeFocus(content, mCurrentTarget, PR_TRUE)) focusChangeFailed = PR_FALSE; } else { focusChangeFailed = PR_FALSE; } } - if (focusChangeFailed) { + // ask focus target the magic question + PRBool surpressBlurAndFocus = PR_FALSE; + nsCOMPtr context; + + if(!mCurrentTarget) break; + mCurrentTarget->GetStyleContext(getter_AddRefs(context)); + if(!context) break; + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if(!styleStruct) break; + + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + surpressBlurAndFocus = PR_TRUE; + } + + if(!surpressBlurAndFocus) { if (nsnull != aEvent->widget) { aEvent->widget->SetFocus(); } - SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + if (focusChangeFailed) { + SetContentState(nsnull, NS_EVENT_STATE_FOCUS); + } } } - SetContentState(newFocus, NS_EVENT_STATE_ACTIVE); - } - } break; case NS_MOUSE_LEFT_BUTTON_UP: @@ -1093,17 +1243,34 @@ nsEventStateManager::DispatchKeyPressEvent(nsIPresContext& aPresContext, } PRBool -nsEventStateManager::ChangeFocus(nsIContent* aFocus, PRBool aSetFocus) +nsEventStateManager::ChangeFocus(nsIContent* aFocusContent, nsIFrame* aFocusFrame, PRBool aSetFocus) { - nsCOMPtr focusChange = do_QueryInterface(aFocus); + nsCOMPtr focusChange = do_QueryInterface(aFocusContent); if (focusChange) { - if (aSetFocus) { - focusChange->SetFocus(mPresContext); + + PRBool surpressBlurAndFocus = PR_FALSE; + nsCOMPtr context; + aFocusFrame->GetStyleContext(getter_AddRefs(context)); + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + surpressBlurAndFocus = PR_TRUE; } - else { + + if(!surpressBlurAndFocus) { + if (aSetFocus) { + + mLastFocusedContent = nsnull; + focusChange->SetFocus(mPresContext); + mLastFocusedContent = aFocusContent; + + + } else { focusChange->RemoveFocus(mPresContext); } + } return PR_TRUE; } //XXX Need to deal with Object tag @@ -1168,7 +1335,7 @@ nsEventStateManager::ShiftFocus(PRBool forward) return; } - ChangeFocus(next, PR_TRUE); + ChangeFocus(next, mCurrentTarget, PR_TRUE); NS_IF_RELEASE(mCurrentFocus); mCurrentFocus = next; @@ -1550,6 +1717,28 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo return NS_OK; } + + + PRBool surpressBlurAndFocus = PR_FALSE; + + + + if(mCurrentTarget) { + nsCOMPtr context; + mCurrentTarget->GetStyleContext(getter_AddRefs(context)); + if(!context) return NS_OK; + + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + surpressBlurAndFocus = PR_TRUE; + } + + } + + if(!surpressBlurAndFocus) { + nsIContent* targetBeforeEvent = mCurrentTargetContent; if (mCurrentFocus) { @@ -1560,7 +1749,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo // not receive the event. nsresult result = mCurrentFocus->GetDocument(*getter_AddRefs(doc)); if (NS_SUCCEEDED(result) && doc) { - ChangeFocus(mCurrentFocus, PR_FALSE); + ChangeFocus(mCurrentFocus, mCurrentTarget, PR_FALSE); //fire blur nsEventStatus status = nsEventStatus_eIgnore; @@ -1667,6 +1856,8 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo } + } + return NS_OK; } diff --git a/mozilla/layout/events/src/nsEventStateManager.h b/mozilla/layout/events/src/nsEventStateManager.h index 3365435e437..13239894b82 100644 --- a/mozilla/layout/events/src/nsEventStateManager.h +++ b/mozilla/layout/events/src/nsEventStateManager.h @@ -73,7 +73,7 @@ protected: NS_IMETHOD DispatchKeyPressEvent(nsIPresContext& aPresContext, nsKeyEvent *aEvent, nsEventStatus& aStatus); NS_IMETHOD SetClickCount(nsIPresContext& aPresContext, nsMouseEvent *aEvent, nsEventStatus& aStatus); NS_IMETHOD CheckForAndDispatchClick(nsIPresContext& aPresContext, nsMouseEvent *aEvent, nsEventStatus& aStatus); - PRBool ChangeFocus(nsIContent* aFocus, PRBool aSetFocus); + PRBool ChangeFocus(nsIContent* aFocus, nsIFrame* aFocusFrame, PRBool aSetFocus); void ShiftFocus(PRBool foward); nsIContent* GetNextTabbableContent(nsIContent* aParent, nsIContent* aChild, nsIContent* aTop, PRBool foward); PRInt32 GetNextTabIndex(nsIContent* aParent, PRBool foward); diff --git a/mozilla/layout/xul/base/src/nsToolbarFrame.cpp b/mozilla/layout/xul/base/src/nsToolbarFrame.cpp index 547aab89624..d879caa422f 100644 --- a/mozilla/layout/xul/base/src/nsToolbarFrame.cpp +++ b/mozilla/layout/xul/base/src/nsToolbarFrame.cpp @@ -335,6 +335,41 @@ nsToolbarFrame :: GetFrameForPoint ( nsIPresContext* aPresContext, } // GetFrameForPoint +// +// HandleEvent +// +// Process events that come to this frame. If they end up here, they are +// almost certainly drag and drop events. +// +NS_IMETHODIMP +nsToolbarFrame :: HandleEvent ( nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus) +{ + if ( !aEvent ) + return nsEventStatus_eIgnore; + + switch (aEvent->message) { + + case NS_MOUSE_ACTIVATE: + // Does the toolbar accept activation/focus? Check style + nsCOMPtr context; + GetStyleContext(getter_AddRefs(context)); + + const nsStyleUserInterface* styleStruct = (const nsStyleUserInterface*)context->GetStyleData(eStyleStruct_UserInterface); + if (NS_STYLE_USER_FOCUS_IGNORE == styleStruct->mUserFocus) { + // we want to surpress the blur and the following focus + if(aEvent->eventStructType == NS_MOUSE_EVENT) + ((nsMouseEvent*)aEvent)->acceptActivation = PR_FALSE; + } + break; + } + + //XXX this needs to change when I am really handling the D&D events + return nsBoxFrame::HandleEvent(aPresContext, aEvent, aEventStatus); + +} // HandleEvent + #if NOT_YET_NEEDED /** diff --git a/mozilla/layout/xul/base/src/nsToolbarFrame.h b/mozilla/layout/xul/base/src/nsToolbarFrame.h index 0e6d7d9e1be..a786932bb69 100644 --- a/mozilla/layout/xul/base/src/nsToolbarFrame.h +++ b/mozilla/layout/xul/base/src/nsToolbarFrame.h @@ -82,6 +82,10 @@ public: PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aHint) ; + + NS_IMETHOD HandleEvent ( nsIPresContext& aPresContext, + nsGUIEvent* aEvent, + nsEventStatus& aEventStatus); #if WTF_IS_THIS //еее not sure at all where this comes from. I asked rods, no reply yet. diff --git a/mozilla/widget/src/windows/nsWindow.cpp b/mozilla/widget/src/windows/nsWindow.cpp index 100e82db6d7..c8c877b52e1 100644 --- a/mozilla/widget/src/windows/nsWindow.cpp +++ b/mozilla/widget/src/windows/nsWindow.cpp @@ -2448,6 +2448,9 @@ BOOL nsWindow::OnChar( UINT mbcsCharCode, UINT virtualKeyCode, bool isMultiByte // Process all nsWindows messages // //------------------------------------------------------------------------- +static PRBool gJustGotDeactivate = PR_FALSE; +static PRBool gJustGotActivate = PR_FALSE; + PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *aRetValue) { static UINT vkKeyCached = 0; // caches VK code fon WM_KEYDOWN @@ -2770,12 +2773,48 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT result = PR_TRUE; break; + case WM_ACTIVATE: + if (mEventCallback) { + PRInt32 fActive = LOWORD(wParam); + + if(WA_INACTIVE == fActive) { + gJustGotDeactivate = PR_TRUE; + result = DispatchFocus(NS_DEACTIVATE); + } else { + gJustGotActivate = PR_TRUE; + nsMouseEvent event; + event.eventStructType = NS_GUI_EVENT; + InitEvent(event, NS_MOUSE_ACTIVATE); + + event.acceptActivation = PR_TRUE; + + PRBool result = DispatchWindowEvent(&event); + NS_RELEASE(event.widget); + + if(event.acceptActivation) + *aRetValue = MA_ACTIVATE; + else + *aRetValue = MA_NOACTIVATE; + } + } + break; + case WM_SETFOCUS: + if(gJustGotActivate) { + result = DispatchFocus(NS_ACTIVATE); + gJustGotActivate = PR_FALSE; + } else { result = DispatchFocus(NS_GOTFOCUS); + } break; case WM_KILLFOCUS: + if(gJustGotDeactivate) { + result = DispatchFocus(NS_DEACTIVATE); + gJustGotDeactivate = PR_FALSE; + } else { result = DispatchFocus(NS_LOSTFOCUS); + } break; case WM_WINDOWPOSCHANGED: diff --git a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp index a62ecebf775..a89b661f28f 100644 --- a/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp +++ b/mozilla/xpfe/appshell/src/nsWebShellWindow.cpp @@ -543,6 +543,8 @@ nsWebShellWindow::HandleEvent(nsGUIEvent *aEvent) break; } + case NS_MOUSE_ACTIVATE: + case NS_ACTIVATE: case NS_GOTFOCUS: { void* data; aEvent->widget->GetClientData(data); diff --git a/mozilla/xpfe/browser/resources/skin/navigator.css b/mozilla/xpfe/browser/resources/skin/navigator.css index 5b364eef0f6..ec8c2c50911 100644 --- a/mozilla/xpfe/browser/resources/skin/navigator.css +++ b/mozilla/xpfe/browser/resources/skin/navigator.css @@ -37,6 +37,7 @@ titledbutton#reload-button { margin: 0px; font: inherit; border: none; + user-focus: normal; } box#url-bar-box { diff --git a/mozilla/xpfe/global/resources/skin/xul.css b/mozilla/xpfe/global/resources/skin/xul.css index c7dd47d61be..f65ac8369c2 100644 --- a/mozilla/xpfe/global/resources/skin/xul.css +++ b/mozilla/xpfe/global/resources/skin/xul.css @@ -66,6 +66,7 @@ spring { toolbox { display: block; + user-focus: ignore; } toolbar, menubar {