Fixed delayed text entry for OTP codes on iOS (thanks @pipiwoaini!)

Fixes https://github.com/libsdl-org/SDL/issues/13717
This commit is contained in:
Sam Lantinga
2025-09-14 08:06:24 -07:00
parent 4561be89a5
commit 113c7e8a58

View File

@@ -79,6 +79,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
BOOL rotatingOrientation;
NSString *committedText;
NSString *obligateForBackspace;
BOOL isOTPMode;
#endif
}
@@ -280,6 +281,7 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
textField.hidden = YES;
textFieldFocused = NO;
isOTPMode = NO;
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
#ifndef SDL_PLATFORM_TVOS
@@ -477,6 +479,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
if (SDL_TextInputActive(window)) {
[textField becomeFirstResponder];
}
isOTPMode =
(SDL_GetTextInputType(props) == SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN) ||
(SDL_GetTextInputType(props) == SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE);
}
/* requests the SDL text field to become focused and accept text input.
@@ -490,6 +496,12 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
return true;
}
if (isOTPMode) {
if (textField.text.length == 64 && [textField.text isEqualToString:[@"" stringByPaddingToLength:64 withString:@" " startingAtIndex:0]]) {
textField.text = @"";
committedText = @"";
}
}
return [textField becomeFirstResponder];
}
@@ -554,14 +566,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
- (void)textFieldTextDidChange:(NSNotification *)notification
{
// When opening a password manager overlay to select a password and have it auto-filled,
// text input becomes stopped as a result of the keyboard being hidden or the text field losing focus.
// As a workaround, ensure text input is activated on any changes to the text field.
bool startTextInputMomentarily = !SDL_TextInputActive(window);
if (startTextInputMomentarily)
SDL_StartTextInput(window);
if (textField.markedTextRange == nil) {
NSUInteger compareLength = SDL_min(textField.text.length, committedText.length);
NSUInteger matchLength;
@@ -596,9 +600,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
}
committedText = textField.text;
}
if (startTextInputMomentarily)
SDL_StopTextInput(window);
}
- (void)updateKeyboard
@@ -643,8 +644,8 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
// UITextFieldDelegate method. Invoked when user types something.
- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField.markedTextRange == nil) {
if ([string length] == 0 && textField.text.length < 16) {
if (!isOTPMode) {
if (textField.markedTextRange == nil && textField.text.length < 16) {
[self resetTextState];
}
}
@@ -664,8 +665,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
- (void)resetTextState
{
textField.text = obligateForBackspace;
committedText = textField.text;
if (!isOTPMode) {
textField.text = obligateForBackspace;
committedText = textField.text;
}
}
#endif