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();