@@ -67,8 +67,11 @@ import com.x8bit.bitwarden.ui.platform.manager.biometrics.BiometricsManager
67
67
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
68
68
import kotlinx.collections.immutable.persistentListOf
69
69
import kotlinx.collections.immutable.toImmutableList
70
+ import kotlinx.coroutines.delay
70
71
import javax.crypto.Cipher
71
72
73
+ private const val AUTO_FOCUS_DELAY = 415L
74
+
72
75
/* *
73
76
* The top level composable for the Vault Unlock screen.
74
77
*/
@@ -251,6 +254,18 @@ fun VaultUnlockScreen(
251
254
) {
252
255
Spacer (modifier = Modifier .height(12 .dp))
253
256
if (! state.hideInput) {
257
+ // When switching from an unlocked account to a locked account, the
258
+ // current activity is recreated and therefore the composition takes place
259
+ // twice. Adding this delay prevents the MP or Pin field
260
+ // from auto focusing on the first composition which creates a visual jank where
261
+ // the keyboard shows, disappears, and then shows again.
262
+ var autoFocusDelayCompleted by rememberSaveable {
263
+ mutableStateOf(false )
264
+ }
265
+ LaunchedEffect (Unit ) {
266
+ delay(AUTO_FOCUS_DELAY )
267
+ autoFocusDelayCompleted = true
268
+ }
254
269
BitwardenPasswordField (
255
270
label = state.vaultUnlockType.unlockScreenInputLabel(),
256
271
value = state.input,
@@ -261,7 +276,7 @@ fun VaultUnlockScreen(
261
276
showPasswordTestTag = state
262
277
.vaultUnlockType
263
278
.inputFieldVisibilityToggleTestTag,
264
- autoFocus = state.showKeyboard,
279
+ autoFocus = state.showKeyboard && autoFocusDelayCompleted ,
265
280
imeAction = ImeAction .Done ,
266
281
keyboardActions = KeyboardActions (
267
282
onDone = remember(viewModel) {
0 commit comments