Loading accessible/src/atk/nsAccessibleWrap.cpp +43 −41 Original line number Diff line number Diff line Loading @@ -1276,40 +1276,12 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent) *(gint *)eventData); break; // Is a superclass of ATK event children_changed case nsIAccessibleEvent::EVENT_REORDER: AtkChildrenChange *pAtkChildrenChange; MAI_LOG_DEBUG(("\n\nReceived: EVENT_REORDER(children_change)\n")); pAtkChildrenChange = NS_REINTERPRET_CAST(AtkChildrenChange *, eventData); nsAccessibleWrap *childAccWrap; if (pAtkChildrenChange && pAtkChildrenChange->child) { childAccWrap = NS_STATIC_CAST(nsAccessibleWrap *, pAtkChildrenChange->child); g_signal_emit_by_name (atkObj, pAtkChildrenChange->add ? \ "children_changed::add" : \ "children_changed::remove", pAtkChildrenChange->index, childAccWrap->GetAtkObject(), NULL); } else { // // EVENT_REORDER is normally fired by "HTML Document". // // In GOK, [only] "children_changed::add" can cause foreground // window accessible to update it children, which will // refresh "UI-Grab" window. // g_signal_emit_by_name (atkObj, "children_changed::add", -1, NULL, NULL); } case nsIAccessibleEvent::EVENT_SHOW: return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE); case nsIAccessibleEvent::EVENT_HIDE: return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE); break; /* * Because dealing with menu is very different between nsIAccessible * and ATK, and the menu activity is important, specially transfer the Loading Loading @@ -1368,18 +1340,14 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent) } break; case nsIAccessibleEvent::EVENT_MENUPOPUP_START: // fire extra focus event, then go down to EVENT_SHOW atk_focus_tracker_notify(atkObj); case nsIAccessibleEvent::EVENT_SHOW: MAI_LOG_DEBUG(("\n\nReceived: EVENT_SHOW\n")); MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n")); atk_focus_tracker_notify(atkObj); // fire extra focus event atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_TRUE); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_TRUE); break; case nsIAccessibleEvent::EVENT_HIDE: case nsIAccessibleEvent::EVENT_MENUPOPUP_END: MAI_LOG_DEBUG(("\n\nReceived: EVENT_HIDE\n")); MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_END\n")); atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_FALSE); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_FALSE); break; Loading Loading @@ -1528,3 +1496,37 @@ nsAccessibleWrap::FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent, return NS_OK; } nsresult nsAccessibleWrap::FireAtkShowHideEvent(nsIAccessibleEvent *aEvent, AtkObject *aObject, PRBool aIsAdded) { if (aIsAdded) MAI_LOG_DEBUG(("\n\nReceived: EVENT_SHOW\n")); else MAI_LOG_DEBUG(("\n\nReceived: EVENT_HIDE\n")); nsCOMPtr<nsIAccessible> accessible; aEvent->GetAccessible(getter_AddRefs(accessible)); NS_ENSURE_STATE(accessible); nsCOMPtr<nsIAccessible> parentAccessible; accessible->GetParent(getter_AddRefs(parentAccessible)); NS_ENSURE_STATE(parentAccessible); PRInt32 indexInParent = -1; accessible->GetIndexInParent(&indexInParent); AtkObject *parentObject = GetAtkObject(parentAccessible); NS_ENSURE_STATE(parentObject); g_signal_emit_by_name(parentObject, aIsAdded ? \ "children_changed::add" : \ "children_changed::remove", indexInParent, aObject, NULL); return NS_OK; } accessible/src/atk/nsAccessibleWrap.h +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,8 @@ protected: AtkObject *aObject); nsresult FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent, AtkObject *aObject); nsresult FireAtkShowHideEvent(nsIAccessibleEvent *aEvent, AtkObject *aObject, PRBool aIsAdded); AtkObject *mAtkObject; Loading accessible/src/base/nsAccessibleEventData.h +5 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ * Contributor(s): * Kyle Yuan (kyle.yuan@sun.com) * John Sun (john.sun@sun.com) * Alexander Surkov <surkov.alexander@gmail.com> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), Loading Loading @@ -128,14 +129,8 @@ private: PRInt32 mCaretOffset; }; // XXX todo: We might want to use XPCOM interfaces instead of structs // e.g., nsAccessibleTextChangeEvent: public nsIAccessibleTextChangeEvent struct AtkChildrenChange { PRInt32 index; // index of child in parent nsIAccessible *child; PRBool add; // true for add, false for delete }; // XXX todo: We might want to use XPCOM interfaces instead of struct // e.g., nsAccessibleTableChangeEvent: public nsIAccessibleTableChangeEvent struct AtkTableChange { PRUint32 index; // the start row/column after which the rows are inserted/deleted. Loading @@ -143,3 +138,4 @@ struct AtkTableChange { }; #endif accessible/src/base/nsDocAccessible.cpp +28 −26 Original line number Diff line number Diff line Loading @@ -1294,6 +1294,9 @@ void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure) void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent) { NS_ASSERTION(aChangeEvent != nsIAccessibleEvent::EVENT_SHOW, "nsDocAccessible::RefreshNodes isn't supposed to work with show event."); nsCOMPtr<nsIDOMNode> iterNode(aStartNode), nextNode; nsCOMPtr<nsIAccessNode> accessNode; Loading @@ -1306,12 +1309,11 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent // Don't shutdown our doc object! if (accessNode != NS_STATIC_CAST(nsIAccessNode*, this)) { if (aChangeEvent != nsIAccessibleEvent::EVENT_SHOW) { nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode)); if (accessible) { // Fire menupopupend events for menu popups that go away PRUint32 role, event = 0; accessible->GetFinalRole(&role); PRUint32 role = Role(accessible); if (role == nsIAccessibleRole::ROLE_MENUPOPUP) { nsCOMPtr<nsIDOMNode> domNode; accessNode->GetDOMNode(getter_AddRefs(domNode)); Loading @@ -1319,14 +1321,12 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent if (!popup) { // Popup elements already fire these via DOMMenuInactive // handling in nsRootAccessible::HandleEvent event = nsIAccessibleEvent::EVENT_MENUPOPUP_END; } } if (event) { FireToolkitEvent(event, accessible, nsnull); FireToolkitEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, accessible, nsnull); } } } void *uniqueID; accessNode->GetUniqueID(&uniqueID); nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode)); Loading Loading @@ -1403,6 +1403,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } nsCOMPtr<nsPIAccessible> privateChildAccessible = do_QueryInterface(childAccessible); NS_ENSURE_STATE(privateChildAccessible); #ifdef DEBUG_A11Y nsAutoString localName; childNode->GetLocalName(localName); Loading @@ -1418,14 +1420,13 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } #endif if (aChangeEventType == nsIAccessibleEvent::EVENT_HIDE) { // Fire EVENT_HIDE or EVENT_MENUPOPUP_END if previous accessible existed // for node being hidden. Fire this before the accessible goes away if (privateChildAccessible) { if (aChangeEventType == nsIAccessibleEvent::EVENT_HIDE || aChangeEventType == nsIAccessibleEvent::EVENT_REORDER) { // Fire EVENT_HIDE if previous accessible existed for node being hidden. // Fire this before the accessible goes away. privateChildAccessible->FireToolkitEvent(nsIAccessibleEvent::EVENT_HIDE, childAccessible, nsnull); } } // Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in this subtree if (aChangeEventType != nsIAccessibleEvent::EVENT_SHOW) { Loading Loading @@ -1465,7 +1466,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } } if (aChangeEventType == nsIAccessibleEvent::EVENT_SHOW && aChild) { if (aChild && (aChangeEventType == nsIAccessibleEvent::EVENT_SHOW || aChangeEventType == nsIAccessibleEvent::EVENT_REORDER)) { // Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content. // Fire after a short timer, because we want to make sure the view has been // updated to make this accessible content visible. If we don't wait, Loading accessible/src/msaa/nsAccessibleWrap.cpp +50 −35 Original line number Diff line number Diff line Loading @@ -1530,41 +1530,8 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent) newAccessible = accessible; } HWND hWnd = 0; nsCOMPtr<nsPIAccessNode> privateAccessNode = do_QueryInterface(newAccessible); if (privateAccessNode) { nsIFrame *frame = privateAccessNode->GetFrame(); if (frame) { nsIWidget *window = frame->GetWindow(); PRBool isVisible; window->IsVisible(isVisible); if (isVisible) { // Short explanation: // If HWND for frame is inside a hidden window, fire the event on the // containing document's visible window. // // Long explanation: // This is really just to fix combo boxes with JAWS. Window-Eyes already worked with // combo boxes because they use the value change event in the closed combo box // case. JAWS will only pay attention to the focus events on the list items. // The JAWS developers haven't fixed that, so we'll use the focus events to make JAWS work. // However, JAWS is ignoring events on a hidden window. So, in order to fix the bug where // JAWS doesn't echo the current option as it changes in a closed combo box, we need to use an // ensure that we never fire an event with an HWND for a hidden window. hWnd = (HWND)frame->GetWindow()->GetNativeData(NS_NATIVE_WINDOW); } } } if (!hWnd) { void* handle = nsnull; nsCOMPtr<nsIAccessibleDocument> accessibleDoc; accessNode->GetAccessibleDocument(getter_AddRefs(accessibleDoc)); NS_ENSURE_STATE(accessibleDoc); accessibleDoc->GetWindowHandle(&handle); hWnd = (HWND)handle; } HWND hWnd = GetHWNDFor(accessible); NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE); // Gecko uses two windows for every scrollable area. One window contains // scrollbars and the child window contains only the client area. Loading Loading @@ -1598,6 +1565,54 @@ PRInt32 nsAccessibleWrap::GetChildIDFor(nsIAccessible* aAccessible) return - NS_PTR_TO_INT32(uniqueID); } HWND nsAccessibleWrap::GetHWNDFor(nsIAccessible *aAccessible) { nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible)); nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode)); if (!privateAccessNode) return 0; HWND hWnd = 0; nsIFrame *frame = privateAccessNode->GetFrame(); if (frame) { nsIWidget *window = frame->GetWindow(); PRBool isVisible; window->IsVisible(isVisible); if (isVisible) { // Short explanation: // If HWND for frame is inside a hidden window, fire the event on the // containing document's visible window. // // Long explanation: // This is really just to fix combo boxes with JAWS. Window-Eyes already // worked with combo boxes because they use the value change event in // the closed combo box case. JAWS will only pay attention to the focus // events on the list items. The JAWS developers haven't fixed that, so // we'll use the focus events to make JAWS work. However, JAWS is // ignoring events on a hidden window. So, in order to fix the bug where // JAWS doesn't echo the current option as it changes in a closed // combo box, we need to use an ensure that we never fire an event with // an HWND for a hidden window. hWnd = (HWND)frame->GetWindow()->GetNativeData(NS_NATIVE_WINDOW); } } if (!hWnd) { void* handle = nsnull; nsCOMPtr<nsIAccessibleDocument> accessibleDoc; accessNode->GetAccessibleDocument(getter_AddRefs(accessibleDoc)); if (!accessibleDoc) return 0; accessibleDoc->GetWindowHandle(&handle); hWnd = (HWND)handle; } return hWnd; } IDispatch *nsAccessibleWrap::NativeAccessible(nsIAccessible *aXPAccessible) { if (!aXPAccessible) { Loading Loading
accessible/src/atk/nsAccessibleWrap.cpp +43 −41 Original line number Diff line number Diff line Loading @@ -1276,40 +1276,12 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent) *(gint *)eventData); break; // Is a superclass of ATK event children_changed case nsIAccessibleEvent::EVENT_REORDER: AtkChildrenChange *pAtkChildrenChange; MAI_LOG_DEBUG(("\n\nReceived: EVENT_REORDER(children_change)\n")); pAtkChildrenChange = NS_REINTERPRET_CAST(AtkChildrenChange *, eventData); nsAccessibleWrap *childAccWrap; if (pAtkChildrenChange && pAtkChildrenChange->child) { childAccWrap = NS_STATIC_CAST(nsAccessibleWrap *, pAtkChildrenChange->child); g_signal_emit_by_name (atkObj, pAtkChildrenChange->add ? \ "children_changed::add" : \ "children_changed::remove", pAtkChildrenChange->index, childAccWrap->GetAtkObject(), NULL); } else { // // EVENT_REORDER is normally fired by "HTML Document". // // In GOK, [only] "children_changed::add" can cause foreground // window accessible to update it children, which will // refresh "UI-Grab" window. // g_signal_emit_by_name (atkObj, "children_changed::add", -1, NULL, NULL); } case nsIAccessibleEvent::EVENT_SHOW: return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE); case nsIAccessibleEvent::EVENT_HIDE: return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE); break; /* * Because dealing with menu is very different between nsIAccessible * and ATK, and the menu activity is important, specially transfer the Loading Loading @@ -1368,18 +1340,14 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent) } break; case nsIAccessibleEvent::EVENT_MENUPOPUP_START: // fire extra focus event, then go down to EVENT_SHOW atk_focus_tracker_notify(atkObj); case nsIAccessibleEvent::EVENT_SHOW: MAI_LOG_DEBUG(("\n\nReceived: EVENT_SHOW\n")); MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n")); atk_focus_tracker_notify(atkObj); // fire extra focus event atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_TRUE); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_TRUE); break; case nsIAccessibleEvent::EVENT_HIDE: case nsIAccessibleEvent::EVENT_MENUPOPUP_END: MAI_LOG_DEBUG(("\n\nReceived: EVENT_HIDE\n")); MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_END\n")); atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_FALSE); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_FALSE); break; Loading Loading @@ -1528,3 +1496,37 @@ nsAccessibleWrap::FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent, return NS_OK; } nsresult nsAccessibleWrap::FireAtkShowHideEvent(nsIAccessibleEvent *aEvent, AtkObject *aObject, PRBool aIsAdded) { if (aIsAdded) MAI_LOG_DEBUG(("\n\nReceived: EVENT_SHOW\n")); else MAI_LOG_DEBUG(("\n\nReceived: EVENT_HIDE\n")); nsCOMPtr<nsIAccessible> accessible; aEvent->GetAccessible(getter_AddRefs(accessible)); NS_ENSURE_STATE(accessible); nsCOMPtr<nsIAccessible> parentAccessible; accessible->GetParent(getter_AddRefs(parentAccessible)); NS_ENSURE_STATE(parentAccessible); PRInt32 indexInParent = -1; accessible->GetIndexInParent(&indexInParent); AtkObject *parentObject = GetAtkObject(parentAccessible); NS_ENSURE_STATE(parentObject); g_signal_emit_by_name(parentObject, aIsAdded ? \ "children_changed::add" : \ "children_changed::remove", indexInParent, aObject, NULL); return NS_OK; }
accessible/src/atk/nsAccessibleWrap.h +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,8 @@ protected: AtkObject *aObject); nsresult FireAtkPropChangedEvent(nsIAccessibleEvent *aEvent, AtkObject *aObject); nsresult FireAtkShowHideEvent(nsIAccessibleEvent *aEvent, AtkObject *aObject, PRBool aIsAdded); AtkObject *mAtkObject; Loading
accessible/src/base/nsAccessibleEventData.h +5 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ * Contributor(s): * Kyle Yuan (kyle.yuan@sun.com) * John Sun (john.sun@sun.com) * Alexander Surkov <surkov.alexander@gmail.com> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), Loading Loading @@ -128,14 +129,8 @@ private: PRInt32 mCaretOffset; }; // XXX todo: We might want to use XPCOM interfaces instead of structs // e.g., nsAccessibleTextChangeEvent: public nsIAccessibleTextChangeEvent struct AtkChildrenChange { PRInt32 index; // index of child in parent nsIAccessible *child; PRBool add; // true for add, false for delete }; // XXX todo: We might want to use XPCOM interfaces instead of struct // e.g., nsAccessibleTableChangeEvent: public nsIAccessibleTableChangeEvent struct AtkTableChange { PRUint32 index; // the start row/column after which the rows are inserted/deleted. Loading @@ -143,3 +138,4 @@ struct AtkTableChange { }; #endif
accessible/src/base/nsDocAccessible.cpp +28 −26 Original line number Diff line number Diff line Loading @@ -1294,6 +1294,9 @@ void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure) void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent) { NS_ASSERTION(aChangeEvent != nsIAccessibleEvent::EVENT_SHOW, "nsDocAccessible::RefreshNodes isn't supposed to work with show event."); nsCOMPtr<nsIDOMNode> iterNode(aStartNode), nextNode; nsCOMPtr<nsIAccessNode> accessNode; Loading @@ -1306,12 +1309,11 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent // Don't shutdown our doc object! if (accessNode != NS_STATIC_CAST(nsIAccessNode*, this)) { if (aChangeEvent != nsIAccessibleEvent::EVENT_SHOW) { nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode)); if (accessible) { // Fire menupopupend events for menu popups that go away PRUint32 role, event = 0; accessible->GetFinalRole(&role); PRUint32 role = Role(accessible); if (role == nsIAccessibleRole::ROLE_MENUPOPUP) { nsCOMPtr<nsIDOMNode> domNode; accessNode->GetDOMNode(getter_AddRefs(domNode)); Loading @@ -1319,14 +1321,12 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode, PRUint32 aChangeEvent if (!popup) { // Popup elements already fire these via DOMMenuInactive // handling in nsRootAccessible::HandleEvent event = nsIAccessibleEvent::EVENT_MENUPOPUP_END; } } if (event) { FireToolkitEvent(event, accessible, nsnull); FireToolkitEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, accessible, nsnull); } } } void *uniqueID; accessNode->GetUniqueID(&uniqueID); nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode)); Loading Loading @@ -1403,6 +1403,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } nsCOMPtr<nsPIAccessible> privateChildAccessible = do_QueryInterface(childAccessible); NS_ENSURE_STATE(privateChildAccessible); #ifdef DEBUG_A11Y nsAutoString localName; childNode->GetLocalName(localName); Loading @@ -1418,14 +1420,13 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } #endif if (aChangeEventType == nsIAccessibleEvent::EVENT_HIDE) { // Fire EVENT_HIDE or EVENT_MENUPOPUP_END if previous accessible existed // for node being hidden. Fire this before the accessible goes away if (privateChildAccessible) { if (aChangeEventType == nsIAccessibleEvent::EVENT_HIDE || aChangeEventType == nsIAccessibleEvent::EVENT_REORDER) { // Fire EVENT_HIDE if previous accessible existed for node being hidden. // Fire this before the accessible goes away. privateChildAccessible->FireToolkitEvent(nsIAccessibleEvent::EVENT_HIDE, childAccessible, nsnull); } } // Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in this subtree if (aChangeEventType != nsIAccessibleEvent::EVENT_SHOW) { Loading Loading @@ -1465,7 +1466,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, } } if (aChangeEventType == nsIAccessibleEvent::EVENT_SHOW && aChild) { if (aChild && (aChangeEventType == nsIAccessibleEvent::EVENT_SHOW || aChangeEventType == nsIAccessibleEvent::EVENT_REORDER)) { // Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content. // Fire after a short timer, because we want to make sure the view has been // updated to make this accessible content visible. If we don't wait, Loading
accessible/src/msaa/nsAccessibleWrap.cpp +50 −35 Original line number Diff line number Diff line Loading @@ -1530,41 +1530,8 @@ nsAccessibleWrap::FireAccessibleEvent(nsIAccessibleEvent *aEvent) newAccessible = accessible; } HWND hWnd = 0; nsCOMPtr<nsPIAccessNode> privateAccessNode = do_QueryInterface(newAccessible); if (privateAccessNode) { nsIFrame *frame = privateAccessNode->GetFrame(); if (frame) { nsIWidget *window = frame->GetWindow(); PRBool isVisible; window->IsVisible(isVisible); if (isVisible) { // Short explanation: // If HWND for frame is inside a hidden window, fire the event on the // containing document's visible window. // // Long explanation: // This is really just to fix combo boxes with JAWS. Window-Eyes already worked with // combo boxes because they use the value change event in the closed combo box // case. JAWS will only pay attention to the focus events on the list items. // The JAWS developers haven't fixed that, so we'll use the focus events to make JAWS work. // However, JAWS is ignoring events on a hidden window. So, in order to fix the bug where // JAWS doesn't echo the current option as it changes in a closed combo box, we need to use an // ensure that we never fire an event with an HWND for a hidden window. hWnd = (HWND)frame->GetWindow()->GetNativeData(NS_NATIVE_WINDOW); } } } if (!hWnd) { void* handle = nsnull; nsCOMPtr<nsIAccessibleDocument> accessibleDoc; accessNode->GetAccessibleDocument(getter_AddRefs(accessibleDoc)); NS_ENSURE_STATE(accessibleDoc); accessibleDoc->GetWindowHandle(&handle); hWnd = (HWND)handle; } HWND hWnd = GetHWNDFor(accessible); NS_ENSURE_TRUE(hWnd, NS_ERROR_FAILURE); // Gecko uses two windows for every scrollable area. One window contains // scrollbars and the child window contains only the client area. Loading Loading @@ -1598,6 +1565,54 @@ PRInt32 nsAccessibleWrap::GetChildIDFor(nsIAccessible* aAccessible) return - NS_PTR_TO_INT32(uniqueID); } HWND nsAccessibleWrap::GetHWNDFor(nsIAccessible *aAccessible) { nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible)); nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode)); if (!privateAccessNode) return 0; HWND hWnd = 0; nsIFrame *frame = privateAccessNode->GetFrame(); if (frame) { nsIWidget *window = frame->GetWindow(); PRBool isVisible; window->IsVisible(isVisible); if (isVisible) { // Short explanation: // If HWND for frame is inside a hidden window, fire the event on the // containing document's visible window. // // Long explanation: // This is really just to fix combo boxes with JAWS. Window-Eyes already // worked with combo boxes because they use the value change event in // the closed combo box case. JAWS will only pay attention to the focus // events on the list items. The JAWS developers haven't fixed that, so // we'll use the focus events to make JAWS work. However, JAWS is // ignoring events on a hidden window. So, in order to fix the bug where // JAWS doesn't echo the current option as it changes in a closed // combo box, we need to use an ensure that we never fire an event with // an HWND for a hidden window. hWnd = (HWND)frame->GetWindow()->GetNativeData(NS_NATIVE_WINDOW); } } if (!hWnd) { void* handle = nsnull; nsCOMPtr<nsIAccessibleDocument> accessibleDoc; accessNode->GetAccessibleDocument(getter_AddRefs(accessibleDoc)); if (!accessibleDoc) return 0; accessibleDoc->GetWindowHandle(&handle); hWnd = (HWND)handle; } return hWnd; } IDispatch *nsAccessibleWrap::NativeAccessible(nsIAccessible *aXPAccessible) { if (!aXPAccessible) { Loading