Landing focus changes. R: joki

This commit is contained in:
saari%netscape.com 1999-11-13 05:16:33 +00:00
parent 38ad4a2ec2
commit 1cfbe7d9a6
11 changed files with 552 additions and 87 deletions

View File

@ -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<nsIContent> 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<nsIContent> oldFocusedContent;
mCurrentTarget->GetContent(getter_AddRefs(oldFocusedContent));
if(mLastFocusedContent == oldFocusedContent)
break;
// ask focus target about its CSS user-focus style
PRBool surpressBlurAndFocus = PR_FALSE;
nsCOMPtr<nsIStyleContext> 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<nsIContent> 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<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
if (mDocument) {
mCurrentTarget = nsnull;
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
nsCOMPtr<nsIScriptGlobalObject> 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<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
if (mDocument) {
nsCOMPtr<nsIContent> newFoo;
mCurrentTarget->GetContent(getter_AddRefs(newFoo));
mLastFocusedContent = newFoo;
mCurrentTarget = nsnull;
// fire focus on window, not document
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
nsCOMPtr<nsIScriptGlobalObject> 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<nsIPresShell> 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<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
nsCOMPtr<nsIScriptGlobalObject> 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<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
if (mDocument) {
mCurrentTarget = nsnull;
if (!mDocument) {
nsCOMPtr<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
// fire focus on window, not document
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
if (mDocument) {
mCurrentTarget = nsnull;
mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
nsCOMPtr<nsIScriptGlobalObject> 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<nsIContent> 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<nsIStyleContext> 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<nsIFocusableContent> focusChange = do_QueryInterface(aFocus);
nsCOMPtr<nsIFocusableContent> focusChange = do_QueryInterface(aFocusContent);
if (focusChange) {
if (aSetFocus) {
focusChange->SetFocus(mPresContext);
PRBool surpressBlurAndFocus = PR_FALSE;
nsCOMPtr<nsIStyleContext> 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<nsIStyleContext> 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;
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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<nsIContent> 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<nsIContent> oldFocusedContent;
mCurrentTarget->GetContent(getter_AddRefs(oldFocusedContent));
if(mLastFocusedContent == oldFocusedContent)
break;
// ask focus target about its CSS user-focus style
PRBool surpressBlurAndFocus = PR_FALSE;
nsCOMPtr<nsIStyleContext> 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<nsIContent> 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<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
if (mDocument) {
mCurrentTarget = nsnull;
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
nsCOMPtr<nsIScriptGlobalObject> 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<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
if (mDocument) {
nsCOMPtr<nsIContent> newFoo;
mCurrentTarget->GetContent(getter_AddRefs(newFoo));
mLastFocusedContent = newFoo;
mCurrentTarget = nsnull;
// fire focus on window, not document
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
nsCOMPtr<nsIScriptGlobalObject> 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<nsIPresShell> 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<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
nsCOMPtr<nsIScriptGlobalObject> 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<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
if (mDocument) {
mCurrentTarget = nsnull;
if (!mDocument) {
nsCOMPtr<nsIPresShell> presShell;
aPresContext.GetShell(getter_AddRefs(presShell));
if (presShell) {
presShell->GetDocument(&mDocument);
}
}
// fire focus on window, not document
nsCOMPtr<nsIScriptContextOwner> contextOwner = dont_QueryInterface(mDocument->GetScriptContextOwner());
if(!contextOwner) break;
if (mDocument) {
mCurrentTarget = nsnull;
mDocument->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
}
}
nsCOMPtr<nsIScriptGlobalObject> 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<nsIContent> 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<nsIStyleContext> 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<nsIFocusableContent> focusChange = do_QueryInterface(aFocus);
nsCOMPtr<nsIFocusableContent> focusChange = do_QueryInterface(aFocusContent);
if (focusChange) {
if (aSetFocus) {
focusChange->SetFocus(mPresContext);
PRBool surpressBlurAndFocus = PR_FALSE;
nsCOMPtr<nsIStyleContext> 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<nsIStyleContext> 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;
}

View File

@ -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);

View File

@ -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<nsIStyleContext> 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
/**

View File

@ -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.

View File

@ -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:

View File

@ -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);

View File

@ -37,6 +37,7 @@ titledbutton#reload-button {
margin: 0px;
font: inherit;
border: none;
user-focus: normal;
}
box#url-bar-box {

View File

@ -66,6 +66,7 @@ spring {
toolbox {
display: block;
user-focus: ignore;
}
toolbar, menubar {