This commit is contained in:
Yousif Almulla 2026-05-24 19:09:46 +08:00 committed by GitHub
commit e1fdcf4a17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 2 deletions

View file

@ -177,6 +177,7 @@ class _RemotePageState extends State<RemotePage> with WidgetsBindingObserver {
);
void onSoftKeyboardChanged(bool visible) {
inputModel.androidSoftKeyboardActive = visible;
if (!visible) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
// [pi.version.isNotEmpty] -> check ready or not, avoid login without soft-keyboard
@ -276,8 +277,11 @@ class _RemotePageState extends State<RemotePage> with WidgetsBindingObserver {
if (newValue.length == oldValue.length) {
// ?
} else if (newValue.length < oldValue.length) {
final char = 'VK_BACK';
inputModel.inputKey(char);
// Send exactly one VK_BACK per onChanged callback regardless of how many
// characters the IME removed (Samsung accelerates held-delete). The
// IME's own callback frequency provides a steady, controllable repeat
// rate instead of runaway exponential deletion.
inputModel.inputKey('VK_BACK');
} else {
final content = newValue.substring(oldValue.length);
if (content.length > 1) {

View file

@ -445,6 +445,12 @@ class InputModel {
bool _pointerMovedAfterEnter = false;
bool _pointerInsideImage = false;
/// True while the Android soft keyboard editor is active.
/// When set, key events are ignored so they flow through to the
/// hidden TextFormField's onChanged handler instead of being
/// processed here with potentially incorrect physicalKey data.
bool androidSoftKeyboardActive = false;
// mouse
final isPhysicalMouse = false.obs;
int _lastButtons = 0;
@ -819,6 +825,29 @@ class InputModel {
KeyEventResult handleKeyEvent(KeyEvent e) {
if (isViewOnly) return KeyEventResult.handled;
if (isViewCamera) return KeyEventResult.handled;
// When the Android soft keyboard is active, avoid processing key events
// through the normal input pipeline because physicalKey data from the
// soft keyboard is unreliable (Flutter issue #157771) and can corrupt
// subsequent input, causing every keypress to repeat a single character.
//
// Return `handled` (not `ignored`) so Android keeps sending key-repeat
// events for held keys and the TextFormField does not consume sentinel
// buffer characters.
//
// For Backspace and Enter, send them directly using the reliable logical
// key data. This is required because for some IMEs (ko/zh/ja) returning
// `handled` prevents the IME from processing the key through onChanged.
if (isAndroid && androidSoftKeyboardActive) {
if (e is KeyDownEvent || e is KeyRepeatEvent) {
if (e.logicalKey == LogicalKeyboardKey.backspace) {
inputKey('VK_BACK', press: true);
} else if (e.logicalKey == LogicalKeyboardKey.enter ||
e.logicalKey == LogicalKeyboardKey.numpadEnter) {
inputKey('VK_RETURN', press: true);
}
}
return KeyEventResult.handled;
}
if (!isInputSourceFlutter) {
if (isDesktop) {
return KeyEventResult.handled;