Flutter - actively check if special key (like ctrl) is pressed
Asked Answered
T

3

12

Question: How to actively check if a certain (decoration) key is pressed, like CTRL or SHIFT, like:

if (SomeKeyboardRelatedService.isControlPressed()) {...}

background

I'd like to check if a certain (decoration) key is pressed when the user clicks the mouse. We cannot manage to do it actively. Instead, we are using RawKeyboardListener and remember the isControlPressed in onKey event. This way, later in GestureDetector.onTap we can check if isControlPressed is true. The problem is:

  1. It seems nowhere reasonable to maintain the key pressed state on our own, as it violated the single-source-of-truth principle and may cause inconsistency.
  2. It actually IS causing inconsistency, if the user switches away from the app while holding the special key.

We have read relevant docs and searched with several keywords and ended up with no result.

Teaspoon answered 29/3, 2022 at 9:44 Comment(0)
S
15

RawKeyboard is probably what you are looking for. Example:

RawKeyboard.instance.keysPressed.contains(LogicalKeyboardKey.controlLeft)

Note that you need to check for all possible key variants when checking for control keys etc.

final shiftKeys = [LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.shiftRight];
final isShiftPressed = RawKeyboard.instance.keysPressed
    .where((it) => shiftKeys.contains(it))
    .isNotEmpty;
Somersomers answered 13/4, 2022 at 7:56 Comment(1)
Please use HardwareKeyboard instead to avoid missing KeyDown events. "RawKeyboard is the legacy API, and will be deprecated and removed in the future. It is recommended to always use HardwareKeyboard and KeyEvent APIs (such as FocusNode.onKeyEvent) to handle key events."Undersea
D
8

Since Flutter 3.19

'RawKeyboardListener' is deprecated and shouldn't be used. Use KeyboardListener instead. This feature was deprecated after v3.18.0-2.0.pre.

Instead of RawKeyEvent.isShiftPressed use:

HardwareKeyboard.instance.isShiftPressed;
Digamy answered 26/2 at 9:31 Comment(1)
Note that the new replacement does not work on Android, even if a hardware keyboard is present. RawKeyEvent.isShiftPressed works on Android for both virtual and hardware keyboards. The new replacement only works on desktop platforms. I haven't found a way yet to detect if shift was pressed on Android (to distinguish "enter" and "shift+enter") without RawKeyEvent.Brotherhood
R
4

i use this method to detect if ctrl + v or cmd + v is pressed, to get image from clipboard

1

// declare focusNode first
final _fokusTitle = FocusNode();

...

2

Padding(
            padding: const EdgeInsets.all(60),
            // listen key press widget
            child: RawKeyboardListener(
              // add focus node here
              focusNode: _fokusTitle,
              child: Text("halo apa kabar , saya disini"),
              onKey: (x) async {
                // detect if ctrl + v or cmd + v is pressed
                if (x.isControlPressed && x.character == "v" || x.isMetaPressed && x.character == "v") {
                  // you need add some package "pasteboard" , 
                  // if you wan to get image from clipboard, or just replace with some handle
                  final imageBytes = await Pasteboard.image;
                  print(imageBytes?.length);
                }
              },
            ),
          )

...

3

Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  // keyboard listener will catch some key pressed here , if you focused cursor here
                                  child: TextFormField(
                                    focusNode: _fokusTitle,
                                    controller: _controllerTitle,
                                    maxLength: 50,
                                    maxLines: 1,
                                    decoration: InputDecoration(hintText: "mulai ketik sesuatu", labelText: "judul"),
                                  ),
                                ),
Reading answered 10/7, 2022 at 4:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.