Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter FocusNode onKeyEvent detect multiple keys

Tags:

flutter

Using this for Flutter Desktop. I used to use onKey of FocusNode. The doc says it will be deprecated:

  /// To receive key events that focuses on this node, pass a listener to `onKeyEvent`.
  /// The `onKey` is a legacy API based on [RawKeyEvent] and will be deprecated
  /// in the future.

This is how I used onKey for detecting shift + enter:

FocusNode(          
    onKey: (node, event)
    {
        if (event.isKeyPressed(LogicalKeyboardKey.enter))
        {
            if (event.isShiftPressed)
                return KeyEventResult.ignored;

            sendAction();
            return KeyEventResult.handled;
        }

        return KeyEventResult.ignored;
    },

How do you detect multiple keys being pressed at the same time with onKeyEvent?

Edit: I'm looking for a way to detect multiple keys being pressed WITHOUT the legacy approach. The event parameter in onKeyEvent is not RawKeyEvent type, therefore isKeyPressed() is not available there. The only thing available is event.logicalKey.keyLabel which can't be used for multiple key detection.

like image 800
alex smith Avatar asked Oct 16 '25 05:10

alex smith


2 Answers

To handle the shortcuts Flutter has Shortcut widget. To start using it you have to specify:

  • Intent - describes that shortcut intent triggered
  • Action - describes action on triggered Intent

Let's create an intent class

class NewLineIntent extends Intent {
  const NewLineIntent();
}

Add it to your widget and specify the conditions:

static const newLine = SingleActivator(LogicalKeyboardKey.enter, shift: true);

Finally, build a widget:

@override
Widget build(BuildContext context) {
    return Shortcuts(
      shortcuts: const {
        newLine: NewLineIntent()
      },
      child: Actions(
        actions: {
          NewLineIntent: CallbackAction<NewLineIntent>(
            onInvoke: (NewLineIntent intent) {
              print('New line');
            },
          )
        },
        child: Focus(
          autofocus: true,
          child: ... ,
        ),
      ),
    );
  }

And when your widget will appear on the screen and you press Shift + Enter your shortcut will be triggered.

like image 154
powerman23rus Avatar answered Oct 18 '25 20:10

powerman23rus


The behavior of onKeyEvent is indeed quite strange because it doesn't allow to check for modifier keys while pressing another key. It just supports handling of one key at a time. So if you want to check for multiple keys pressed, you can use HardwareKeyboard to check for another key when pressing enter. Like this:

FocusNode(
  onKeyEvent: (node, event) {
    final enterPressedWithShift = event is KeyDownEvent &&
        event.physicalKey == PhysicalKeyboardKey.enter &&
        HardwareKeyboard.instance.physicalKeysPressed.any(
          (key) => <PhysicalKeyboardKey>{
            PhysicalKeyboardKey.shiftLeft,
            PhysicalKeyboardKey.shiftRight,
          }.contains(key),
        );

    if (enterPressedWithShift) {
      // Do something
      return KeyEventResult.handled;
    } else {
      return KeyEventResult.ignored;
    }
  },
);
like image 23
Donny Rozendal Avatar answered Oct 18 '25 20:10

Donny Rozendal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!