From dcf05165d389af01d5680b66e2656c2cdc5a24ca Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
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
---
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 f42f586d8900c..a758de7ff53c9 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 ffb822d919a29..bbb49f835a441 100644
--- a/src/video/uikit/SDL_uikitviewcontroller.m
+++ b/src/video/uikit/SDL_uikitviewcontroller.m
@@ -75,7 +75,6 @@ @implementation SDL_uikitviewcontroller
#ifdef SDL_IPHONE_KEYBOARD
SDLUITextField *textField;
- BOOL hidingKeyboard;
BOOL rotatingOrientation;
NSString *committedText;
NSString *obligateForBackspace;
@@ -92,7 +91,6 @@ - (instancetype)initWithSDLWindow:(SDL_Window *)_window
#ifdef SDL_IPHONE_KEYBOARD
[self initKeyboard];
- hidingKeyboard = NO;
rotatingOrientation = NO;
#endif
@@ -289,6 +287,10 @@ - (void)initKeyboard
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 @@ - (void)deinitKeyboard
[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 @@ - (void)keyboardWillShow:(NSNotification *)notification
[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 @@ - (void)textFieldTextDidChange:(NSNotification *)notification
}
committedText = textField.text;
}
-
- if (startTextInputMomentarily)
- SDL_StopTextInput(window);
}
- (void)updateKeyboard