diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java index 4edeecc33c..19c5218b48 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java @@ -1426,10 +1426,24 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh * the bottom edge of the input region and the top edge of an input * method (soft keyboard) */ - static final int HEIGHT_PADDING = 15; + static int getPanPadding() { + /* The hint is in window coordinates. Convert to pixels by + * multiplying by density. */ + int defaultPadding = 10; + try { + String hint = nativeGetHint("SDL_IME_PAN_PADDING"); + if (hint != null) { + defaultPadding = Integer.parseInt(hint); + } + } catch (NumberFormatException ignored) { + } + float density = getContext().getResources().getDisplayMetrics().density; + return (int)(defaultPadding * density); + } public int input_type; public int x, y, w, h; + private final int panPadding; public ShowTextInputTask(int input_type, int x, int y, int w, int h) { this.input_type = input_type; @@ -1437,19 +1451,20 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh this.y = y; this.w = w; this.h = h; + this.panPadding = getPanPadding(); /* Minimum size of 1 pixel, so it takes focus. */ if (this.w <= 0) { this.w = 1; } - if (this.h + HEIGHT_PADDING <= 0) { - this.h = 1 - HEIGHT_PADDING; + if (this.h + panPadding <= 0) { + this.h = 1 - panPadding; } } @Override public void run() { - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + HEIGHT_PADDING); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + panPadding); params.leftMargin = x; params.topMargin = y; diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h index d23577fa8c..200482ad93 100644 --- a/include/SDL3/SDL_hints.h +++ b/include/SDL3/SDL_hints.h @@ -1280,6 +1280,25 @@ extern "C" { */ #define SDL_HINT_IME_IMPLEMENTED_UI "SDL_IME_IMPLEMENTED_UI" +/** + * A variable controlling the padding in pixels added above the on-screen + * keyboard to keep the text input area visible. + * + * This padding is used on platforms with on-screen keyboards (iOS, Android) + * to ensure there is extra breathing room between the text input area and + * the top of the keyboard when panning the view. + * + * The variable can be set to a number representing the padding in window + * coordinates. + * + * The default value is "10". + * + * This hint can be set anytime. + * + * \since This hint is available since SDL 3.6.0. + */ +#define SDL_HINT_IME_PAN_PADDING "SDL_IME_PAN_PADDING" + /** * A variable controlling whether the home indicator bar on iPhone X and later * should be hidden. diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index 7da8731699..93619755b9 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -646,7 +646,10 @@ static void SDLCALL SDL_HideHomeIndicatorHintChanged(void *userdata, const char #endif if (self.keyboardHeight && self.textInputRect.h) { - int rectbottom = (int)(self.textInputRect.y + self.textInputRect.h); + /// Get the pan padding from the hint (in window coordinates). + const char *hint = SDL_GetHint(SDL_HINT_IME_PAN_PADDING); + int padding = (hint && *hint) ? SDL_atoi(hint) : 10; + int rectbottom = (int)(self.textInputRect.y + self.textInputRect.h + padding); int keybottom = (int)(self.view.bounds.size.height - self.keyboardHeight); if (keybottom < rectbottom) { offset.y = keybottom - rectbottom;