Add TalkBack accessibility support for links in chat messages#110
Closed
Add TalkBack accessibility support for links in chat messages#110
Conversation
- Created LinkAccessibilityDelegate to expose links as custom actions - Updated ConversationItem to use delegate when TalkBack is enabled - Each link becomes a separate accessible action with clear label Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
- Added accessibility_link_action string resource - Updated LinkAccessibilityDelegate to accept Context and use resource - Updated ConversationItem to pass context to delegate Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
- Reuse LinkAccessibilityDelegate instance instead of creating new one each time - Add detailed comment explaining the magic number for action IDs - Improves performance by avoiding unnecessary object allocations Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
- Explain why accessibility delegate is not set during batch selection - Explain why map is cleared and rebuilt on each accessibility update - Improves code maintainability and readability Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Fix chat links not available for Talkback users
Add TalkBack accessibility support for links in chat messages
Feb 11, 2026
|
@adbenitez I have a few little suggestions though:
Huge thanks for such dedication and preserving screen reader accessibility during Arcanechat and deltachat development. |
Collaborator
|
hi @pvagner thanks a lot for the feedback, about other actions: one step at a time, this will be about solving the specific issue of links, once that is in place then it should be easier to add other actions, we should have a dedicated issue for that one and make then a fix for that other problem (thanks for bringing it up btw! your feedback is very usefull) |
bodyText has importantForAccessibility="no" in the XML layout, so TalkBack focuses the parent ConversationItem. The delegate must be set on `this` and must read spans from a bodyText reference, not from the view it's attached to. Agent-Logs-Url: https://github.com/ArcaneChat/android/sessions/598a695d-a5cd-4948-85e9-edce5e10c67c Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
…mpat The previous code used View.AccessibilityDelegate (raw framework) and AccessibilityNodeInfoCompat.wrap() which is deprecated and does not reliably propagate addAction() to the real AccessibilityNodeInfo that TalkBack reads. Switch to AccessibilityDelegateCompat (AndroidX) set via ViewCompat.setAccessibilityDelegate(). Its onInitializeAccessibilityNodeInfo callback receives a properly-backed AccessibilityNodeInfoCompat so info.addAction() reliably surfaces custom actions in the TalkBack context menu (L-gesture) on all Android versions including API 36. Also clear the delegate in the CALL/empty-text branch to prevent a stale delegate remaining on a recycled view. Agent-Logs-Url: https://github.com/ArcaneChat/android/sessions/87aa7735-a87e-473d-b80c-67e697cd4fa7 Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
…ction for link actions The previous AccessibilityDelegateCompat approach had two fatal flaws: 1. The delegate was only set when isTouchExplorationEnabled() returned true AT BIND TIME — a timing bug that caused TalkBack to see no actions if the view was bound before TalkBack fully initialised. 2. Even when set, the delegate/custom-action-ID approach did not reliably produce an "Actions" submenu in the TalkBack local context menu on Android 14+. Replace the entire mechanism with ViewCompat.addAccessibilityAction(), the modern API (androidx.core 1.5.0+) that TalkBack always surfaces under "Actions". Actions are registered unconditionally at bind time; stale actions from recycled views are removed via ViewCompat.removeAccessibilityAction() before re-registration. Delete the now-unused LinkAccessibilityDelegate class. Agent-Logs-Url: https://github.com/ArcaneChat/android/sessions/95854760-c8e5-43d8-b7b4-55879a7c5dea Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AccessibilityDelegateCompatwas only set whenisTouchExplorationEnabled()returned true at bind time (timing bug), and did not reliably produce an "Actions" submenu in TalkBack on Android 14+ViewCompat.addAccessibilityAction()— the modern, guaranteed API that TalkBack always shows under "Actions"List<Integer>per view and callViewCompat.removeAccessibilityAction()on rebind to clear stale entriesisTouchExplorationEnabled()guard (not needed — registration is unconditional)LinkAccessibilityDelegate.java(no longer needed)Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.