Repository navigation
[CP-stable][linux] Read heading text through the AtkText interface - #191397
Conversation
Fixes flutter#187925 ## Problem On Linux, a node with `Semantics(header: true)` is announced by Orca as just **"header"** — the node's text is never read. With `header: false` the same text is read correctly. ## Root cause Two issues in the Linux embedder's accessibility code (`engine/src/flutter/shell/platform/linux/`): 1. **The node's label is exposed only via the `AtkObject` name property, not the `AtkText` interface.** Orca reads the text content of a heading **exclusively through `AtkText`** (see `_generate_heading` in Orca's `speech_generator.py`, which calls `_generate_text_content` → `AXText.get_substring` → `atk_text_get_text`). It never falls back to the name for the heading/header roles. So Orca finds no text and announces only the role. This matches the ATK contract used by GTK: `GtkLabel` exposes its text through `AtkText`. Flutter's label **is** its text content, so it should be exposed the same way. (`FlAccessibleTextField` already does this for editable text.) 2. **The wrong ATK role.** `is_header` maps to `ATK_ROLE_HEADER`, which is the *document masthead/banner* role. `ATK_ROLE_HEADING` is the *content-heading* role (the HTML `<h1>`–`<h6>` analogue) and is what `Semantics(header: true)` means (matching iOS `header` trait and Android heading class). ## Fix * Implement the `AtkText` interface on `FlAccessibleNode`, backed by the node's existing accessibility name (`get_character_count`, `get_text`, `get_character_at_offset`, `get_caret_offset`, `get_n_selections`, `get_selection`, `get_text_at_offset`). This is safe for other roles: Orca's default presentation for buttons/panels/images reads the `AtkObject` name via `_generate_accessible_label_and_name`, not `AtkText`, so their announcement is unchanged. `FlAccessibleTextField` already declares a richer `AtkText` and continues to override the base implementation. * Map the `is_header` flag to `ATK_ROLE_HEADING`. ## Result For the repro in flutter#187925, Orca now announces **"Section One, heading"** instead of just **"header"**. ## Test plan - [x] Added `ExposesTextViaAtkText` test verifying `atk_text_get_character_count` / `atk_text_get_text` / `atk_text_get_character_at_offset` return the node's label. - [x] Extended the existing role-mapping test to assert `is_header` → `ATK_ROLE_HEADING`. - [ ] `Linux linux_unit_tests` (cannot run locally — Linux GTK/ATK build; developed/analyzed on macOS). Reviewers, please confirm CI is green. --------- Co-authored-by: Robert Ancell <[email protected]>
|
@robert-ancell please fill out the PR description above, afterwards the release team will review this request. |
|
This pull request was opened from and to a release candidate branch. This should only be done as part of the official Flutter release process. If you are attempting to make a regular contribution to the Flutter project, please close this PR and follow the instructions at Tree Hygiene for detailed instructions on contributing to Flutter. Reviewers: Use caution before merging pull requests to release branches. Ensure the proper procedure has been followed. |
There was a problem hiding this comment.
Code Review
This pull request implements the AtkText interface for FlAccessibleNode in the Flutter Linux shell, enabling screen readers to read the text content of accessible nodes like headings. It also updates the header role mapping to ATK_ROLE_HEADING and adds comprehensive unit tests. Feedback suggests simplifying a redundant null check on priv->name in fl_accessible_node_get_string_at_offset.
|
I have tested this myself and can confirm that it now announces the text followed by the roll which is the expected behavior. Thanks or this fix! |
d2ab418
into
flutter:flutter-3.47-candidate.0
This pull request is created by automatic cherry pick workflow
Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request.
Issue Link:
What is the link to the issue this cherry-pick is addressing?
#187925
Impact Description:
What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)?
Does it impact development (ex. flutter doctor crashes when Android Studio is installed),
or the shipping of production apps (the app crashes on launch).
This information is for domain experts and release engineers to understand the consequences of saying yes or no to the cherry pick.
Linux embedder was not correctly handling semantic nodes with
headerset to true, which meant screen readers would not announce these correctly.Changelog Description:
Explain this cherry pick:
See best practices for examples.
[flutter/187925] Fix header elements not being announced by screen reader on Linux
Workaround:
Is there a workaround for this issue?
No workaround.
Risk:
What is the risk level of this cherry-pick?
Test Coverage:
Are you confident that your fix is well-tested by automated tests?
Validation Steps:
What are the steps to validate that this fix works?
Run Flutter app in #187925 on Linux with screen reader enabled. Tab to heading and confirm it is correctly read out as "Section One" instead of "header".