Bug 212991 - Mac OS X accessibility does not have the standard relations
Summary: Mac OS X accessibility does not have the standard relations
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: 3.4 RC1   Edit
Assignee: Carolyn MacLeod CLA
QA Contact:
URL:
Whiteboard:
Keywords: accessibility
Depends on:
Blocks:
 
Reported: 2007-12-14 04:51 EST by Carolyn MacLeod CLA
Modified: 2008-05-07 14:29 EDT (History)
3 users (show)

See Also:
grant_gayed: review+


Attachments
_patch.txt (13.39 KB, patch)
2008-05-07 13:26 EDT, Carolyn MacLeod CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Carolyn MacLeod CLA 2007-12-14 04:51:09 EST
On Windows, there are several standard relations under MSAA, for example, a Label preceeding a Text will provide the accessible name for the Text. 

On GTK, these relations were implemented for SWT using ATK relations.
(see Control.setRelations() and Label.addRelation() in the GTK code)

Need to implement these on Mac OS X.
Comment 1 Carolyn MacLeod CLA 2007-12-14 05:00:43 EST
Implementation info:
Use HIObjectSetAuxiliaryAccessibilityAttribute for both elements.
Example:
HIObjectSetAuxiliaryAccessibilityAttribute(x, kAXTitleUIElementAttribute, y);
and
HIObjectSetAuxiliaryAccessibilityAttribute(x, kAXServesAsTitleForUIElementsAttribute, y);
Comment 2 Carolyn MacLeod CLA 2008-05-07 13:26:51 EDT
Created attachment 99124 [details]
_patch.txt

Patch for the fix. One new native.
Comment 3 Carolyn MacLeod CLA 2008-05-07 13:30:12 EDT
Test snippet that tests label and control insertions and deletions to make sure all relations are added and removed correctly.

import org.eclipse.swt.*;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class LabelForTextTest {
	static int count = 0;
	static Label currentLabel;
	static Text currentText;

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout(2, false));
		
		final Composite parent = new Composite(shell, SWT.BORDER);
		parent.setLayout(new FillLayout());
		parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
		
		currentLabel = new Label(parent, SWT.NONE);
		currentLabel.setText("Title:");
		
		currentText = new Text(parent, SWT.BORDER);
		currentText.setText("Hello");
		
		Button button = new Button(shell, SWT.PUSH);
		button.setText("Insert Label");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				Label label = new Label(parent, SWT.NONE);
				count++;
				label.setText("Title" + count + ":");
				if (currentText != null) label.moveAbove(currentText);
//				if (currentLabel != null) label.moveBelow(currentLabel);
				currentLabel = label;
				parent.layout();
			}
		});

		button = new Button(shell, SWT.PUSH);
		button.setText("Insert Text");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				Text text = new Text(parent, SWT.BORDER);
				count++;
				text.setText("Hello" + count);
				if (currentText != null) text.moveAbove(currentText);
				currentText = text;
				parent.layout();
			}
		});

		button = new Button(shell, SWT.PUSH);
		button.setText("Delete Label");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (currentLabel != null) {
					currentLabel.dispose();
					currentLabel = null;
					Control [] children = parent.getChildren();
					for (int i = 0; i < children.length; i++) {
						if (children[i] instanceof Label) {
							currentLabel = (Label)children[i];
						}
					}
				}
				parent.layout();
			}
		});

		button = new Button(shell, SWT.PUSH);
		button.setText("Delete Text");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (currentText != null) {
					currentText.dispose();
					currentText = null;
					Control [] children = parent.getChildren();
					for (int i = 0; i < children.length; i++) {
						if (children[i] instanceof Text) {
							currentText = (Text)children[i];
							break;
						}
					}
				}
				parent.layout();
			}
		});

		shell.pack();
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}

Comment 4 Carolyn MacLeod CLA 2008-05-07 14:29:22 EDT
Fixed > 20080507