Skip to content

Accessibility Focus ignores Semantics(focused: true) depends on Widget hierarchy #76108

Closed

Description

@omatt

Accessibility Focus prioritizes to highlight the top of widget hierarchy (unless excluded). See sample below where the expected behavior is to have Widget3 be highlighted first by Accessibility Focus.

Scenario 1: Widget3 isn't focused first even with focused: true argument on Semantics. Clip: https://i.stack.imgur.com/sZMPm.gif

Column(    
    children: [        
        Widget1(),        
        Widget2(),               
        Semantics(            
            focused: true            
            child: Widget3()        
        ),    
    ]
)

Scenario 2: Widget3 is first in the widget hierarchy, Widget3 gets highlighted first. Clip: https://i.stack.imgur.com/rLHh1.gif

Column(    
    children: [        
        Semantics(            
            child: Widget3()        
        ),        
        Widget1(),       
        Widget2(),    
    ]
)

I've also tried using ExcludeSemantics, but it renders Widget1 and Widget2 inaccessible from Accessibility Focus.

Steps to Reproduce

Minimal Repro

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final nodes = List.generate(3, (i) => FocusNode());
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Focus'),
      ),
      body: Builder(
          builder: (context) => Center(
                child: RaisedButton(
                  onPressed: () async {
                    nodes[2].requestFocus();
                    await showModalBottomSheet(
                      context: context,
                      builder: (context) => BottomSheet(nodes),
                    );
                  },
                  child: Text('Show bottom sheet'),
                ),
              )),
    );
  }
}

class BottomSheet extends StatelessWidget {
  final List<FocusNode> nodes;
  const BottomSheet(this.nodes);
  @override
  Widget build(BuildContext context) {
    return Container(
      height: 300,
      child: Column(
        children: [
          Row(
            children: [
              OutlineButton(
                focusNode: nodes[0],
                onPressed: () {
                  sleep(Duration(milliseconds: 500));
                  nodes[2].requestFocus();
                },
                child: Text('ONE'),
              ),
              OutlineButton(
                focusNode: nodes[1],
                onPressed: () {
                  nodes[2].requestFocus();
                },
                child: Text('TWO'),
              ),
            ],
          ),
          Expanded(
            child: Center(
              child: Semantics(
                focused: true,
                child: OutlineButton(
                  autofocus: true,
                  focusNode: nodes[2],
                  onPressed: () {},
                  child: Text('THREE'),
                ),
              ),
            ),
          ),
          Text("Can't receive focus"),
        ],
      ),
    );
  }
}
  1. Run the minimal repro on a physical Android device with Accessibility TalkBack enabled
  2. Click 'Show bottom sheet' button to display BottomSheet on screen

Expected results:
'THREE' button should be highlighted

Actual results:
Accessibility Focus ignores Semantics(focused: true) and depends on Widget hierarchy. 'ONE' button gets highlighted.

Logs
[✓] Flutter (Channel master, 1.26.0-2.0.pre.281, on macOS 11.2.1 20D74 darwin-x64)
    • Flutter version 1.26.0-2.0.pre.281
    • Framework revision 4d5db88998 (5 weeks ago), 2021-01-11 10:29:26 -0800
    • Engine revision d5cacaa3a6
    • Dart version 2.12.0 (build 2.12.0-211.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK
    • Platform android-30, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.0.1, Build version 12A7300
    • CocoaPods version 1.10.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)

[✓] VS Code (version 1.52.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.18.1

[✓] Connected device (1 available)
    • Chrome (web) • chrome • web-javascript • Google Chrome 88.0.4324.150

• No issues found!

Activity

  1. darshankawar commented on Feb 16, 2021

    @darshankawar
    Member

    Issue replicable on latest stable (1.22.6). ONE button is read / highlighted first.

    flutter doctor -v
    [✓] Flutter (Channel stable, 1.22.6, on Mac OS X 10.15.4 19E2269 darwin-x64,
        locale en-IN)
        • Flutter version 1.22.6 at /Users/dhs/documents/Fluttersdk/flutter
        • Framework revision 9b2d32b605 (4 weeks ago), 2021-01-22 14:36:39 -0800
        • Engine revision 2f0af37152
        • Dart version 2.10.5
    
     
    [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
        • Android SDK at /Users/dhs/Library/Android/sdk
        • Platform android-30, build-tools 30.0.0
        • Java binary at: /Applications/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build
          1.8.0_242-release-1644-b3-6915495)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 12.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 12.3, Build version 12C33
        • CocoaPods version 1.9.3
    
    [!] Android Studio (version 4.1)
        • Android Studio at /Applications/Android Studio.app/Contents
        ✗ Flutter plugin not installed; this adds Flutter specific functionality.
        ✗ Dart plugin not installed; this adds Dart specific functionality.
        • Java version OpenJDK Runtime Environment (build
          1.8.0_242-release-1644-b3-6915495)
    
    [✓] VS Code (version 1.53.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.18.1
    
    [✓] Connected device (2 available)
        • SM A260G (mobile)          • 5200763ebcfa861f                     •
          android-arm • Android 8.1.0 (API 27)
        • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios
          • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    
    ! Doctor found issues in 1 category.
    
    
  2. added
    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    platform-androidAndroid applications specifically
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Feb 16, 2021
  3. chunhtai commented on Feb 17, 2021

    @chunhtai
    Contributor

    Hi @omatt

    What you see is expected, the Semantics(focused: true) is used for keyboard focus, it is different from accessibility focus.

    We do not support programmatically changing accessibility focus because it is against a11y guideline and can make talkback user confused. However, you can use semantics sortkey to change the semantics traverse order. For example, you can do something like this

    Column(
            children: [
              Semantics(
                sortKey: OrdinalSortKey(3),
                child: Text('1'),
              ),
              Semantics(
                  sortKey: OrdinalSortKey(2),
                  child: Text('2'),
              ),
              Semantics(
                  sortKey: OrdinalSortKey(1),
                  child: Text('3')
              ),
            ]
          )

    In this example text 3 will be focused first. If you swipe right, the text2 will be focused next.

  4. omatt commented on Feb 17, 2021

    @omatt
    MemberAuthor

    Thanks @chunhtai Semantics(sortKey: SemanticsSortKey) is a good workaround and fits my use case. I'm able to verify it working on my build.

  5. github-actions commented on Aug 5, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  6. locked as resolved and limited conversation to collaborators on Aug 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)found in release: 1.22Found to occur in 1.22frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: material_uimaterial_ui package in flutter/packagesplatform-androidAndroid applications specificallyr: solvedIssue is closed as solved

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions