Bug 412288 Toolbar menus do not have ATK state focusable patch by Marco Zehe r=ginn.chen, aaronleventhal sr=mtschrep
authorginn.chen@sun.com
Wed, 16 Jan 2008 22:30:15 -0800
changeset 10350 e75eae5157bf7f737103bfe2b034842da0cb763f
parent 10349 5e11b04e7823c2f025bae49baa337ef3157d237c
child 10351 d7a600e2cbc0a6256a44456a9c915c3718b622b8
push idunknown
push userunknown
push dateunknown
reviewersginn, mtschrep
bugs412288
milestone1.9b3pre
Bug 412288 Toolbar menus do not have ATK state focusable patch by Marco Zehe r=ginn.chen, aaronleventhal sr=mtschrep
accessible/src/xul/nsXULMenuAccessible.cpp
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -46,18 +46,22 @@
 #include "nsIDOMKeyEvent.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIServiceManager.h"
 #include "nsIPresShell.h"
 #include "nsIContent.h"
 #include "nsGUIEvent.h"
 #include "nsXULFormControlAccessible.h"
+#include "nsILookAndFeel.h"
+#include "nsWidgetsCID.h"
 
 
+static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
+
 /** ------------------------------------------------------ */
 /**  Impl. of nsXULSelectableAccessible                    */
 /** ------------------------------------------------------ */
 
 // Helper methos
 nsXULSelectableAccessible::nsXULSelectableAccessible(nsIDOMNode* aDOMNode,
                                                      nsIWeakReference* aShell):
 nsAccessibleWrap(aDOMNode, aShell)
@@ -317,38 +321,34 @@ nsXULMenuitemAccessible::GetState(PRUint
     nsAutoString checkValue;
     element->GetAttribute(NS_LITERAL_STRING("checked"), checkValue);
     if (checkValue.EqualsLiteral("true")) {
       *aState |= nsIAccessibleStates::STATE_CHECKED;
     }
   }
 
   // Combo box listitem
-  if (Role(this) == nsIAccessibleRole::ROLE_COMBOBOX_OPTION) {
+  PRBool isComboboxOption =
+    (Role(this) == nsIAccessibleRole::ROLE_COMBOBOX_OPTION);
+  if (isComboboxOption) {
     // Is selected?
     PRBool isSelected = PR_FALSE;
     nsCOMPtr<nsIDOMXULSelectControlItemElement>
       item(do_QueryInterface(mDOMNode));
     NS_ENSURE_TRUE(item, NS_ERROR_FAILURE);
     item->GetSelected(&isSelected);
 
     // Is collapsed?
     PRBool isCollapsed = PR_FALSE;
     nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
     if (parentAccessible &&
         State(parentAccessible) & nsIAccessibleStates::STATE_INVISIBLE) {
       isCollapsed = PR_TRUE;
     }
     
-    // Is disabled?
-    if (0 == (*aState & nsIAccessibleStates::STATE_UNAVAILABLE)) {
-      *aState |= (nsIAccessibleStates::STATE_FOCUSABLE |
-                  nsIAccessibleStates::STATE_SELECTABLE);
-    }
-
     if (isSelected) {
       *aState |= nsIAccessibleStates::STATE_SELECTED;
       
       // Selected and collapsed?
       if (isCollapsed) {
         // Set selected option offscreen/invisible according to combobox state
         nsCOMPtr<nsIAccessible> grandParentAcc;
         parentAccessible->GetParent(getter_AddRefs(grandParentAcc));
@@ -364,16 +364,33 @@ nsXULMenuitemAccessible::GetState(PRUint
         if (aExtraState) {
           *aExtraState |=
             grandParentExtState & nsIAccessibleStates::EXT_STATE_OPAQUE;
         }
       } // isCollapsed
     } // isSelected
   } // ROLE_COMBOBOX_OPTION
 
+  // Set focusable and selectable for items that are available
+  // and whose metric setting does allow disabled items to be focused.
+  if (*aState & nsIAccessibleStates::STATE_UNAVAILABLE) {
+    // Honour the LookAndFeel metric.
+    nsCOMPtr<nsILookAndFeel> lookNFeel(do_GetService(kLookAndFeelCID));
+    PRInt32 skipDisabledMenuItems = 0;
+    lookNFeel->GetMetric(nsILookAndFeel::eMetric_SkipNavigatingDisabledMenuItem,
+                         skipDisabledMenuItems);
+    // We don't want the focusable and selectable states for combobox items,
+    // so exclude them here as well.
+    if (skipDisabledMenuItems || isComboboxOption) {
+      return NS_OK;
+    }
+  }
+  *aState|= (nsIAccessibleStates::STATE_FOCUSABLE |
+             nsIAccessibleStates::STATE_SELECTABLE);
+
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULMenuitemAccessible::GetName(nsAString& _retval)
 {
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   if (!element) {
     return NS_ERROR_FAILURE;