Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On Android, KeyboardListener catches software keyboard input. #148375

Open
asci-00 opened this issue May 15, 2024 · 14 comments
Open

On Android, KeyboardListener catches software keyboard input. #148375

asci-00 opened this issue May 15, 2024 · 14 comments
Labels
a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project platform-android Android applications specifically team-text-input Owned by Text Input team triaged-text-input Triaged by Text Input team

Comments

@asci-00
Copy link
Contributor

asci-00 commented May 15, 2024

Steps to reproduce

Our app has a function that operates by distinguishing between hardware (bluetooth) keyboard input and software keyboard input for TextField.
While searching for the API provided by Flutter to implement this, I came across the KeyboardListener widget description below.

/// ..in keyboard_listener.dart
/// A [KeyboardListener] is useful for listening to key events and
/// hardware buttons that are represented as keys. Typically used by games and
/// other apps that use keyboards for purposes other than text entry.

/// ..in hardware_keyboard.dart
/// The [KeyEvent] provides a universal model for key event information from a
/// hardware keyboard across platforms.

From the above explanation, I understood that KeyboardListener only recognizes hardware keys.

We applied this to our project because we thought it suited our requirements, but the actual behavior was different from what we expected.

In fact, when we run the app with the code below using KeyboardListenerd, the backspace (if there is no string to delete) and enter (textfield property - textInputAction: newline) keys entered on the software keyboard are detected as if backspace or enter were pressed on the hardware keyboard.
Additionally, we were unable to determine whether the input was software or hardware from the detected results.

Does this mean I misunderstood the document? or is this not the widget provided with this intention?
I'm not sure if this is a bug, but if this is the intended result, it would be helpful if the documentation for KeyboardListener or KeyEvent was a bit nicer.
Also, if there is a way to implement the above requirements, please kindly let me know.

(I tested it on Samsung Keyboard and GBoard, and the results were different. I used a Korean/English keyboard, and it was also different when I typed in Korean and English. - test os: android - )

Expected results

Key input from the software keyboard is not detected in the Keyboardlistener onKeyEvent.

Actual results

Depending on the keyboard type / input language / key type, onKeyEvent is called for some software keyboard inputs.

Code sample

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final FocusNode focusNode = FocusNode();

  @override
  void dispose() {
    focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("keyboard listener")),
      body: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
        KeyboardListener(
          focusNode: focusNode,
          onKeyEvent: print,
          child: const TextField(textInputAction: TextInputAction.newline),
        ),
      ]),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[Paste your output here]
@darshankawar darshankawar added the in triage Presently being triaged by the triage team label May 15, 2024
@darshankawar
Copy link
Member

@asci-00
Can you check if this resembles your case or not ?
Also check if this is related #44681

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 15, 2024
@asci-00
Copy link
Contributor Author

asci-00 commented May 15, 2024

Hi @darshankawar
Well, I don't know if it's completely unrelated, but
#51478 issue is an issue where the OnScreen keyboard (the software keyboard I wrote above) is opened due to input from the hardware keyboard.
#44681 issue is also related to this, and seems to be a question about how to not raise the keyboard when the textfield has focus. It may be related internally, but it seems to be a different problem than mine.

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 15, 2024
@darshankawar
Copy link
Member

Thanks for the update. Check if this applies to your case as well or not.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 16, 2024
@LongCatIsLooong
Copy link
Contributor

The Android InputConnection API allows a software keyboard to send a keypress as a KeyEvent (https://developer.android.com/reference/android/view/inputmethod/InputConnection#sendKeyEvent(android.view.KeyEvent)).

Usually keyboards do that for backspace because sometimes if a text field is already empty you want to move the focus to the previous field. Flutter currently does not distinguish KeyEvents emitted by this method call and KeyEvents generated by physical keyboards.

@asci-00
Copy link
Contributor Author

asci-00 commented May 18, 2024

@darshankawar I'm not sure if I understand the problem correctly. I think the issue is that the hardware keyboard operates differently depending on the mobile device (s9 / pixel) when using RawKeyboardListener.
It seems like a similar problem to some extent, but the point of my issue is that keypress from the “software keyboard” are detected by KeyboardListener, so it seems like a different issue. Please let me know if I misunderstood the issue

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 18, 2024
@asci-00
Copy link
Contributor Author

asci-00 commented May 18, 2024

@LongCatIsLooong thank you for the reply.
This is an area I don't know, so I'd like to ask. Is the entity that raises KeyEvent using InputConnection the software keyboard? ex) GBoard / Samsung Keyboard
Also, I wonder if the Enter key, other than backspace, also applies.
If so, I am curious as to whether it is possible to distinguish the KeyEvent in Flutter (at a low level) and whether it plans to support the function to distinguish it.
If it is not supported, is there any way to implement the requirements I mentioned?

