Fix soft-keyboard level advance behavior

- Keep terminal focus without explicitly reopening the software keyboard after command field recreation.
- Preserve submitted-command IME echo suppression when advancing to the next level.
- Recreate the terminal input field when loading a level so stale editor state is discarded.
This commit is contained in:
Joe Tretter
2026-05-13 15:05:02 -05:00
parent e8bcf660d9
commit 61951408de
3 changed files with 13 additions and 13 deletions

View File

@@ -19,8 +19,8 @@ android {
applicationId = "solutions.tretter.githugandroid"
minSdk = 26
targetSdk = 35
versionCode = 138
versionName = "0.1.137"
versionCode = 139
versionName = "0.1.138"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true

View File

@@ -211,13 +211,19 @@ fun GitHugApp() {
applyRecommendedPaneWeights(persist = false)
}
fun loadLevel(index: Int, message: List<String> = listOf("Loaded level: ${levels[index].title}")) {
fun loadLevel(
index: Int,
message: List<String> = listOf("Loaded level: ${levels[index].title}"),
keepSuppressedImeEcho: Boolean = false,
) {
AppLog.d("GitHugApp", "Loading level index=$index id=${levels[index].id} title=${levels[index].title}")
currentLevelIndex = index
repo = runtime.prepareLevel(levels[index])
output = message
clearCommandInput()
suppressedImeEcho = null
clearCommandInput(recreateField = true)
if (!keepSuppressedImeEcho) {
suppressedImeEcho = null
}
hintIndex = 0
activeExerciseDetail = null
visibleHint = null
@@ -327,7 +333,7 @@ fun GitHugApp() {
"Level solved ${levelForResult.id}; advancing to next incomplete index=$nextLevelIndex id=$nextLevelId",
)
scope.launch { persistProgress(updatedCompletedLevels, nextLevelId) }
loadLevel(nextLevelIndex, message = emptyList())
loadLevel(nextLevelIndex, message = emptyList(), keepSuppressedImeEcho = true)
} else {
AppLog.d("GitHugApp", "All levels completed")
scope.launch { persistProgress(updatedCompletedLevels, levels.lastOrNull()?.id) }

View File

@@ -40,13 +40,12 @@ import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.layout.boundsInRoot
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onPreviewKeyEvent
import androidx.compose.ui.input.key.type
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
@@ -77,7 +76,6 @@ fun TerminalPane(
) {
val configuration = LocalConfiguration.current
val focusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
val outputHorizontalScroll = rememberScrollState()
val outputVerticalScroll = rememberScrollState()
val terminalMinWidth = 80.dp * 7.2f
@@ -90,7 +88,6 @@ fun TerminalPane(
LaunchedEffect(inputFieldVersion) {
outputHorizontalScroll.scrollTo(0)
focusRequester.requestFocus()
keyboardController?.show()
}
LaunchedEffect(output.size) {
@@ -184,7 +181,6 @@ fun TerminalPane(
commandInput = commandInput,
onValueChange = onValueChange,
focusRequester = focusRequester,
keyboardController = keyboardController,
onFocused = onInputHintDismiss,
onSubmit = { submitCommand() },
onTab = onTab,
@@ -205,7 +201,6 @@ private fun RowScope.TerminalInputField(
commandInput: TextFieldValue,
onValueChange: (TextFieldValue) -> Unit,
focusRequester: FocusRequester,
keyboardController: androidx.compose.ui.platform.SoftwareKeyboardController?,
onFocused: () -> Unit,
onSubmit: () -> Unit,
onTab: () -> Unit,
@@ -224,7 +219,6 @@ private fun RowScope.TerminalInputField(
.onFocusChanged { state ->
if (state.isFocused) {
onFocused()
keyboardController?.show()
}
}
.onPreviewKeyEvent { event ->