v1.2.1: add hidden input bridge for soft keyboard

- Added transparent BasicTextField (0x0) to trigger soft keyboard
- Tapping terminal area now shows input method
- Removed keyCode-based character capture (didn't work with IME)
- Enter detection via OnValueChange (\n in text)
- Hardware keyboard still handled via onKeyEvent
This commit is contained in:
茂之钳
2026-05-24 09:45:56 +00:00
parent 008f44fac5
commit 58320fcaf5
@@ -10,6 +10,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Close
@@ -462,32 +463,6 @@ fun SshTerminalScreen(
}
}
fun handleCharacterInput(event: KeyEvent): Boolean {
if (!state.connected) return false
if (event.type != KeyEventType.KeyUp) return false
return when (event.key) {
Key.Enter, Key.Backspace, Key.Tab,
Key.Escape, Key.F1, Key.F2, Key.F3, Key.F4, Key.F5, Key.F6,
Key.F7, Key.F8, Key.F9, Key.F10, Key.F11, Key.F12,
Key.DirectionUp, Key.DirectionDown, Key.DirectionLeft, Key.DirectionRight,
Key.PageUp, Key.PageDown, Key.MoveHome, Key.MoveEnd,
Key.Insert, Key.Delete, Key.CapsLock,
Key.ShiftLeft, Key.ShiftRight, Key.CtrlLeft, Key.CtrlRight,
Key.AltLeft, Key.AltRight, Key.MetaLeft, Key.MetaRight -> false
else -> {
val c = event.key.nativeKeyCode.toChar()
if (c.isISOControl()) return false
if (event.isCtrlPressed) return false
if (event.isAltPressed) return false
if (event.isMetaPressed) return false
currentInput += c
true
}
}
}
val focusModifier = remember { FocusRequester() }
// 连接后自动获取焦点
@@ -497,15 +472,41 @@ fun SshTerminalScreen(
}
}
// 透明输入桥 — 用于弹出软键盘
Box(
modifier = modifier
.fillMaxSize()
.background(bg)
.onKeyEvent { handleKeyEvent(it) }
.onPreviewKeyEvent { handleCharacterInput(it) }
.focusRequester(focusModifier)
.onFocusChanged { }
.clickable { focusModifier.requestFocus() }
) {
// 透明输入框 — 0 高度 + Invisible,仅用来弹出软键盘
BasicTextField(
value = TextFieldValue(currentInput),
onValueChange = { newVal ->
val old = currentInput
currentInput = newVal.text
// 检测回车:如果内容有换行符说明用户按了发送
if (newVal.text.contains('\n')) {
val cmd = newVal.text.replace("\n", "").trim()
if (cmd.isNotEmpty()) {
coroutineScope.launch {
manager.sendCommand(cmd)
}
}
currentInput = ""
}
},
modifier = Modifier
.size(0.dp, 0.dp) // 零尺寸,不占据空间
.focusRequester(focusModifier),
singleLine = true,
textStyle = TextStyle(color = Color.Transparent, fontSize = 1.sp)
)
Column(
modifier = Modifier
.fillMaxSize()