Community
Participate
Working Groups
Build Identifier: Build id: M20100909-0800 When using the JAWS screenreader with Memory Analyzer, the pin tab checkbox in the Inspector view, and all the buttons in the heap dump "editor" do not have their tool tip (or any) text read when they are selected. Reproducible: Always Steps to Reproduce: 1. Start Memory Analyzer and open a heap dump 2. Start the JAWS screen reader (v 12.0.525 ?) 3. Use the tab key to navigate to the pin tab in the Inspector View, or to navigate through the buttons on the toolbar of the heap dump editor. 4. Notice that the tooltip/label/text of the buttons is not read by JAWS.
The reason for this is that the default Accessible behaviour of org.eclipse.swt.widgets.ToolBar does not provide the name of toolbar items to an accessibility client. A minor modification to the default behaviour is required by adding a custom AccessibilityAdapter to the Accessible object associated with the ToolBars. Here is a patch which improves the accessibility of the affected ToolBars in MAT: Index: src/org/eclipse/mat/ui/editor/MultiPaneEditor.java =================================================================== --- src/org/eclipse/mat/ui/editor/MultiPaneEditor.java (revision 1081) +++ src/org/eclipse/mat/ui/editor/MultiPaneEditor.java (working copy) @@ -50,6 +50,7 @@ import org.eclipse.mat.query.IQueryContext; import org.eclipse.mat.ui.MemoryAnalyserPlugin; import org.eclipse.mat.ui.Messages; +import org.eclipse.mat.ui.accessibility.AccessibleToolbarAdapter; import org.eclipse.mat.ui.snapshot.ImageHelper.ImageImageDescriptor; import org.eclipse.mat.ui.util.ErrorHelper; import org.eclipse.mat.ui.util.NavigatorState; @@ -214,11 +215,15 @@ // create tool bar ToolBar toolbar = new ToolBar(composite, SWT.FLAT); + // Add custom AccessibleAdapter, passing in associated ToolBar. + toolbar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolbar) ); GridDataFactory.fillDefaults().grab(true, false).indent(0, 2).applyTo(toolbar); toolbarMgr = new ToolBarManager(toolbar); // create tool bar toolbar = new ToolBar(composite, SWT.FLAT); + // Add custom AccessibleAdapter, passing in associated ToolBar. + toolbar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolbar) ); GridDataFactory.fillDefaults().grab(false, false).indent(0, 2).applyTo(toolbar); toolbarMgrHelp = new ToolBarManager(toolbar); Index: src/org/eclipse/mat/ui/accessibility/AccessibleToolbarAdapter.java =================================================================== --- src/org/eclipse/mat/ui/accessibility/AccessibleToolbarAdapter.java (revision 0) +++ src/org/eclipse/mat/ui/accessibility/AccessibleToolbarAdapter.java (revision 0) @@ -0,0 +1,32 @@ +package org.eclipse.mat.ui.accessibility; + +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +public class AccessibleToolbarAdapter extends AccessibleAdapter { + + private ToolBar toolBar; // ToolBar with which this adapter is associated. + + public AccessibleToolbarAdapter(ToolBar toolBar){ + super(); + this.toolBar = toolBar; // Store ref to associated toolbar + } + + @Override + public void getName(AccessibleEvent e) { + if (e.childID != ACC.CHILDID_SELF) { // Not self - ie probably a child + ToolItem item = toolBar.getItem(e.childID); // Try to get child item + if (item != null) { // Found it + String toolTip = item.getToolTipText(); // Get tool tip if any + if (toolTip != null) { // Got one + e.result = toolTip; // Return to caller in AccessibleEvent + } + } + } + } // getName() + +} // AccessibleToolbarAdapter + Index: src/org/eclipse/mat/ui/snapshot/views/inspector/InspectorView.java =================================================================== --- src/org/eclipse/mat/ui/snapshot/views/inspector/InspectorView.java (revision 1081) +++ src/org/eclipse/mat/ui/snapshot/views/inspector/InspectorView.java (working copy) @@ -56,6 +56,7 @@ import org.eclipse.mat.snapshot.model.IPrimitiveArray; import org.eclipse.mat.ui.MemoryAnalyserPlugin; import org.eclipse.mat.ui.Messages; +import org.eclipse.mat.ui.accessibility.AccessibleToolbarAdapter; import org.eclipse.mat.ui.snapshot.ImageHelper; import org.eclipse.mat.ui.snapshot.editor.HeapEditor; import org.eclipse.mat.ui.snapshot.editor.ISnapshotEditorInput; @@ -476,6 +477,8 @@ GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(tabFolder); ToolBar toolBar = new ToolBar(tabFolder, SWT.HORIZONTAL | SWT.FLAT); + // Add custom AccessibleAdapter, passing in associated ToolBar. + toolBar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolBar) ); tabFolder.setTopRight(toolBar); // set the height of the tab to display the tool bar correctly tabFolder.setTabHeight(Math.max(toolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, tabFolder.getTabHeight()));
The following revised patch adds a copyright statement and applies the MAT standard code formatting as prescribed in the contributor guidelines at http://wiki.eclipse.org/index.php?title=MemoryAnalyzer/Contributor_Reference#Setup There is no logic change from the patch in the previous comment. Index: src/org/eclipse/mat/ui/editor/MultiPaneEditor.java =================================================================== --- src/org/eclipse/mat/ui/editor/MultiPaneEditor.java (revision 1081) +++ src/org/eclipse/mat/ui/editor/MultiPaneEditor.java (working copy) @@ -50,6 +50,7 @@ import org.eclipse.mat.query.IQueryContext; import org.eclipse.mat.ui.MemoryAnalyserPlugin; import org.eclipse.mat.ui.Messages; +import org.eclipse.mat.ui.accessibility.AccessibleToolbarAdapter; import org.eclipse.mat.ui.snapshot.ImageHelper.ImageImageDescriptor; import org.eclipse.mat.ui.util.ErrorHelper; import org.eclipse.mat.ui.util.NavigatorState; @@ -214,11 +215,15 @@ // create tool bar ToolBar toolbar = new ToolBar(composite, SWT.FLAT); + // Add custom AccessibleAdapter, passing in associated ToolBar. + toolbar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolbar) ); GridDataFactory.fillDefaults().grab(true, false).indent(0, 2).applyTo(toolbar); toolbarMgr = new ToolBarManager(toolbar); // create tool bar toolbar = new ToolBar(composite, SWT.FLAT); + // Add custom AccessibleAdapter, passing in associated ToolBar. + toolbar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolbar) ); GridDataFactory.fillDefaults().grab(false, false).indent(0, 2).applyTo(toolbar); toolbarMgrHelp = new ToolBarManager(toolbar); Index: src/org/eclipse/mat/ui/accessibility/AccessibleToolbarAdapter.java =================================================================== --- src/org/eclipse/mat/ui/accessibility/AccessibleToolbarAdapter.java (revision 0) +++ src/org/eclipse/mat/ui/accessibility/AccessibleToolbarAdapter.java (revision 0) @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial implementation + *******************************************************************************/ + +package org.eclipse.mat.ui.accessibility; + +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; + +public class AccessibleToolbarAdapter extends AccessibleAdapter +{ + + private ToolBar toolBar; // ToolBar with which this adapter is associated. + + public AccessibleToolbarAdapter(ToolBar toolBar) + { + super(); + this.toolBar = toolBar; // Store ref to associated toolbar + } + + @Override + public void getName(AccessibleEvent e) + { + if (e.childID != ACC.CHILDID_SELF) + { // Not self - ie probably a child + ToolItem item = toolBar.getItem(e.childID); // Try to get child item + if (item != null) + { // Found it + String toolTip = item.getToolTipText(); // Get tool tip if any + if (toolTip != null) + { // Got one + e.result = toolTip; // Return to caller in AccessibleEvent + } + } + } + } // getName() + +} // AccessibleToolbarAdapter + Index: src/org/eclipse/mat/ui/snapshot/views/inspector/InspectorView.java =================================================================== --- src/org/eclipse/mat/ui/snapshot/views/inspector/InspectorView.java (revision 1081) +++ src/org/eclipse/mat/ui/snapshot/views/inspector/InspectorView.java (working copy) @@ -56,6 +56,7 @@ import org.eclipse.mat.snapshot.model.IPrimitiveArray; import org.eclipse.mat.ui.MemoryAnalyserPlugin; import org.eclipse.mat.ui.Messages; +import org.eclipse.mat.ui.accessibility.AccessibleToolbarAdapter; import org.eclipse.mat.ui.snapshot.ImageHelper; import org.eclipse.mat.ui.snapshot.editor.HeapEditor; import org.eclipse.mat.ui.snapshot.editor.ISnapshotEditorInput; @@ -476,6 +477,8 @@ GridDataFactory.fillDefaults().grab(true, true).align(SWT.FILL, SWT.FILL).applyTo(tabFolder); ToolBar toolBar = new ToolBar(tabFolder, SWT.HORIZONTAL | SWT.FLAT); + // Add custom AccessibleAdapter, passing in associated ToolBar. + toolBar.getAccessible().addAccessibleListener(new AccessibleToolbarAdapter(toolBar) ); tabFolder.setTopRight(toolBar); // set the height of the tab to display the tool bar correctly tabFolder.setTabHeight(Math.max(toolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT).y, tabFolder.getTabHeight()));
Thanks for the patch! I don't have JAWS, and therefore I tried using the Windows Narrator. I was able to reproduce the problem, and after applying the fix the Narrator started telling me the tooltips of the buttons, so I think the patch is fine. Can I ask you, please, to put the patch as an attachment to the ticket. It is easier then to maintain the IP log in the future. And I have one more question. While "reading" the buttons, the narrator tells me for some of them "progress bar; <x> % completed; invisible" and then the label text. Any ideas what the reason for this could be? I have no experience so far with accessibility. (Just to make it clear, it was telling this also before the patch. With the patch it tells also the tooltip text).
Created attachment 191660 [details] Patch enabling toolbar buttons for accessible screenreader. This patch enables screen readers to read the tool tip text for toolbar buttons in MAT (pin tab and heap dump toolbar buttons). Works with JAWS and Windows Narrator.
Good to know that this works with other screenreader(s) as well as JAWS, thanks for testing that. Patch attached as requested. I'm not sure why Narrator is reading a progress bar; I didn't notice that with JAWS but will look out for that and add more info if I discover anything.
Sorry for not responding for a while. I just checked in the patch into SVN. I also set the +iplog on the attachment. Thanks a lot for the contribution! Shall we keep the ticket open for a while, in case you discover some more info about the fact that Narrator is reading also "progress bar..."? Or shall I close it already and leave further optimizations to be discussed in separate tickets?
I'm closing the message now