Project: SWT
Bug 405244 Accessibility: There is no way to supply group position information for IAccessible2 support
Reported: 2013-04-09 04:40:51 | Status: resolved fixed

There is get_groupPosition() method in IAccessible2 which is used to get accessibility group information for a child. But in 3.7.2, there is no implementation for that method which cause AT tools not able to get group information. Even in Eclipse 4.2.2, get_groupPosition() only implemented group information for radio button. We need to supply a way allowing developer specify those group information by themselves. I worked out fix below. The idea is to let developer set the group information in method AccessibleControlListener.getChild(). When we need to get group information, we will call AccessibleControlListener.getChild() passing AccessibleControlEvent.childID = ACC.CHILDID_GROUP_POSITION. Then developer should set positionInGroup to event.detail, set groupLevel in event.x, set similarItemsInGroup in event.y. Thus we can get group information and return to AT tools. Accessible.java int get_groupPosition(int /*long*/ pGroupLevel, int /*long*/ pSimilarItemsInGroup, int /*long*/ pPositionInGroup) { // TODO: handle where possible - maybe add AccessibleGroup later //get the role //if it has role tree, then the level is the value else 0 (for N/A) int groupLevel = 0; int similarItemsInGroup = 0; int positionInGroup = 0; AccessibleControlEvent event = new AccessibleControlEvent(this); event.childID = ACC.CHILDID_GROUP_POSITION; event.detail = -1; for (int i = 0; i < accessibleControlListeners.size(); i++) { AccessibleControlListener listener = (AccessibleControlListener) accessibleControlListeners.elementAt(i); listener.getChild(event); } positionInGroup = event.detail; if(positionInGroup!=-1){ groupLevel = event.x; similarItemsInGroup = event.y; }else if (control instanceof Button && ((control.getStyle() & SWT.RADIO) != 0)) { /* We currently only determine position and count for radio buttons. */ Control [] children = control.getParent().getChildren(); positionInGroup = 1; similarItemsInGroup = 1; for (int i = 0; i < children.length; i++) { Control child = children[i]; if (child instanceof Button && ((child.getStyle() & SWT.RADIO) != 0)) { if (child == control) positionInGroup = similarItemsInGroup; else similarItemsInGroup++; } } } COM.MoveMemory(pGroupLevel, new int [] { groupLevel }, 4); COM.MoveMemory(pSimilarItemsInGroup, new int [] { similarItemsInGroup }, 4); COM.MoveMemory(pPositionInGroup, new int [] { positionInGroup }, 4); if (DEBUG) print(this + ".IAccessible2::get_groupPosition() returning" + hresult(groupLevel == 0 && similarItemsInGroup == 0 && positionInGroup == 0 ? COM.S_FALSE : COM.S_OK)); if (groupLevel == 0 && similarItemsInGroup == 0 && positionInGroup == 0) return COM.S_FALSE; return COM.S_OK; } AccessibleControlEvent.java public static final int CHILDID_GROUP_POSITION = -6;

Files changed in fix:
bundles/org.eclipse.swt/Eclipse SWT Accessibility/common/org/eclipse/swt/accessibility/ACC.java bundles/org.eclipse.swt/Eclipse SWT Accessibility/common/org/eclipse/swt/accessibility/AccessibleAttributeAdapter.java bundles/org.eclipse.swt/Eclipse SWT Accessibility/common/org/eclipse/swt/accessibility/AccessibleAttributeEvent.java bundles/org.eclipse.swt/Eclipse SWT Accessibility/common/org/eclipse/swt/accessibility/AccessibleAttributeListener.java bundles/org.eclipse.swt/Eclipse SWT Accessibility/gtk/org/eclipse/swt/accessibility/AccessibleObject.java bundles/org.eclipse.swt/Eclipse SWT Accessibility/win32/org/eclipse/swt/accessibility/Accessible.java