Maelstrom: Added support for the Steam on-screen keyboard

From 904d80b2f09918be966cf8332eeffa94d75ed1ea Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 21 Mar 2026 13:34:59 -0700
Subject: [PATCH] Added support for the Steam on-screen keyboard

---
 game/gameover.cpp              |  2 +-
 screenlib/SDL_FrameBuf.cpp     | 47 ++++++++++++++++++++++++++++++++--
 screenlib/SDL_FrameBuf.h       |  2 +-
 screenlib/UIElementEditbox.cpp |  2 +-
 4 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/game/gameover.cpp b/game/gameover.cpp
index 6229a57c..85456443 100644
--- a/game/gameover.cpp
+++ b/game/gameover.cpp
@@ -246,7 +246,7 @@ void GameOverPanelDelegate::BeginEnterName()
 	}
 	m_handleSize = (int)SDL_strlen(m_handle);
 
-	screen->EnableTextInput();
+	screen->EnableTextInput(m_handleLabel->X(), m_handleLabel->Y(), m_handleLabel->Width(), m_handleLabel->Height());
 }
 
 void GameOverPanelDelegate::FinishEnterName()
diff --git a/screenlib/SDL_FrameBuf.cpp b/screenlib/SDL_FrameBuf.cpp
index 0fcfe5af..c37423ce 100644
--- a/screenlib/SDL_FrameBuf.cpp
+++ b/screenlib/SDL_FrameBuf.cpp
@@ -21,6 +21,10 @@
 
 #include <stdio.h>
 
+#ifdef ENABLE_STEAM
+#include <steam/steam_api.h>
+#endif
+
 #include "../utils/files.h"
 #include "SDL_FrameBuf.h"
 
@@ -316,15 +320,54 @@ FrameBuf::GetCursorPosition(int *x, int *y)
 }
 
 void
-FrameBuf::EnableTextInput()
+FrameBuf::EnableTextInput(int textfieldX, int textfieldY, int textfieldWidth, int textfieldHeight, bool numeric)
 {
-	SDL_StartTextInput(m_window);
+	SDL_Rect textrect;
+	float x = (float)textfieldX;
+	float y = (float)textfieldY;
+
+	SDL_RenderCoordinatesToWindow(m_renderer, x, y, &x, &y);
+	textrect.x = (int)x;
+	textrect.y = (int)y;
+	textrect.w = textfieldWidth;
+	textrect.h = textfieldHeight;
+
+	int window_width, window_height;
+	if (SDL_GetWindowSize(m_window, &window_width, &window_height)) {
+		float scale = (float)window_width / m_width;
+		textrect.w = (int)(textrect.w * scale);
+		textrect.h = (int)(textrect.h * scale);
+	}
+
+#ifdef ENABLE_STEAM
+	ISteamUtils *pSteamUtils = SteamUtils();
+	if (pSteamUtils) {
+		pSteamUtils->ShowFloatingGamepadTextInput(k_EFloatingGamepadTextInputModeModeSingleLine, textrect.x, textrect.y, textrect.w, textrect.h);
+	}
+#endif
+
+	SDL_SetTextInputArea(m_window, &textrect, 0);
+
+	SDL_PropertiesID props = SDL_CreateProperties();
+	if (numeric) {
+		SDL_SetNumberProperty(props, SDL_PROP_TEXTINPUT_TYPE_NUMBER, SDL_TEXTINPUT_TYPE_NUMBER);
+	}
+	SDL_SetBooleanProperty(props, SDL_PROP_TEXTINPUT_MULTILINE_BOOLEAN, false);
+	SDL_StartTextInputWithProperties(m_window, props);
+	SDL_DestroyProperties(props);
 }
 
 void
 FrameBuf::DisableTextInput()
 {
 	SDL_StopTextInput(m_window);
+
+#ifdef ENABLE_STEAM
+	ISteamUtils *pSteamUtils = SteamUtils();
+	if (pSteamUtils) {
+		pSteamUtils->DismissFloatingGamepadTextInput();
+	}
+#endif
 }
 
 void
diff --git a/screenlib/SDL_FrameBuf.h b/screenlib/SDL_FrameBuf.h
index c181bfc2..f138997b 100644
--- a/screenlib/SDL_FrameBuf.h
+++ b/screenlib/SDL_FrameBuf.h
@@ -72,7 +72,7 @@ class FrameBuf : public ErrorBase {
 
 	bool ConvertTouchCoordinates(const SDL_TouchFingerEvent &finger, int *x, int *y);
 
-	void EnableTextInput();
+	void EnableTextInput(int textfieldX, int textfieldY, int textfieldWidth, int textfieldHeight, bool numeric = false);
 	void DisableTextInput();
 	void SetGamepadMouse(bool enabled);
 	bool GamepadMouseEnabled() { return (m_gamepadMouse > 0); }
diff --git a/screenlib/UIElementEditbox.cpp b/screenlib/UIElementEditbox.cpp
index 1046afdf..2ab05f3f 100644
--- a/screenlib/UIElementEditbox.cpp
+++ b/screenlib/UIElementEditbox.cpp
@@ -152,7 +152,7 @@ UIElementEditbox::SetFocus(bool focus)
 	}
 
 	if (m_focus) {
-		m_screen->EnableTextInput();
+		m_screen->EnableTextInput(X(), Y(), Width(), Height(), m_numeric);
 	} else {
 		m_screen->DisableTextInput();
 	}