Community
Participate
Working Groups
To support IAccesible2 API, we are trying to create Accessible object for each table cell in a custom table. For performance, we just create Accessible object as needed. The goal is not to create Accessible object for cell when there is no AT running. When cell focus changed, we will call tableAccessible.setFocus(childID) to fire an accessibility focus change event. In such case, code in Accessible.setFocus(childID) will result in a call to getChild() which cause a cell Accessible object created even with no AT tools running. Here is the call stack: STableRow(STableItem).getAccessible(Accessible) line: 2776 STable$41.getChild(AccessibleControlEvent) line: 8718 Accessible.checkUniqueID(int) line: 4619 Accessible.childIDToOs(int) line: 4645 Accessible.setFocus(int) line: 1385 STable.fireFocusAccessibilityEvent() line: 8243 STable.onBodyFocusIn(Event) line: 1478 STable$4.handleEvent(Event) line: 804 EventTable.sendEvent(Event) line: 84 STableBody(Widget).sendEvent(Event) line: 1053 STableBody(Canvas).WM_SETFOCUS(int, int) line: 448 STableBody(Control).windowProc(int, int, int, int) line: 4598 Display.windowProc(int, int, int, int) line: 4972 OS.SetFocus(int) line: not available [native method] One solution to improve: in Accessible.setFocus(childID) method, check refCount first. If refCount <= 1, it means that only current application running, not AT tools available. In such case, we do not need to fire COM event any more, thus no Accessible object for child will be created. Here is the code: org.eclipse.swt.accessibility.Accessible.java public void setFocus(int childID) { checkWidget(); if(this.refCount>1){ // only there is AT tools running, we need to fire COM event int osChildID = childID == ACC.CHILDID_SELF ? eventChildID() : childIDToOs(childID); if (DEBUG) print(this + ".NotifyWinEvent EVENT_OBJECT_FOCUS hwnd=" + control.handle + " childID=" + osChildID); COM.NotifyWinEvent (COM.EVENT_OBJECT_FOCUS, control.handle, COM.OBJID_CLIENT, osChildID); } } Could you help to review above solution to the problem? Could we contribute this to Eclipse build. Thanks!
We can't always trust that the refCount will be accurate - for example, if a screen reader crashes, then the refCount may never be decremented back down to 1. However, there is a platform way to tell if a screen reader is running. On Windows: static boolean isATRunning() { final int SPI_GETSCREENREADER = 70; int [] pvParam = new int [1]; boolean result = OS.SystemParametersInfo(SPI_GETSCREENREADER, 0, pvParam, 0); return result && (pvParam [0] != 0); } On Mac: static boolean isATRunning() { NSUserDefaults defaults = NSUserDefaults.standardUserDefaults(); defaults.addSuiteNamed (NSString.stringWith("com.apple.universalaccess")); defaults.synchronize(); return defaults.integerForKey (NSString.stringWith("voiceOverOnOffKey")) != 0; } On GTK: static boolean isATRunning() { // Currently no platform way to get this info on GTK. // See: https://bugzilla.gnome.org/show_bug.cgi?id=649123 // and http://web.archiveorange.com/archive/v/D5mSCXzQOd5voBtnXOzY return true; }
Although the refCount is not always accurate, it does not matter. In most case, screen reader will not run and the refCount is always 0. We can improve performance in such situation. For screen reader crash scenario, even refCount is always 1, we just always send the focus event if the setFocus method called. It has no any bad effect. Even we have way to know whether AT tools is running in each platform, it is not good to add such kind of code each time we call setFocus. This should not be handled by upper layer applications. Thanks!
The detecting code of comment#1 is going to add uncecessary overhead when the AT is running. I believe checking the refCount is a good compromise. Fixed http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=7b55f42ce534817654ce74c0273c74173f0f1d6d Note that the final fix also avoids sending other events.
Fix for this bug has caused a regression w.r.t. functioning of JAWS screen reader, refer bug 421255 :- [Accessibility] [Regression] - JAWS does not read text from label associated with text field The below assumption made in this bug fix does not hold true for JAWS screen reader: "refCount <= 1, it means that only current application running, no AT tools available" But when JAWS screen reader is running the refCount continues to be 1, so JAWS is not able to read text from label. In order to fix issue in bug 421255, required to partially revert change done as part of this bug.
'refCount' approach to optimize Accessible code has being reverted, since it broke the functioning of JAWS. Re-opening this bug for further investigation.
Reverted the fix for this bug via http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=5b8cefcb6dd3cedb939b3c00a1e12e7ba4986b99
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.