fix(edit): put the keyboard away when the calendar picker takes over
All checks were successful
Translations / check (pull_request) Successful in 5s
CI / ci (pull_request) Successful in 6m54s

Opening the picker from a focused field left the IME up — the picker's own
window doesn't pan (ADJUST_NOTHING), so the keyboard simply stayed, and
following the "Missing a calendar?" row carried it onto the calendar manager,
where nothing could type into it.

Focus is cleared and the IME hidden as the picker opens. The controller is
read in the form's window, where the focused field actually lives — reading
it inside the picker would address the dialog's window instead. The field
keeps its text; only focus and the keyboard go.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-26 18:15:43 +02:00
parent b3b2ec9d05
commit e710f930ca

View File

@@ -89,6 +89,8 @@ import androidx.compose.ui.graphics.isSpecified
import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
@@ -512,6 +514,10 @@ private fun EventEditContent(
// they're locked here; everything else (reminders, location, notes) is the // they're locked here; everything else (reminders, location, notes) is the
// user's to edit. // user's to edit.
val locked = state.isManaged val locked = state.isManaged
// Read in the form's own window, not the picker's: the field holding focus
// lives here, so this is the controller that can put its keyboard away.
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current
var picker by remember { mutableStateOf<PickerTarget?>(null) } var picker by remember { mutableStateOf<PickerTarget?>(null) }
var showCalendarPicker by rememberSaveable { mutableStateOf(false) } var showCalendarPicker by rememberSaveable { mutableStateOf(false) }
var showReminderPicker by rememberSaveable { mutableStateOf(false) } var showReminderPicker by rememberSaveable { mutableStateOf(false) }
@@ -1117,6 +1123,17 @@ private fun EventEditContent(
null -> Unit null -> Unit
} }
// A full-screen picker over the form is a change of place, so the form's
// keyboard has no business following it there — least of all onto the
// calendar manager, which the picker can hand off to. The form's own field
// keeps its text; only focus and the IME go.
LaunchedEffect(showCalendarPicker) {
if (showCalendarPicker) {
focusManager.clearFocus(force = true)
keyboardController?.hide()
}
}
if (showCalendarPicker) { if (showCalendarPicker) {
CalendarPicker( CalendarPicker(
calendars = state.calendars, calendars = state.calendars,