Skip to content

FocusScope - Provide a way to prevent a FocusScope from receiving focus when traversalDescendants is empty #171516

@pedromassango

Description

@pedromassango

Use case

I have a use-case where if descendants of a FocusScope are not focusable, then it should not be possible to focus the scope itself. Otherwise this introduce a bug where you have to press TAB twice (see video & sample code).

Current problem

  1. run the sample code
  2. Press TAB twice

EXPECTED
Since focus scope doesn't have any focusable descendant, then Enabled Button 2 should be focused

CURRENT
You have to press TAB trice to focus Enabled Button 2

NO WORKAROUNDS...
I can't simply set skipTraversal: true dynamically as my parent component doesn't know wether descendants are focusable or not.

Video

preview.mp4

Sample code

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  SemanticsBinding.instance.ensureSemantics();
  final node = FocusScopeNode();
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('FocusScope.onFocusChange Bug')),
        body: Center(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              MaterialButton(
                onPressed: () {}, // disabled
                child: Text('Enabled Button 1'),
              ),
              FocusScope(
                descendantsAreFocusable: true,
                descendantsAreTraversable: true,
                onFocusChange: (focused) {
                  debugPrint('FocusScope: $focused - focusable descendants: ${node.traversalDescendants.length}');
                },
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: const [
                    MaterialButton(
                      onPressed: null, // disabled
                      child: Text('Disabled Button 1'),
                    ),
                    SizedBox(height: 16),
                    MaterialButton(
                      onPressed: null, // disabled
                      child: Text('Disabled Button 2'),
                    ),
                  ],
                ),
              ),
              MaterialButton(
                onPressed: () {}, // disabled
                child: Text('Enabled Button 2'),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}

Proposal

Provide a boolean param so we can control this behaviour, e.g. "skipScopeFocusIfNoTraversalDescendants". When true (regardless of the value from skipTraversal), whenever the Scope is about to gain focus but no descendants are traversable, then "do not" focus the scope itself.

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listf: focusFocus traversal, gaining or losing focusf: material designflutter/packages/flutter/material repository.found in release: 3.32Found to occur in 3.32found in release: 3.33Found to occur in 3.33frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    pFad - Phonifier reborn

    Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

    Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


    Alternative Proxies:

    Alternative Proxy

    pFad Proxy

    pFad v3 Proxy

    pFad v4 Proxy