Fix/extend LCL TLazAccessibleObject
Original Reporter info from Mantis: djenkins @dfjenkins
-
Reporter name: David Jenkins
Original Reporter info from Mantis: djenkins @dfjenkins
- Reporter name: David Jenkins
Description:
Fixed some issues with TLazAccessibleObject and added some additional functionality. Implemented mostly complete accessibility functionality for Cocoa. Implement base functionality for Qt5.
Patch files are broken into lcl only, interfaces/cocoa only, and interfaces/qt5 only. Patches are created against lazarus/trunk rev 64768
accessiblity_lcl.patch
- Updated TLazAccessiblityRole enum and put larIgnore at the top as first entry so that it is the default value
- Added accessibleName as new parameter
Current object has three base param: Description, Role, Value. Qt5 and Cocoa have four: Description, Role, Value, and Name (qt5) or Title (cocoa). Description in cocoa/qt5 is expected to be an instance specific, more than a couple of word, string that gives the user a better idea of what that specific instance is doing. Name/Title is expected to be a short - mostly one word - description that can be used as a search Id. It was difficult to create a good Name/Title entry out of either Description or Role. So I added accessiblityName.
- Added some nil checking and a couple of other fixes to handle crashes that were occuring with TLazAcessibleObject code.
- TLazAccessibleObject.FChildrenSortedForDataObject was not being sorted by DataObject.
- when created a sort function was passed in but it did not sort on DataObject.
- When objects were added to the TavlTree they were added before the DataObject had been attached. Sorting happens on add. They couldn't be sorted. See code in TreeView.inc.
It is possible that the original intent was to have a DataObject sorted tree and then that intent changed, the sort filter was changed and TreeView.inc adding of children was changed.
However, the name is still FChildrenSortedForDataObject and there are several children related functions that are currently now working because they expect a DataObject sorted tree.
So I changed the sort function back to one that sorts on DataObject. Changed AddChildAccessibleObject to take the DataObject as a param. Also changed AddChildAccessibleObject() to search existing tree to see if it already has an object matching the one being added and return existing child if so. And then changed code in TreeView.inc to use the new function. TreeView.inc was the only place that children were being added to a TLazAccessibleObject.
The tree is not DataObject sorted.
- Fixed child related functions that relied on DataObject sort so that they are fully functional. Previously they did not work at all because of the incorrect sort. With sort fixed there were still a few tweaks needed.
- Extended parent type functionality by making sure that when a child it destroyed it removes itself from it's parent. Also when a child is inserted into a parent make sure it isn't already connected to another parent and remove itself if it is. And cleared parent value of child when it was removed from parent.
- modified TCustomLabel to update accessibleValue when its text is changed.
- Gave TToolButton an accessible role so that it isn't defaulted to larIgnore. And have it update accessibleName when it's text is changed.
General Issues that could be resolved in LCL code that I haven't done anything with.
- Both qt5/cocoa include accessibility notification functionalility that allows an app to alert an accessiblity client that the ui has changed (differnt tab selected, treeview item disclosed, etc). LCL has not current method to generate a notification or request that the widgetset layer do so.
I think this could be done by adding a sendAccessibleNotification(AValue: TAccNotificationType) where TAccNotification is a subset of the possible types of notifcations that Qt5/Cocoa support.
- Qt and Cocoa both have sufficient accessiblity build into the native widgets that the handles used for TWinControl can also be the handles that back TWinControl.TLazAccessibleObject. But there is not current connection between TWinControl getting a handle and the TlazAccessibleObject getting a handle. It would be good to have TWinControl request that it's TLazAccessibleObject.handle be updated/created when TWinControl is handled.
If the above were done then some of the somewhat wedged code in Qt5 could be changed and the TQtWSLazAccessibleObject.CreateHandle() code could handle what is being done in TQtCustomControl.InitializeAccessibility.