Index: src/mac/carbon/window.cpp =================================================================== --- src/mac/carbon/window.cpp (revision 53276) +++ src/mac/carbon/window.cpp (working copy) @@ -197,10 +197,123 @@ { kEventClassService , kEventServiceCopy }, { kEventClassService , kEventServicePaste }, + { kEventClassAccessibility , kEventAccessibleGetNamedAttribute }, + // TODO: Is this needed? { kEventClassAccessibility , kEventAccessibleGetChildAtPoint }, + // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only // { kEventClassControl , kEventControlBoundsChanged } , } ; + +static pascal OSStatus wxMacWindowAccessibilityHandler( EventHandlerCallRef handler , EventRef event , void *data ) +{ + printf("Accesibility callback called\n"); + + OSStatus result = eventNotHandledErr ; + OSStatus error = noErr; + + wxMacCarbonEvent cEvent( event ) ; + + ControlRef controlRef ; + wxWindowMac* thisWindow = (wxWindowMac*) data ; + + cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; + + AXUIElementRef element; + UInt64 identifier; + + error = GetEventParameter( event, kEventParamAccessibleObject, typeCFTypeRef, NULL, sizeof(AXUIElementRef), NULL, &element ); +// require_noerr( error, ParameterMissing ); + + // An identifier of 0 means the whole control, otherwise, it wants info about a child + // or a specific area of the control (e.g. a row) + + AXUIElementGetIdentifier( element, &identifier ); + + switch ( GetEventKind( event ) ) + { + case kEventAccessibleGetNamedAttribute: + CFStringRef attribute; + + printf("Accesibility callbcak, GetNamedAttr, identifier %i\n", (int)identifier); + + error = GetEventParameter( event, kEventParamAccessibleAttributeName, typeCFStringRef, NULL, sizeof(CFStringRef), NULL, &attribute ); +// require_noerr( error, ParameterMissing ); + + if ( identifier == 0 ) + { + // We need to return an array of child accessibility items here. Since it seems to just create them, + // I *think* all we need to do is to get a count of "parts" in the control - in list ctrl terms, rows, + // or perhaps rows + cols then return that. I suspect every control does need at least 1 part though, + // otherwise the call to get kAXDescriptionAttribute below will never be called. + + if ( CFStringCompare( attribute, kAXChildrenAttribute, 0 ) == kCFCompareEqualTo ) + { + + printf("Accesibility callback, Children Attr\n"); + + // Create and return an array of AXUIElements describing the children of this view. + CFMutableArrayRef children; + AXUIElementRef child; + CFIndex i; + + // wxAccessibilityEvent event; + // event.SetEventType(wxAX_GET_PART_COUNT); + // event.SetPartCode(0); + // event.SetEventObject(thisWindow); + // + // if (thisWindow->GetEventHandler()->ProcessEvent(event)) { + + int childrencount = 1; //event.GetPartCount(); + + children = CFArrayCreateMutable( kCFAllocatorDefault, childrencount, &kCFTypeArrayCallBacks ); + for ( i = 0; i < childrencount; i++ ) + { + child = AXUIElementCreateWithHIObjectAndIdentifier( (HIObjectRef)controlRef, i + 1 ); + + CFArrayAppendValue( children, child ); + CFRelease( child ); + } + + SetEventParameter( event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( children ), &children ); + + CFRelease( children ); + + result = noErr; + // } + } else { + printf("Accesibility callback, other Attr\n"); + } + } + else + { + if ( CFStringCompare( attribute, kAXDescriptionAttribute, 0 ) == kCFCompareEqualTo ) + { + + printf("Accesibility id>0 callback, DescriptionAttr\n"); + + // We need to return the string describing this 'part' of the view. For now, you can probably equivilate anything except 0 + // as meaning 'report on the item id returned by wxListCtrl::HitTest at current mouse point'. So something like: + // wxAccessibilityEvent event; + // event.SetEventType(wxAX_GET_PART_DESCRIPTION); + // event.SetPartCode( identifier ); + // event.SetEventObject(thisWindow); + // ... in handler, check what's under the mouse in your handler and provide an appropriate description, + // or just say "list control" or something if GetPartCode() == 0 ... + // if (thisWindow->GetEventHandler()->ProcessEvent(event)) { + // SetEventParameter( event, kEventParamAccessibleAttributeValue, typeCFTypeRef, sizeof( description ), wxMacCFStringHolder(event.GetDescription() , encoding ) ); + // result = noErr; + // } + } else { + printf("Accesibility id>0 callback, Other Attr\n"); + } + } + break; + // TODO: is this needed? case kEventAccessibleGetChildAtPoint: + } + return result; +} + static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; @@ -787,6 +900,9 @@ result = wxMacUnicodeTextEventHandler( handler , event , data ) ; break ; + case kEventClassAccessibility: + result = wxMacWindowAccessibilityHandler( handler , event , data ) ; + break ; default : break ; }