From aef5dc096744cb5bef3993f8fe0f412710d01c2a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 27 Apr 2026 09:57:31 -0700 Subject: [PATCH] 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 dcf05165d389af01d5680b66e2656c2cdc5a24ca) --- src/video/uikit/SDL_uikitviewcontroller.h | 2 + src/video/uikit/SDL_uikitviewcontroller.m | 46 ++++++----------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index f42f586d89..a758de7ff5 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -75,7 +75,9 @@ - (void)deinitKeyboard; - (void)keyboardWillShow:(NSNotification *)notification; +- (void)keyboardDidShow:(NSNotification *)notification; - (void)keyboardWillHide:(NSNotification *)notification; +- (void)keyboardDidHide:(NSNotification *)notification; - (void)updateKeyboard; diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index ffb822d919..bbb49f835a 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -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