From 873a8e8c624e78508bf81b5bd35e8e2b4953da14 Mon Sep 17 00:00:00 2001 From: "aaronleventhal@moonset.net" Date: Wed, 27 Feb 2008 08:22:41 -0800 Subject: [PATCH] Bug 406308. Don't fire accessible focus events if widget is not actually in focus, confuses screen readers. r=ginn, r=surkov, a=beltzner for 1.9b4 --- accessible/src/base/nsRootAccessible.cpp | 27 +++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index 2f1b0f752c14..026d62931409 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -845,6 +845,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, } } else if (eventType.EqualsLiteral("DOMMenuItemActive")) { + PRBool fireFocus = PR_FALSE; if (!treeItemAccessible) { #ifdef MOZ_XUL if (isTree) { @@ -857,6 +858,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, NS_ENSURE_TRUE(menuFrame, NS_ERROR_FAILURE); nsIMenuFrame* imenuFrame; CallQueryInterface(menuFrame, &imenuFrame); + if (imenuFrame) + fireFocus = PR_TRUE; // QI failed for nsIMenuFrame means it's not on menu bar if (imenuFrame && imenuFrame->IsOnMenuBar() && !imenuFrame->IsOnActiveMenuBar()) { @@ -870,7 +873,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, // It is not top level menuitem // Only fire focus event if it is not inside collapsed popup // and not a listitem of a combo box - if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) { + if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) { nsCOMPtr containerParent; containerAccessible->GetParent(getter_AddRefs(containerParent)); NS_ENSURE_TRUE(containerParent, NS_ERROR_FAILURE); @@ -880,8 +883,26 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, } } } - nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input - FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE, PR_TRUE); + if (!fireFocus) { + nsCOMPtr realFocusedNode = GetCurrentFocus(); + nsCOMPtr realFocusedContent = do_QueryInterface(realFocusedNode); + nsCOMPtr targetContent = do_QueryInterface(aTargetNode); + nsIContent *containerContent = targetContent; + while (containerContent) { + nsCOMPtr popup = do_QueryInterface(containerContent); + if (popup || containerContent == realFocusedContent) { + // If we're inside the focus or a popup we can fire focus events + // for the changed active item + fireFocus = PR_TRUE; + break; + } + containerContent = containerContent->GetParent(); + } + } + if (fireFocus) { + nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input + FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE, PR_TRUE); + } } else if (eventType.EqualsLiteral("DOMMenuBarActive")) { // Always asynch, always from user input nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);