On May 11, 2010, at 1:40 PM, Christiaan Hofman wrote: On May 11, 2010, at 19:41, James Dempsey wrote: On May 11, 2010, at 4:10 AM, Christiaan Hofman wrote: On May 11, 2010, at 2:17, James Dempsey wrote: On May 10, 2010, at 2:57 PM, Mickey Roberson wrote: I have implemented custom table cells (subclass of NSTextFieldCell) in my application (a Twitter client). Each cell represents a tweet including things like name, date, tweet text, etc. Within my cell subclass I have the following code:
- (NSArray *)accessibilityAttributeNames { if(validAXAttributes == nil) { validAXAttributes = [[NSArray alloc] initWithObjects:NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityHelpAttribute, NSAccessibilityFocusedAttribute, NSAccessibilityParentAttribute, NSAccessibilityChildrenAttribute, NSAccessibilityWindowAttribute, NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, NSAccessibilityEnabledAttribute, NSAccessibilityValueAttribute, nil]; } return validAXAttributes; }
- (id)accessibilityAttributeValue:(NSString *)attribute { if([attribute isEqualToString:NSAccessibilityRoleAttribute]) //AXRole return NSAccessibilityStaticTextRole; if([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) //AXRoleDescription return @"Timeline Tweet"; if([attribute isEqualToString:NSAccessibilityHelpAttribute]) //AXHelp return @"Timeline Tweet"; if([attribute isEqualToString:NSAccessibilityValueAttribute]) { //AXValue SRXTweetObject* tweet = (SRXTweetObject*)[self objectValue]; NSMutableString* readableString = [NSMutableString stringWithFormat:@"%@: %@", [tweet.user displayName], tweet.text]; //Removed for brevity... return readableString; } return [super accessibilityAttributeValue:attribute]; }
Mickey - it's great that you are working towards making your app accessible! That's great!
You should always ignore NSAccessibilityException exceptions - and if you have special exception-handling code, you should always re-raise NSAccessibilityExceptions. They are expected to occur even if there is no problem in your application.
Why? For historic reasons, AppKit uses exceptions internally to deal with situations where an application needs to send an error back to the accessibility client.
So, you can and should safely ignore those exceptions.
Some other things to point out, scanning through the code you provided:
1. When subclassing a text field cell, it is best to let the NSAccessibilityValueAttribute keep its inherited behavior (which reports the string value of the text field). This is because there are a number of other attributes and parameterized attributes, such as AXNumberOfCharacters, AXBoundsForRange, AXAttributedStringForRange, AXStringForRange, etc, which all are based on the value of the text field.
Can anyone tell me precisely WHICH (parameterized) attributes the roles like AXStaticText and AXTextArea are supposed to implement and how they are supposed to be related? I can certainly not find it in the documentation (yes, I did read them).
Christiaan
The NSAccessibility protocol reference has a description of each parameterized attribute:
Also that is just a list of some parameters. Are these all? How do they relate to the different roles? How do they relate to each other? Are they required, or optional?
And, again, also, there does not seem to be any cross link between these different docs, moreover these also certainly need to be listed in other docs, like the one Bill Cheeseman mentioned. It is very difficult to figure things out that are spread around in different docs that sometimes are not even apparently related. If this is not documented, or not documented well enough, please file a bug report at bugreporter.apple.com. This should be documented.
I already filed bug reports on this a while ago, rdar://problem/5910367, r dar://problem/5879861. No reaction on these.
Yes, I realize filing bug reports is like dropping a note into a deep wishing well. In general, the more specific and actionable the report, the quicker it tends to be addressed. (i.e. "The role X is missing from the documentation" as opposed to "A bunch of roles are missing"). And, in general, filing the bug report with one issue per report also helps.
With documentation - a more lightweight way of sending feedback is to use the "Did this document help you?" button at the bottom of the documentation page. The docs folks definitely read the feedback.
Notice that with the new Accessibility Roles and Attributes Reference that various parameterized attributes are documented for the first time, so improvements are occurring. I do encourage you to continue sending feedback, but realize it can be frustrating.
In the meantime, you can get what you need by launching TextEdit and using Accessibility Inspector on it. Lock focus on the text area, and the inspector will show you all the parameterized attributes it has - an AXTextArea should have those parameterized attribute. Then open the preferences pane and lock focus on one of the static text labels. The inspector will show you its parameterized attributes (it's the same set though).
It's the set of nine attributes listed in the "Text-specific parameterized attributes" of the reference documentation above.
Are they all required? And what to do when some attributes don't have aren't meaningful or can't be supported in a particular case? For instance I have a situation where I want to represent a text, but I have no way to get the layout of the text, so I can't implement attributes like NSAccessibilityRangeForPositionParameterizedAttribute.
If you provide no parameterized attributes, and only provide AXValue, VoiceOver will speak the value, but VoiceOver will not be able to do things it relies on the parameterized attributes for. So to get basic functionality they are not required.
The parameterized attributes allow VoiceOver to do things such as draw the VO cursor properly over portions of text, get the rich text for a range of text, get text line by line as the user navigates through the text, etc.
-James
As Bill Cheeseman mentions, his tool allows you to query for parameterized attributes, Accessibility Inspector does not have that functionality. In general, the behavior of the text area and static text in Text Edit, since it uses stock AppKit controls, is the reference for how any of those attributes should behave.
Definitely file the documentation bug though - if it is not documented, it should be. Thanks.
-James
Christiaan If you return something else as the AXValue, it will confuse accessibility clients like VoiceOver.
Instead, add an NSAccessibilityDescriptionAttribute. This string can contain all of the extra information.
2. If the cell is not editable, it should already report its role as static text, and its role description should be provided automatically as well.
3. In this case, you should not provide a custom role description - the role is static text, and the element should describe its role accordingly.
4. You might want to consider getting the attributes from your superclass, and adding the additional attributes. Otherwise, if an attribute is added to text fields in the future (For instance we added AXPlaceholderValue in a recent release), then your subclass will not support it automatically.
-James
For the most part this behaves correctly except that it occasionally reads the Accessibility Content twice. While looking into this in gdb I noticed that multiple NSAccessibilityExceptions are being thrown when I turn VO on with a tweet as main focus.
2010-05-10 17:39:43.954 Syrinx[85907:a0f] NSExceptionHandler has recorded the following exception: NSAccessibilityException -- Attempt to observe "AXTextInputMarkingSessionBegan" on non-observable element: <NSTableViewCellProxy: 0x11d4ebbf0> col:0 row:33 real element:<SRXTableCell: 0x11d51e5a0> Stack trace: 0x7fff81c18a2c 0x7fff827510f3 0x7fff82ed19b9 0x7fff86485c45 0x7fff864839f5 0x7fff8618900b 0x7fff86192f6c 0x7fff8616f541 0x7fff82e16201 0x7fff82e148df 0x7fff85349ada 0x7fff853498df 0x7fff85349798 0x7fff86235a2a 0x7fff86235379 0x7fff861fb05b 0x7fff861f3d7c 0x100001365 0x100001314 0x1 (gdb) continue (gdb) continue 2010-05-10 17:39:44.641 Syrinx[85907:a0f] NSExceptionHandler has recorded the following exception: NSAccessibilityException -- Attempt to observe "AXCreated" on non-observable element: <NSTableViewCellProxy: 0x11e673ac0> col:0 row:33 real element:<SRXTableCell: 0x11d51e5a0> Stack trace: 0x7fff81c18a2c 0x7fff827510f3 0x7fff82ed19b9 0x7fff86485c45 0x7fff864839f5 0x7fff8618900b 0x7fff86192f6c 0x7fff8616f541 0x7fff82e16201 0x7fff82e148df 0x7fff85349ada 0x7fff853498df 0x7fff85349798 0x7fff86235a2a 0x7fff86235379 0x7fff861fb05b 0x7fff861f3d7c 0x100001365 0x100001314 0x1
What am I doing wrong that is causing these exceptions, and how do I fix them? _______________________ Mickey Roberson
-------------------------------------------------- James Dempsey AppKit Engineering Apple
-------------------------------------------------- James Dempsey AppKit Engineering Apple
|