@darshankawar
Copy link
Member

@asci-00
Check if below issues help in your case or not:

#142882
#131510

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 20, 2024
@LongCatIsLooong LongCatIsLooong removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 20, 2024
@LongCatIsLooong
Copy link
Contributor

@LongCatIsLooong thank you for the reply. This is an area I don't know, so I'd like to ask. Is the entity that raises KeyEvent using InputConnection the software keyboard? ex) GBoard / Samsung Keyboard Also, I wonder if the Enter key, other than backspace, also applies. If so, I am curious as to whether it is possible to distinguish the KeyEvent in Flutter (at a low level) and whether it plans to support the function to distinguish it. If it is not supported, is there any way to implement the requirements I mentioned?

Yes. Software keyboards (Gboard / Samsung Keyboard) can choose to send certain key presses as hardware key events (for reasons stated above). They can even send "A" as a key event if they so choose.

If so, I am curious as to whether it is possible to distinguish the KeyEvent in Flutter

I believe this is possible on Android because they have separate call paths: https://github.com/flutter/engine/blob/c6fecf65fbf385c5e9168c5b40526c9ae998045b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java#L285-L287

But this may not be possible on other platforms. And editors typically don't need such information.

Our app has a function that operates by distinguishing between hardware (bluetooth) keyboard input and software keyboard input

This sounds like a relatively niche use case, could you elaborate?

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 21, 2024
@asci-00
Copy link
Contributor Author

asci-00 commented May 26, 2024

@LongCatIsLooong Sorry for the late reply. 😓
To explain part of the function, you can set the enter (submit) action of the software keyboard and the enter action of the hardware keyboard separately in the textfield.
If you press enter on a hardware keyboard, the default action branches into two actions depending on the value you set.

  1. When press enter, newline
  2. When press enter, send
    However, the software keyboard must always be newline.

However, flutter cannot check whether the hardware keyboard is connected and
In the case of Samsung keyboards, due to an issue, the software keyboard comes up even when the hardware keyboard is connected unless the user configures it separately.
Therefore, we need to know whether the Enter KeyEvent caught by KeyboardListener occurred in hardware or software, but there is no way to distinguish between them. This is the current problem situation.

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 26, 2024
@darshankawar
Copy link
Member

Keeping the issue open and labeling for team's tracking.

@darshankawar darshankawar added a: text input Entering text in a text field or keyboard related problems platform-android Android applications specifically framework flutter/packages/flutter repository. See also f: labels. team-text-input Owned by Text Input team and removed in triage Presently being triaged by the triage team labels May 27, 2024
@LongCatIsLooong
Copy link
Contributor

@asci-00
Copy link
Contributor Author

asci-00 commented May 29, 2024

@LongCatIsLooong
Could you please explain in more detail?
When I checked by applying onEditingComplete, it seems that both hardware Enter and software Enter are not distinguished and are caught in callback.

@LongCatIsLooong
Copy link
Contributor

LongCatIsLooong commented May 29, 2024

Ah indeed it does, but it's disabled for multiline: https://github.com/flutter/engine/blob/557a4c622617c6c0f66b604669d14d11b8aa1cbe/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java#L304

This is a bit strange. I don't think a hardware key-presses should trigger performEditorAction automatically.

@LongCatIsLooong LongCatIsLooong added P3 Issues that are less important to the Flutter project labels May 29, 2024
@LongCatIsLooong LongCatIsLooong added P3 Issues that are less important to the Flutter project triaged-text-input Triaged by Text Input team labels May 29, 2024
@LongCatIsLooong
Copy link
Contributor

Tentatively marked this issue as P3. However, if you would like to see this issue fixed sooner, you are welcome to open a pull request to remove the logic that is causing this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project platform-android Android applications specifically team-text-input Owned by Text Input team triaged-text-input Triaged by Text Input team
Projects
None yet
Development

No branches or pull requests

3 participants