Patch that gets tabbing back into text fields. r=waterson

This commit is contained in:
hyatt%netscape.com 1999-12-21 19:35:13 +00:00
Родитель b34e26f745
Коммит 563b3b509d
7 изменённых файлов: 79 добавлений и 57 удалений

Просмотреть файл

@ -700,6 +700,10 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
if (!keyEvent->isAlt) {
switch(keyEvent->keyCode) {
case NS_VK_TAB:
if (mConsumeFocusEvents) {
mConsumeFocusEvents = PR_FALSE;
break;
}
//Shift focus forward or back depending on shift key
ShiftFocus(!((nsInputEvent*)aEvent)->isShift);
*aStatus = nsEventStatus_eConsumeNoDefault;
@ -1490,6 +1494,17 @@ nsEventStateManager::ShiftFocus(PRBool forward)
return;
}
// Now we need to get the content node's frame and reset
// the mCurrentTarget target. Otherwise the focus
// code will be slightly out of sync (with regards to
// focusing widgets within the current target).
nsCOMPtr<nsIPresShell> shell;
if (mPresContext) {
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
shell->GetPrimaryFrameFor(next, &mCurrentTarget);
}
}
ChangeFocus(next, mCurrentTarget, PR_TRUE);
NS_IF_RELEASE(mCurrentFocus);
@ -1917,6 +1932,9 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
}
}
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (nsnull != gLastFocusedPresContext) {
if (gLastFocusedContent) {
@ -1925,7 +1943,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// the Ender widget case.
nsCOMPtr<nsIDocument> doc;
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
if(doc) {
if (doc) {
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(doc->GetShellAt(0));
nsCOMPtr<nsIPresContext> oldPresContext;
shell->GetPresContext(getter_AddRefs(oldPresContext));
@ -1947,10 +1965,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Go ahead and fire a blur on the window.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (!mDocument) {
if (presShell) {
presShell->GetDocument(&mDocument);
@ -2001,32 +2016,19 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
}
}
// XXx The following line could be bad in the case where a
// parent element is really the one with the focus.
nsIFrame * currentFocusFrame = mCurrentTarget;
// Check to see if the newly focused content's frame has a view with a widget
// i.e TextField or TextArea, if so, don't set the focus on their window
PRBool shouldSetFocusOnWindow = PR_TRUE;
if (nsnull != currentFocusFrame) {
nsIView * view = nsnull;
currentFocusFrame->GetView(aPresContext, &view);
if (view != nsnull) {
nsIWidget *window = nsnull;
view->GetWidget(window);
if (window != nsnull) { // addrefs
shouldSetFocusOnWindow = PR_FALSE;
NS_RELEASE(window);
}
}
}
// Find the window that this frame is in and
// make sure it has focus
// XXX Note: mLastWindowToHaveFocus this does not track when ANY focus
// event comes through, the only place this gets set is here
// so some windows may get multiple focus events
// For example, if you clicked in the window (generates focus event)
// then click on a gfx control (generates another focus event)
if (shouldSetFocusOnWindow && nsnull != currentFocusFrame) {
// GFX Text Control frames handle their own focus
// and must be special-cased.
nsCOMPtr<nsIGfxTextControlFrame> gfxFrame = do_QueryInterface(currentFocusFrame);
if (gfxFrame) {
gfxFrame->SetInnerFocus();
}
else if (currentFocusFrame) {
nsIFrame * parentFrame;
currentFocusFrame->GetParentWithView(aPresContext, &parentFrame);
if (nsnull != parentFrame) {

Просмотреть файл

@ -700,6 +700,10 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
if (!keyEvent->isAlt) {
switch(keyEvent->keyCode) {
case NS_VK_TAB:
if (mConsumeFocusEvents) {
mConsumeFocusEvents = PR_FALSE;
break;
}
//Shift focus forward or back depending on shift key
ShiftFocus(!((nsInputEvent*)aEvent)->isShift);
*aStatus = nsEventStatus_eConsumeNoDefault;
@ -1490,6 +1494,17 @@ nsEventStateManager::ShiftFocus(PRBool forward)
return;
}
// Now we need to get the content node's frame and reset
// the mCurrentTarget target. Otherwise the focus
// code will be slightly out of sync (with regards to
// focusing widgets within the current target).
nsCOMPtr<nsIPresShell> shell;
if (mPresContext) {
nsresult rv = mPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
shell->GetPrimaryFrameFor(next, &mCurrentTarget);
}
}
ChangeFocus(next, mCurrentTarget, PR_TRUE);
NS_IF_RELEASE(mCurrentFocus);
@ -1917,6 +1932,9 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
}
}
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (nsnull != gLastFocusedPresContext) {
if (gLastFocusedContent) {
@ -1925,7 +1943,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// the Ender widget case.
nsCOMPtr<nsIDocument> doc;
gLastFocusedContent->GetDocument(*getter_AddRefs(doc));
if(doc) {
if (doc) {
nsCOMPtr<nsIPresShell> shell = getter_AddRefs(doc->GetShellAt(0));
nsCOMPtr<nsIPresContext> oldPresContext;
shell->GetPresContext(getter_AddRefs(oldPresContext));
@ -1947,10 +1965,7 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
// Go ahead and fire a blur on the window.
nsCOMPtr<nsIScriptGlobalObject> globalObject;
gLastFocusedDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (!mDocument) {
if (presShell) {
presShell->GetDocument(&mDocument);
@ -2001,32 +2016,19 @@ nsEventStateManager::SendFocusBlur(nsIPresContext* aPresContext, nsIContent *aCo
}
}
// XXx The following line could be bad in the case where a
// parent element is really the one with the focus.
nsIFrame * currentFocusFrame = mCurrentTarget;
// Check to see if the newly focused content's frame has a view with a widget
// i.e TextField or TextArea, if so, don't set the focus on their window
PRBool shouldSetFocusOnWindow = PR_TRUE;
if (nsnull != currentFocusFrame) {
nsIView * view = nsnull;
currentFocusFrame->GetView(aPresContext, &view);
if (view != nsnull) {
nsIWidget *window = nsnull;
view->GetWidget(window);
if (window != nsnull) { // addrefs
shouldSetFocusOnWindow = PR_FALSE;
NS_RELEASE(window);
}
}
}
// Find the window that this frame is in and
// make sure it has focus
// XXX Note: mLastWindowToHaveFocus this does not track when ANY focus
// event comes through, the only place this gets set is here
// so some windows may get multiple focus events
// For example, if you clicked in the window (generates focus event)
// then click on a gfx control (generates another focus event)
if (shouldSetFocusOnWindow && nsnull != currentFocusFrame) {
// GFX Text Control frames handle their own focus
// and must be special-cased.
nsCOMPtr<nsIGfxTextControlFrame> gfxFrame = do_QueryInterface(currentFocusFrame);
if (gfxFrame) {
gfxFrame->SetInnerFocus();
}
else if (currentFocusFrame) {
nsIFrame * parentFrame;
currentFocusFrame->GetParentWithView(aPresContext, &parentFrame);
if (nsnull != parentFrame) {

Просмотреть файл

@ -37,4 +37,5 @@ public:
NS_IMETHOD GetEditor(nsIEditor **aEditor) = 0;
NS_IMETHOD GetWebShell(nsIWebShell** aWebShell) = 0;
NS_IMETHOD SetInnerFocus() = 0;
};

Просмотреть файл

@ -37,4 +37,5 @@ public:
NS_IMETHOD GetEditor(nsIEditor **aEditor) = 0;
NS_IMETHOD GetWebShell(nsIWebShell** aWebShell) = 0;
NS_IMETHOD SetInnerFocus() = 0;
};

Просмотреть файл

@ -37,4 +37,5 @@ public:
NS_IMETHOD GetEditor(nsIEditor **aEditor) = 0;
NS_IMETHOD GetWebShell(nsIWebShell** aWebShell) = 0;
NS_IMETHOD SetInnerFocus() = 0;
};

Просмотреть файл

@ -238,6 +238,13 @@ nsGfxTextControlFrame::GetWebShell(nsIWebShell **aWebShell)
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame::SetInnerFocus()
{
SetFocus();
return NS_OK;
}
NS_IMETHODIMP
nsGfxTextControlFrame::CreateEditor()
{
@ -3355,8 +3362,16 @@ nsEnderEventListener::KeyPress(nsIDOMEvent* aKeyEvent)
}
NS_RELEASE(manager);
if(event.flags & NS_EVENT_FLAG_STOP_DISPATCH)
{
// Call consume focus events on the inner event state manager to prevent its
// PostHandleEvent from immediately blurring us.
nsCOMPtr<nsIPresContext> pc;
mInnerShell->GetPresContext(getter_AddRefs(pc));
nsCOMPtr<nsIEventStateManager> esm;
pc->GetEventStateManager(getter_AddRefs(esm));
esm->ConsumeFocusEvents(PR_TRUE);
if(event.flags & NS_EVENT_FLAG_STOP_DISPATCH) {
aKeyEvent->PreventCapture();
aKeyEvent->PreventBubble();
}
@ -3437,7 +3452,6 @@ nsEnderEventListener::DispatchMouseEvent(nsIDOMMouseEvent *aEvent, PRInt32 aEven
nsCOMPtr<nsIEventStateManager> esm;
pc->GetEventStateManager(getter_AddRefs(esm));
esm->ConsumeFocusEvents(PR_TRUE);
// Now set the focus in to the widget.
mFrame->SetFocus();
}
}

Просмотреть файл

@ -510,6 +510,7 @@ public:
/* ============= nsIGfxTextControlFrame ================= */
NS_IMETHOD GetEditor(nsIEditor **aEditor);
NS_IMETHOD GetWebShell(nsIWebShell **aWebShell);
NS_IMETHOD SetInnerFocus();
protected: