v1.2.2: fix hidden TextField value sync & keyboard trigger
- Use mutableStateOf(TextFieldValue) as single source of truth - Removed key(currentInput) that caused focus loss on each keystroke - Changed hidden field from 0x0 to 1x30dp for better IME compatibility - Fixed display: showing inputText.text instead of stale currentInput - Soft keyboard now shows input text in terminal's last line
This commit is contained in:
@@ -417,7 +417,8 @@ fun SshTerminalScreen(
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val state by manager.connectionState.collectAsState()
|
||||
var currentInput by remember { mutableStateOf("") }
|
||||
val inputState = remember { mutableStateOf(TextFieldValue("")) }
|
||||
var currentInput by inputState
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val listState = rememberLazyListState()
|
||||
var showFontPicker by remember { mutableStateOf(false) }
|
||||
@@ -435,24 +436,29 @@ fun SshTerminalScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// 键盘事件处理
|
||||
// 获取当前输入的纯文本(用于显示)
|
||||
val currentInputText = currentInput.text
|
||||
|
||||
// 硬件键盘处理
|
||||
fun handleKeyEvent(event: KeyEvent): Boolean {
|
||||
if (!state.connected) return false
|
||||
return when (event.type) {
|
||||
KeyEventType.KeyUp -> {
|
||||
when (event.key) {
|
||||
Key.Enter -> {
|
||||
if (currentInput.isNotEmpty()) {
|
||||
val cmd = currentInputText.trim()
|
||||
if (cmd.isNotEmpty()) {
|
||||
coroutineScope.launch {
|
||||
manager.sendCommand(currentInput)
|
||||
currentInput = ""
|
||||
manager.sendCommand(cmd)
|
||||
}
|
||||
}
|
||||
currentInput = TextFieldValue("")
|
||||
true
|
||||
}
|
||||
Key.Backspace -> {
|
||||
if (currentInput.isNotEmpty()) {
|
||||
currentInput = currentInput.substring(0, currentInput.length - 1)
|
||||
val t = currentInputText
|
||||
if (t.isNotEmpty()) {
|
||||
currentInput = TextFieldValue(t.substring(0, t.length - 1))
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -472,36 +478,34 @@ fun SshTerminalScreen(
|
||||
}
|
||||
}
|
||||
|
||||
// 透明输入桥 — 用于弹出软键盘
|
||||
|
||||
Box(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.background(bg)
|
||||
.onKeyEvent { handleKeyEvent(it) }
|
||||
.focusRequester(focusModifier)
|
||||
|
||||
.clickable { focusModifier.requestFocus() }
|
||||
) {
|
||||
// 透明输入框 — 0 高度 + Invisible,仅用来弹出软键盘
|
||||
// 透明输入框 — 极小的 1x30 dp,仅用来弹出软键盘
|
||||
BasicTextField(
|
||||
value = TextFieldValue(currentInput),
|
||||
value = currentInput,
|
||||
onValueChange = { newVal ->
|
||||
val old = currentInput
|
||||
currentInput = newVal.text
|
||||
// 检测回车:如果内容有换行符说明用户按了发送
|
||||
if (newVal.text.contains('\n')) {
|
||||
val cmd = newVal.text.replace("\n", "").trim()
|
||||
val t = newVal.text
|
||||
if (t.endsWith('\n')) {
|
||||
val cmd = t.dropLast(1).trim()
|
||||
if (cmd.isNotEmpty()) {
|
||||
coroutineScope.launch {
|
||||
manager.sendCommand(cmd)
|
||||
}
|
||||
}
|
||||
currentInput = ""
|
||||
currentInput = TextFieldValue("")
|
||||
} else {
|
||||
currentInput = newVal
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.size(0.dp, 0.dp) // 零尺寸,不占据空间
|
||||
.width(1.dp)
|
||||
.height(30.dp)
|
||||
.focusRequester(focusModifier),
|
||||
singleLine = true,
|
||||
textStyle = TextStyle(color = Color.Transparent, fontSize = 1.sp)
|
||||
@@ -624,7 +628,7 @@ fun SshTerminalScreen(
|
||||
}
|
||||
item(key = "prompt") {
|
||||
Text(
|
||||
text = "\$ $currentInput",
|
||||
text = "\$ $currentInputText",
|
||||
color = textPrimary,
|
||||
fontSize = terminalFontSizeSp,
|
||||
fontFamily = FontFamily.Monospace,
|
||||
|
||||
Reference in New Issue
Block a user