flutter / flutter/flutter

[iOS][FKA] Full Keyboard Access does not scroll to offscreen Semantics nodes in SingleChildScrollView and does not trigger focus callbacks

Open
#187,055 1 comment 0 reactions 1 assignee Claimed by @chunhtai View on GitHub
a: accessibility has reproducible steps P2 platform-ios team-accessibility triaged-accessibility
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Steps to reproduce

1. Create a Flutter app with a `SingleChildScrollView` containing enough focusable controls to require scrolling.
2. Add visible controls at the top and additional controls below the initial viewport.
3. Wrap some controls in `Semantics(
button: true,
focusable: true,
onTap: ...,
onFocus: ...,
onDidGainAccessibilityFocus: ...,
)`.
4. Run the app on iOS with a physical/external keyboard.
5. Enable iOS Full Keyboard Access.
6. Navigate using `Tab` / `Shift+Tab`.
7. Try to reach controls that are below the visible part of the `SingleChildScrollView`.
8. Try activating a visible Semantics node with Space/Enter.

### Expected results

Full Keyboard Access should be able to navigate to all focusable/semantic controls in the scroll view.

When focus moves to an offscreen control, Flutter should either:
- automatically scroll the `SingleChildScrollView` to reveal the focused semantic node, or
- dispatch a focus/accessibility callback such as `Semantics.onFocus` or `Semantics.onDidGainAccessibilityFocus`, so the app can call `Scrollable.ensureVisible`.

Keyboard activation should continue to invoke `Semantics.onTap`.

### Actual results

Visible semantic controls can be activated: `Semantics.onTap` is called.

However, while navigating with Full Keyboard Access:
- `Semantics.onFocus` is not called.
- `Semantics.onDidGainAccessibilityFocus` is not called.
- Flutter `FocusNode` / `FocusManager.primaryFocus` does not move to the focused semantic controls.
- `HardwareKeyboard` does not receive `Tab` / `Shift+Tab` while FKA is enabled.
- `Scrollable.ensureVisible` cannot be triggered because Dart receives no focus-change callback.
- Offscreen controls inside `SingleChildScrollView` are not scrolled into view and cannot be reached by keyboard navigation.

This was reproduced both with custom form widgets and with plain `OutlinedButton` widgets wrapped in `Semantics(button: true, focusable: true, onTap, onFocus, onDidGainAccessibilityFocus)`.

### Code sample

Code sample

```dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('FKA repro')),
body: SingleChildScrollView(
child: Column(
children: [
for (var index = 1; index <= 20; index++)
Padding(
padding: const EdgeInsets.all(16),
child: Semantics(
container: true,
button: true,
focusable: true,
label: 'FKA probe button $index',
onTap: () => debugPrint('button $index onTap'),
onFocus: () => debugPrint('button $index onFocus'),
onDidGainAccessibilityFocus: () {
debugPrint('button $index onDidGainAccessibilityFocus');
},
child: ExcludeSemantics(
child: OutlinedButton(
onPressed: () =>
debugPrint('button $index onPressed'),
child: Text('FKA probe button $index'),
),
),
),
),
],
),
),
),
);
}
}
```

### Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

### Logs

Logs

```console
[Paste your logs here]
```

### Flutter Doctor output

Doctor output

```console
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.38.10, on macOS 15.3.1 24D70 darwin-arm64, locale pl-PL)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.4)
[✓] Chrome - develop for the web
[✓] Connected device (4 available)
! Error: Browsing on the local area network for iPad. Ensure the device is unlocked and attached with a cable or associated with the same local area network as this Mac.
The device must be opted into Developer Mode to connect wirelessly. (code -27)
[✓] Network resources

• No issues found!
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.