From 07d96fde80f69132af8a87f42ba5442acd760658 Mon Sep 17 00:00:00 2001
From: xLuigiGamerx <88401287+xLuigiGamerx@users.noreply.github.com>
Date: Sun, 17 May 2026 04:28:31 +0300
Subject: [PATCH] Start, stop and checking if text input is active for mods and
disabling chat, console, and playerlist inputs when mods have text input
focus
---
autogen/lua_definitions/functions.lua | 16 +++++++
docs/lua/functions-7.md | 63 +++++++++++++++++++++++++
docs/lua/functions.md | 3 ++
src/pc/controller/controller_keyboard.c | 7 +++
src/pc/djui/djui_interactable.c | 7 +--
src/pc/djui/djui_panel_controls.c | 2 -
src/pc/gfx/gfx_dummy.c | 5 ++
src/pc/gfx/gfx_dxgi.cpp | 5 +-
src/pc/gfx/gfx_pc.c | 2 -
src/pc/gfx/gfx_sdl.c | 6 +--
src/pc/gfx/gfx_window_manager_api.h | 1 +
src/pc/lua/smlua_functions_autogen.c | 48 +++++++++++++++++++
src/pc/lua/utils/smlua_input_utils.c | 19 +++++++-
src/pc/lua/utils/smlua_input_utils.h | 8 ++++
src/pc/network/network.c | 3 ++
15 files changed, 179 insertions(+), 16 deletions(-)
diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index 38df355da..fb0f9d5c8 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -11478,6 +11478,22 @@ function set_clipboard_text(text)
-- ...
end
+--- Starts text input and grabs input focus
+function start_text_input()
+ -- ...
+end
+
+--- Stops text input and loses input focus
+function stop_text_input()
+ -- ...
+end
+
+--- @return boolean
+--- Checks if text input is active and if you have input focus
+function is_text_input_active()
+ -- ...
+end
+
--- @param areaIndex integer
--- Instantly changes the current area to `areaIndex`
function smlua_level_util_change_area(areaIndex)
diff --git a/docs/lua/functions-7.md b/docs/lua/functions-7.md
index 3f837eb9f..b6ec5c324 100644
--- a/docs/lua/functions-7.md
+++ b/docs/lua/functions-7.md
@@ -1289,6 +1289,69 @@ Sets the clipboard text
+## [start_text_input](#start_text_input)
+
+### Description
+Starts text input and grabs input focus
+
+### Lua Example
+`start_text_input()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void start_text_input(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [stop_text_input](#stop_text_input)
+
+### Description
+Stops text input and loses input focus
+
+### Lua Example
+`stop_text_input()`
+
+### Parameters
+- None
+
+### Returns
+- None
+
+### C Prototype
+`void stop_text_input(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [is_text_input_active](#is_text_input_active)
+
+### Description
+Checks if text input is active and if you have input focus
+
+### Lua Example
+`local booleanValue = is_text_input_active()`
+
+### Parameters
+- None
+
+### Returns
+- `boolean`
+
+### C Prototype
+`bool is_text_input_active(void);`
+
+[:arrow_up_small:](#)
+
+
+
---
# functions from smlua_level_utils.h
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index d3d001000..e4ac2b702 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1997,6 +1997,9 @@
- [get_current_gamepad_index](functions-7.md#get_current_gamepad_index)
- [get_clipboard_text](functions-7.md#get_clipboard_text)
- [set_clipboard_text](functions-7.md#set_clipboard_text)
+ - [start_text_input](functions-7.md#start_text_input)
+ - [stop_text_input](functions-7.md#stop_text_input)
+ - [is_text_input_active](functions-7.md#is_text_input_active)
diff --git a/src/pc/controller/controller_keyboard.c b/src/pc/controller/controller_keyboard.c
index cabbd437c..20ba39a94 100644
--- a/src/pc/controller/controller_keyboard.c
+++ b/src/pc/controller/controller_keyboard.c
@@ -14,6 +14,7 @@
#include "menu/file_select.h"
#include "pc/djui/djui.h"
#include "pc/djui/djui_panel_pause.h"
+#include "pc/lua/smlua.h"
#include "pc/lua/utils/smlua_input_utils.h"
static int keyboard_buttons_down;
@@ -72,10 +73,16 @@ void keyboard_on_all_keys_up(void) {
void keyboard_on_text_input(char* text) {
djui_interactable_on_text_input(text);
+ if (gModHasInputFocus) {
+ smlua_call_event_hooks(HOOK_ON_TEXT_INPUT, text);
+ }
}
void keyboard_on_text_editing(char* text, int cursorPos) {
djui_interactable_on_text_editing(text, cursorPos);
+ if (gModHasInputFocus) {
+ smlua_call_event_hooks(HOOK_ON_TEXT_EDITING, text, cursorPos);
+ }
}
static void keyboard_add_binds(int mask, unsigned int *scancode) {
diff --git a/src/pc/djui/djui_interactable.c b/src/pc/djui/djui_interactable.c
index d8aaac951..c4e45c099 100644
--- a/src/pc/djui/djui_interactable.c
+++ b/src/pc/djui/djui_interactable.c
@@ -10,6 +10,7 @@
#include "pc/controller/controller_keyboard.h"
#include "pc/utils/misc.h"
#include "pc/network/network.h"
+#include "pc/lua/utils/smlua_input_utils.h"
#include "sounds.h"
#include "audio/external.h"
@@ -217,7 +218,7 @@ bool djui_interactable_on_key_down(int scancode) {
return true;
}
- if (gDjuiChatBox != NULL && !gDjuiChatBoxFocus) {
+ if (gDjuiChatBox != NULL && !gDjuiChatBoxFocus && !gModHasInputFocus) {
bool pressChat = false;
for (int i = 0; i < MAX_BINDS; i++) {
if (scancode == (int)configKeyChat[i]) { pressChat = true; }
@@ -229,7 +230,7 @@ bool djui_interactable_on_key_down(int scancode) {
}
}
- if ((gDjuiPlayerList != NULL || gDjuiModList != NULL)) {
+ if ((gDjuiPlayerList != NULL || gDjuiModList != NULL) && !gModHasInputFocus) {
for (int i = 0; i < MAX_BINDS; i++) {
if (scancode == (int)configKeyPlayerList[i] && !gDjuiInMainMenu && gNetworkType != NT_NONE) {
if (gServerSettings.enablePlayerList) {
@@ -279,7 +280,7 @@ bool djui_interactable_on_key_down(int scancode) {
void djui_interactable_on_key_up(int scancode) {
- if (!gDjuiChatBoxFocus) {
+ if (!gDjuiChatBoxFocus && !gModHasInputFocus) {
for (int i = 0; i < MAX_BINDS; i++) {
if (scancode == (int)configKeyConsole[i]) { djui_console_toggle(); break; }
}
diff --git a/src/pc/djui/djui_panel_controls.c b/src/pc/djui/djui_panel_controls.c
index 3df1c19e0..d48e01658 100644
--- a/src/pc/djui/djui_panel_controls.c
+++ b/src/pc/djui/djui_panel_controls.c
@@ -42,8 +42,6 @@ void djui_panel_controls_create(struct DjuiBase* caller) {
#endif
djui_checkbox_create(body, DLANG(MISC, USE_STANDARD_KEY_BINDINGS_CHAT), &configUseStandardKeyBindingsChat, NULL);
- djui_checkbox_create(body, DLANG(CONTROLS, EXTENDED_REPORTS), &configExtendedReports, NULL);
-
int numJoys = SDL_NumJoysticks();
if (numJoys == 0) { numJoys = 1; }
diff --git a/src/pc/gfx/gfx_dummy.c b/src/pc/gfx/gfx_dummy.c
index 88654ff04..dd3348095 100644
--- a/src/pc/gfx/gfx_dummy.c
+++ b/src/pc/gfx/gfx_dummy.c
@@ -109,6 +109,10 @@ static void gfx_dummy_wm_start_text_input(void) {
static void gfx_dummy_wm_stop_text_input(void) {
}
+static bool gfx_dummy_wm_is_text_input_active(void) {
+ return false;
+}
+
static void gfx_dummy_wm_set_clipboard_text(UNUSED const char* text) {
}
@@ -213,6 +217,7 @@ struct GfxWindowManagerAPI gfx_dummy_wm_api = {
gfx_dummy_wm_shutdown,
gfx_dummy_wm_start_text_input,
gfx_dummy_wm_stop_text_input,
+ gfx_dummy_wm_is_text_input_active,
gfx_dummy_wm_get_clipboard_text,
gfx_dummy_wm_set_clipboard_text,
gfx_dummy_wm_set_cursor_visible,
diff --git a/src/pc/gfx/gfx_dxgi.cpp b/src/pc/gfx/gfx_dxgi.cpp
index f465afb0d..6a76b6876 100644
--- a/src/pc/gfx/gfx_dxgi.cpp
+++ b/src/pc/gfx/gfx_dxgi.cpp
@@ -29,7 +29,6 @@ extern "C" {
#include "pc/rom_checker.h"
#include "pc/network/version.h"
#include "pc/configfile.h"
- #include "pc/lua/smlua.h"
#include "pc/controller/controller_keyboard.h"
}
@@ -536,8 +535,6 @@ static void gfx_dxgi_on_text_input(wchar_t code_unit) {
utf8_buffer[0] = (char)code_unit;
utf8_buffer[1] = '\0';
}
-
- smlua_call_event_hooks(HOOK_ON_TEXT_INPUT, utf8_buffer);
dxgi.on_text_input(utf8_buffer);
}
}
@@ -1015,6 +1012,7 @@ void gfx_dxgi_shutdown(void) {
void gfx_dxgi_start_text_input(void) { inTextInput = TRUE; }
void gfx_dxgi_stop_text_input(void) { inTextInput = FALSE; }
+bool gfx_dxgi_is_text_input_active(void) { return inTextInput; }
static char* gfx_dxgi_get_clipboard_text(void) {
static char clipboard_buf[WAPI_CLIPBOARD_BUFSIZ];
@@ -1086,6 +1084,7 @@ struct GfxWindowManagerAPI gfx_dxgi = {
gfx_dxgi_shutdown,
gfx_dxgi_start_text_input,
gfx_dxgi_stop_text_input,
+ gfx_dxgi_is_text_input_active,
gfx_dxgi_get_clipboard_text,
gfx_dxgi_set_clipboard_text,
gfx_dxgi_set_cursor_visible,
diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c
index da79dcfe6..70e011f76 100644
--- a/src/pc/gfx/gfx_pc.c
+++ b/src/pc/gfx/gfx_pc.c
@@ -2039,8 +2039,6 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co
gfx_wapi->init(window_title);
gfx_rapi->init();
- gfx_wapi->start_text_input();
-
gfx_cc_precomp();
gGfxInited = true;
diff --git a/src/pc/gfx/gfx_sdl.c b/src/pc/gfx/gfx_sdl.c
index 231a61966..d43ea37d5 100644
--- a/src/pc/gfx/gfx_sdl.c
+++ b/src/pc/gfx/gfx_sdl.c
@@ -42,8 +42,6 @@
#include "pc/utils/misc.h"
#include "pc/mods/mod_import.h"
#include "pc/rom_checker.h"
-#include "pc/lua/smlua.h"
-#include "pc/lua/utils/smlua_input_utils.h"
#ifndef GL_MAX_SAMPLES
#define GL_MAX_SAMPLES 0x8D57
@@ -252,11 +250,9 @@ static void gfx_sdl_handle_events(void) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_TEXTINPUT:
- smlua_call_event_hooks(HOOK_ON_TEXT_INPUT, event.text.text);
kb_text_input(event.text.text);
break;
case SDL_TEXTEDITING: //IME composition
- smlua_call_event_hooks(HOOK_ON_TEXT_EDITING, event.edit.text, event.edit.start);
kb_text_editing(event.edit.text,event.edit.start);
break;
case SDL_KEYDOWN:
@@ -362,6 +358,7 @@ static bool gfx_sdl_has_focus(void) {
static void gfx_sdl_start_text_input(void) { SDL_StartTextInput(); }
static void gfx_sdl_stop_text_input(void) { SDL_StopTextInput(); }
+static bool gfx_sdl_is_text_input_active(void) { return SDL_IsTextInputActive(); }
static char* gfx_sdl_get_clipboard_text(void) {
static char clipboard_buf[WAPI_CLIPBOARD_BUFSIZ];
@@ -391,6 +388,7 @@ struct GfxWindowManagerAPI gfx_sdl = {
gfx_sdl_shutdown,
gfx_sdl_start_text_input,
gfx_sdl_stop_text_input,
+ gfx_sdl_is_text_input_active,
gfx_sdl_get_clipboard_text,
gfx_sdl_set_clipboard_text,
gfx_sdl_set_cursor_visible,
diff --git a/src/pc/gfx/gfx_window_manager_api.h b/src/pc/gfx/gfx_window_manager_api.h
index f1e7760ef..20747c7f1 100644
--- a/src/pc/gfx/gfx_window_manager_api.h
+++ b/src/pc/gfx/gfx_window_manager_api.h
@@ -26,6 +26,7 @@ struct GfxWindowManagerAPI {
void (*shutdown)(void);
void (*start_text_input)(void);
void (*stop_text_input)(void);
+ bool (*is_text_input_active)(void);
char* (*get_clipboard_text)(void);
void (*set_clipboard_text)(const char*);
void (*set_cursor_visible)(bool);
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 012cf4700..04cff602d 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -33109,6 +33109,51 @@ int smlua_func_set_clipboard_text(lua_State* L) {
return 1;
}
+int smlua_func_start_text_input(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "start_text_input", 0, top);
+ return 0;
+ }
+
+
+ start_text_input();
+
+ return 1;
+}
+
+int smlua_func_stop_text_input(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "stop_text_input", 0, top);
+ return 0;
+ }
+
+
+ stop_text_input();
+
+ return 1;
+}
+
+int smlua_func_is_text_input_active(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "is_text_input_active", 0, top);
+ return 0;
+ }
+
+
+ lua_pushboolean(L, is_text_input_active());
+
+ return 1;
+}
+
/////////////////////////
// smlua_level_utils.h //
/////////////////////////
@@ -39046,6 +39091,9 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "get_current_gamepad_index", smlua_func_get_current_gamepad_index);
smlua_bind_function(L, "get_clipboard_text", smlua_func_get_clipboard_text);
smlua_bind_function(L, "set_clipboard_text", smlua_func_set_clipboard_text);
+ smlua_bind_function(L, "start_text_input", smlua_func_start_text_input);
+ smlua_bind_function(L, "stop_text_input", smlua_func_stop_text_input);
+ smlua_bind_function(L, "is_text_input_active", smlua_func_is_text_input_active);
// smlua_level_utils.h
smlua_bind_function(L, "smlua_level_util_change_area", smlua_func_smlua_level_util_change_area);
diff --git a/src/pc/lua/utils/smlua_input_utils.c b/src/pc/lua/utils/smlua_input_utils.c
index e3c46a877..85d9f6f94 100644
--- a/src/pc/lua/utils/smlua_input_utils.c
+++ b/src/pc/lua/utils/smlua_input_utils.c
@@ -8,6 +8,8 @@
#include "pc/mods/mods.h"
#include "pc/mods/mods_utils.h"
+bool gModHasInputFocus = false;
+
struct Gamepad gGamepads[MAX_GAMEPADS];
struct Key gKeyboard[SDL_NUM_SCANCODES];
@@ -16,11 +18,24 @@ u32 get_current_gamepad_index(void) {
}
const char* get_clipboard_text(void) {
- return wm_api->get_clipboard_text();
+ return gWindowApi->get_clipboard_text();
}
void set_clipboard_text(const char* text) {
- wm_api->set_clipboard_text(text);
+ gWindowApi->set_clipboard_text(text);
+}
+
+void start_text_input(void) {
+ gModHasInputFocus = true;
+ gWindowApi->start_text_input();
+}
+
+void stop_text_input(void) {
+ gModHasInputFocus = false;
+}
+
+bool is_text_input_active(void) {
+ return gWindowApi->is_text_input_active() && gModHasInputFocus;
}
void clear_gamepad_input_data(void) {
diff --git a/src/pc/lua/utils/smlua_input_utils.h b/src/pc/lua/utils/smlua_input_utils.h
index 963bb77d8..e83e08583 100644
--- a/src/pc/lua/utils/smlua_input_utils.h
+++ b/src/pc/lua/utils/smlua_input_utils.h
@@ -80,6 +80,8 @@ struct Key {
};
+extern bool gModHasInputFocus;
+
extern struct Gamepad gGamepads[MAX_GAMEPADS];
extern struct Key gKeyboard[SDL_NUM_SCANCODES];
@@ -89,6 +91,12 @@ u32 get_current_gamepad_index(void);
const char* get_clipboard_text(void);
/* |description|Sets the clipboard text|descriptionEnd| */
void set_clipboard_text(const char* text);
+/* |description|Starts text input and grabs input focus|descriptionEnd| */
+void start_text_input(void);
+/* |description|Stops text input and loses input focus|descriptionEnd| */
+void stop_text_input(void);
+/* |description|Checks if text input is active and if you have input focus|descriptionEnd| */
+bool is_text_input_active(void);
void clear_gamepad_input_data(void);
void controller_maps_load(const char* mapsPath, bool appendMaps);
#endif
\ No newline at end of file
diff --git a/src/pc/network/network.c b/src/pc/network/network.c
index 598706ef7..033746b33 100644
--- a/src/pc/network/network.c
+++ b/src/pc/network/network.c
@@ -145,6 +145,8 @@ bool network_init(enum NetworkType inNetworkType, bool reconnecting) {
gPauseMenuHidden = false;
+ gModHasInputFocus = false;
+
// initialize the network system
gNetworkSentJoin = false;
int rc = gNetworkSystem->initialize(inNetworkType, reconnecting);
@@ -774,6 +776,7 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
vec3f_set(gFirstPersonCamera.offset, 0, 0, 0);
first_person_reset();
+ gModHasInputFocus = false;
clear_gamepad_input_data();
le_shutdown();