Skip to content

[web] ChromeVox stuck on first item in a scrollable list #128709

@marcianx

Description

@marcianx

b/286441683

Is there an existing issue for this?

Steps to reproduce

  1. See the code below. Importantly, it uses a ListView with large complex items and uses a large cacheExtent so that SemanticsNodes for all children are generated to demonstrate that this issue is not due to a lack of semantics in the DOM, which is what I originally attributed the issue to.
  2. Resize the window small so that only half the first text area is visible (see Screencast below).
  3. Use ChromeVox to navigate through this UI using basic navigation (Search + Left/Right shortcuts).

Expected results

ChromeVox should be able to navigate through all items in the view.

Actual results

ChromeVox keeps looping through various parts of the first item in the ListView (see screencast).

Code sample

Code sample

It approximates some parts of the apps structure where I demonstrated this. It includes some additional code for debugging to be able to visually confirm that the semantics tree is fine.

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

void main() {
  runApp(const ScrollBug());
  SemanticsBinding.instance.ensureSemantics();
}

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

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      debugDumpSemanticsTree();
    });
    return MaterialApp(
      title: 'Scroll bug',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).colorScheme.inversePrimary,
          title: Text('Scroll bug'),
        ),
        body: ListView(
          cacheExtent: 1000,  // So that semantics for all 3 children is generated.
          children: <Widget>[
            _longContent(context, 1),
            _longContent(context, 2),
            _longContent(context, 3),
          ],
        ),
      ),
    );
  }

  Widget _longContent(BuildContext context, int index) {
    final message1 = 'The quick brown fox jumped over the lazy dog $index.';
    final message2 = 'The five boxing wizards jump quickly $index.';
    return Column(
      children: [
        LayoutBuilder(builder: (context, constraints) {
          return Row(
            children: [
              SizedBox(
                width: constraints.maxWidth / 2,
                child: outlined(RichText(
                    text: TextSpan(
                        text: '$message1 $message1 $message1 $message1'))),
              ),
              SizedBox(
                width: constraints.maxWidth / 2,
                child: outlined(RichText(
                    text: TextSpan(
                        text: '$message2 $message2 $message2 $message2'))),
              ),
            ],
          );
        }),
        outlined(Semantics( // Needed due to go/flutter-issues/26336
          container: true,
          child: const TextField(maxLines: null, minLines: 8),
        )),
        outlined(Wrap(children: [
          TextButton(onPressed: () {}, child: Text('Testing $index'))
        ])),
      ],
    );
  }
}

Widget outlined(Widget child) {
  return Padding(
    padding: const EdgeInsets.all(4),
    child: Container(
      decoration: BoxDecoration(border: Border.all()),
      padding: const EdgeInsets.all(10),
      child: child,
    ),
  );
}

Screenshots or Video

Screenshots / Video demonstration
ChromeVox.stuck.on.first.item.webm

Logs

N/A

Flutter Doctor output

Doctor output

I had to run a server within google3 to be able to access it remotely on my ChromeBook. So this is the output of fg3 doctor -v. I've edited the paths out with [...].

[   +6 ms] ProcessManager.runSync('which java')
[ +374 ms] ProcessManager.runSync('which java')
[  +14 ms] java -version
[   +3 ms] ProcessManager.run('/usr/local/buildtools/java/jdk/bin/java -version')
[   +4 ms] executing: [...]/java/android/android_sdk_linux/platform-tools/adb.static devices -l
[   +4 ms] ProcessManager.run('[...]/java/android/android_sdk_linux/platform-tools/adb.static devices -l')
[   +3 ms] Flag --fuchsia not found, Fuchsia device discovery disabled.
[   +3 ms] Gallium device polling: connecting to galliumd.
[   +5 ms] [✓] Flutter (Channel google3, on Debian GNU/Linux rodete 6.1.25-1rodete1-amd64, locale en_US.UTF-8)
[   +3 ms]     • Framework revision 9e4104b094 (19 days ago), 2023-05-24T00:00:00.000
[   +3 ms]     • Engine revision 62a83490ee
[   +4 ms]     • Dart version 96e29af6e0
[ +338 ms] [✓] Android toolchain - develop for Android devices (Android SDK version Stable)
[   +4 ms]     • Android SDK at google3
[   +3 ms]     • Platform Stable, build-tools Stable
[   +3 ms]     • Java binary at: /usr/local/buildtools/java/jdk/bin/java
[   +3 ms]     • Java version OpenJDK Runtime Environment (build 11.0.16.1+1-google-release-533553428)
[   +4 ms] [!] Android Studio (not installed)
[   +3 ms]     • Android Studio not found; download from https://developer.android.com/studio/index.html
[   +3 ms]       (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).
[   +4 ms] [✓] VS Code (version 1.78.0)
[   +3 ms]     • VS Code at /usr/share/code
[   +4 ms]     • Flutter extension can be installed from:
[   +3 ms]       🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[   +5 ms] Gallium device polling failed to connect to galliumd: gRPC Error (code: 14, codeName: UNAVAILABLE, message: Error connecting: SocketException: Connection refused (OS Error: Connection refused, errno = 111), address = localhost, port = 33174, details: null, rawResponse:
null, trailers: {})
[  +18 ms] List of devices attached


           * daemon not running; starting now at tcp:5037
           * daemon started successfully
[   +4 ms] executing: uname -m
[   +3 ms] ProcessManager.runSync('uname -m')
[   +9 ms] Exit code 0 from: uname -m
[   +3 ms] x86_64
[   +4 ms] executing: [...]/java/android/android_sdk_linux/platform-tools/adb.static devices -l
[   +3 ms] ProcessManager.run('[...]/java/android/android_sdk_linux/platform-tools/adb.static devices -l')
[  +11 ms] List of devices attached
[   +4 ms] [✓] Connected device (1 available)
[   +3 ms]     • Linux (desktop) • linux • linux-x64 • Debian GNU/Linux rodete 6.1.25-1rodete1-amd64
[   +4 ms] [✓] Google3 (on linux)
[   +3 ms]     • KVM enabled
[   +3 ms] ! Doctor found issues in 1 category.
[   +3 ms] "flutter doctor" took 899ms.
[+2858 ms] ensureAnalyticsSent: 2853ms
[   +4 ms] Running 0 shutdown hooks
[   +4 ms] Shutdown hooks complete
[   +4 ms] exiting with code 0

Metadata

Metadata

Assignees

Labels

P0Critical issues such as a build break or regressiona: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)customer: googleVarious Google teamse: device-specificOnly manifests on certain devicesf: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.platform-chromebookChromebook applications specificallyplatform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions