SIGN IN SIGN UP

[linux] Read heading text through the AtkText interface (#188005)

Fixes #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 #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 <robert.ancell@canonical.com>
R
Ricardo Sawir committed
7c18a85ef91a50ac0a91ffc648ba0a1d22b8184a
Parent: 6807bd9
Committed by GitHub <noreply@github.com> on 8/19/2026, 12:16:27 PM