Use SDL_SendScreenKeyboardShown() and SDL_SendScreenKeyboardHidden() on iOS

We now have events for on-screen keyboard visibility, so we should use these instead of starting and stopping text input.

Fixes https://github.com/libsdl-org/SDL/issues/15437
Confirmed not to regress the fix in https://github.com/libsdl-org/SDL/pull/11845

(cherry picked from commit dcf05165d3)
This commit is contained in:
Sam Lantinga
2026-04-27 09:57:31 -07:00
parent d83ac9ebfc
commit aef5dc0967
2 changed files with 14 additions and 34 deletions

View File

@@ -75,7 +75,9 @@
- (void)deinitKeyboard;
- (void)keyboardWillShow:(NSNotification *)notification;
- (void)keyboardDidShow:(NSNotification *)notification;
- (void)keyboardWillHide:(NSNotification *)notification;
- (void)keyboardDidHide:(NSNotification *)notification;
- (void)updateKeyboard;

View File

@@ -75,7 +75,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
#ifdef SDL_IPHONE_KEYBOARD
SDLUITextField *textField;
BOOL hidingKeyboard;
BOOL rotatingOrientation;
NSString *committedText;
NSString *obligateForBackspace;
@@ -92,7 +91,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
#ifdef SDL_IPHONE_KEYBOARD
[self initKeyboard];
hidingKeyboard = NO;
rotatingOrientation = NO;
#endif
@@ -289,6 +287,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[center addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[center addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
@@ -373,6 +375,9 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
[center removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[center removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
[center removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
@@ -543,49 +548,25 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
[self setKeyboardHeight:(int)kbrect.size.height];
#endif
}
/* A keyboard hide transition has been interrupted with a show (keyboardWillHide has been called but keyboardDidHide didn't).
* since text input was stopped by the hide, we have to start it again. */
if (hidingKeyboard) {
SDL_StartTextInput(window);
hidingKeyboard = NO;
}
- (void)keyboardDidShow:(NSNotification *)notification
{
SDL_SendScreenKeyboardShown();
}
- (void)keyboardWillHide:(NSNotification *)notification
{
hidingKeyboard = YES;
[self setKeyboardHeight:0];
/* When the user dismisses the software keyboard by the "hide" button in the bottom right corner,
* we want to reflect that on SDL_TextInputActive by calling SDL_StopTextInput...on certain conditions */
if (SDL_TextInputActive(window)
/* keyboardWillHide gets called when a hardware keyboard is attached,
* keep text input state active if hiding while there is a hardware keyboard.
* if the hardware keyboard gets detached, the software keyboard will appear anyway. */
&& !SDL_HasKeyboard()
/* When the device changes orientation, a sequence of hide and show transitions are triggered.
* keep text input state active in this case. */
&& !rotatingOrientation) {
SDL_StopTextInput(window);
}
}
- (void)keyboardDidHide:(NSNotification *)notification
{
hidingKeyboard = NO;
SDL_SendScreenKeyboardHidden();
}
- (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) {
if (isOTPMode && labs((NSInteger)textField.text.length - (NSInteger)committedText.length) != 1) {
return;
@@ -624,9 +605,6 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char
}
committedText = textField.text;
}
if (startTextInputMomentarily)
SDL_StopTextInput(window);
}
- (void)updateKeyboard