Merge 7b04665f33 into 6ad56075d6
This commit is contained in:
commit
e1fdcf4a17
2 changed files with 35 additions and 2 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue