Search code examples
flutter

Why is KeyEventResult.handled in a root Focus blocking the KeyEvent from getting to the leaf (primaryFocus) EditableText?


As I understand it, key events are supposed to start at the leafmost focused FocusNode then propagate to the root FocusNode if the leaf node allows it through. So, the Focus widget here shouldn't be able to block key events from reaching the TextField, but it is! You'll find that you can't type anything into it. (If you change the KeyEventResponse to KeyEventResponse.ignored, the TextField will become editable again, so you see that is what's causing it)

https://dartpad.dev/?id=7b5b886697310f363c4d6c2c1aedaced

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(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: Focus(onKeyEvent: (FocusNode f, KeyEvent e){
            return KeyEventResult.handled;
          }, child: TextField()),
        ),
      ),
    );
  }
}

Am I misunderstanding something about the focus tree? I even checked the focus tree's stack to make sure the EditableText at the leaf really was the primaryFocus, and it was.


Solution

  • From Understanding Flutter's keyboard focus system:

    Focus key events are processed before text entry events, so handling a key event when the focus widget surrounds a text field prevents that key from being entered into the text field.

    So the effect you see is by design. Returning KeyEventResult.ignored is the correct solution, as shown in the example at the link.