From 7978e0301d613e273eecffde4184d4c14e2c196d Mon Sep 17 00:00:00 2001 From: fufesou <13586388+fufesou@users.noreply.github.com> Date: Fri, 8 Nov 2024 12:11:56 +0800 Subject: [PATCH] fix: input mobile -> Android (#9767) Signed-off-by: fufesou --- .../com/carriez/flutter_hbb/InputService.kt | 24 ++++++++++++------- .../flutter_hbb/KeyboardKeyEventMapper.kt | 4 +--- flutter/lib/mobile/pages/remote_page.dart | 8 +++++++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt index 3fcc72df3..f53f95d67 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/InputService.kt @@ -280,20 +280,20 @@ class InputService : AccessibilityService() { var textToCommit: String? = null - if (keyboardMode == KeyboardMode.Legacy) { - if (keyEvent.hasChr() && keyEvent.getDown()) { + // [down] indicates the key's state(down or up). + // [press] indicates a click event(down and up). + // https://github.com/rustdesk/rustdesk/blob/3a7594755341f023f56fa4b6a43b60d6b47df88d/flutter/lib/models/input_model.dart#L688 + if (keyEvent.hasSeq()) { + textToCommit = keyEvent.getSeq() + } else if (keyboardMode == KeyboardMode.Legacy) { + if (keyEvent.hasChr() && (keyEvent.getDown() || keyEvent.getPress())) { val chr = keyEvent.getChr() if (chr != null) { textToCommit = String(Character.toChars(chr)) } } } else if (keyboardMode == KeyboardMode.Translate) { - if (keyEvent.hasSeq() && keyEvent.getDown()) { - val seq = keyEvent.getSeq() - if (seq != null) { - textToCommit = seq - } - } + } else { } Log.d(logTag, "onKeyEvent $keyEvent textToCommit:$textToCommit") @@ -320,6 +320,10 @@ class InputService : AccessibilityService() { } else { ke?.let { event -> inputConnection.sendKeyEvent(event) + if (keyEvent.getPress()) { + val actionUpEvent = KeyEventAndroid(KeyEventAndroid.ACTION_UP, event.keyCode) + inputConnection.sendKeyEvent(actionUpEvent) + } } } } @@ -333,6 +337,10 @@ class InputService : AccessibilityService() { for (item in possibleNodes) { val success = trySendKeyEvent(event, item, textToCommit) if (success) { + if (keyEvent.getPress()) { + val actionUpEvent = KeyEventAndroid(KeyEventAndroid.ACTION_UP, event.keyCode) + trySendKeyEvent(actionUpEvent, item, textToCommit) + } break } } diff --git a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/KeyboardKeyEventMapper.kt b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/KeyboardKeyEventMapper.kt index 1e63df405..ccb33195e 100644 --- a/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/KeyboardKeyEventMapper.kt +++ b/flutter/android/app/src/main/kotlin/com/carriez/flutter_hbb/KeyboardKeyEventMapper.kt @@ -31,14 +31,12 @@ object KeyEventConverter { } var action = 0 - if (keyEventProto.getDown()) { + if (keyEventProto.getDown() || keyEventProto.getPress()) { action = KeyEvent.ACTION_DOWN } else { action = KeyEvent.ACTION_UP } - // FIXME: The last parameter is the repeat count, not modifiers ? - // https://developer.android.com/reference/android/view/KeyEvent#KeyEvent(long,%20long,%20int,%20int,%20int) return KeyEvent(0, 0, action, chrValue, 0, modifiers) } diff --git a/flutter/lib/mobile/pages/remote_page.dart b/flutter/lib/mobile/pages/remote_page.dart index fd0e007e2..e63a5c5b9 100644 --- a/flutter/lib/mobile/pages/remote_page.dart +++ b/flutter/lib/mobile/pages/remote_page.dart @@ -560,6 +560,14 @@ class _RemotePageState extends State with WidgetsBindingObserver { controller: _textController, // trick way to make backspace work always keyboardType: TextInputType.multiline, + // `onChanged` may be called depending on the input method if this widget is wrapped in + // `Focus(onKeyEvent: ..., child: ...)` + // For `Backspace` button in the soft keyboard: + // en/fr input method: + // 1. The button will not trigger `onKeyEvent` if the text field is not empty. + // 2. The button will trigger `onKeyEvent` if the text field is empty. + // ko/zh/ja input method: the button will trigger `onKeyEvent` + // and the event will not popup if `KeyEventResult.handled` is returned. onChanged: handleSoftKeyboardInput, ), ),