diff --git a/src/console.c b/src/console.c
index 4533dfca47864165e9c67391f48767355fef0f4e..29510435ae445396fd9bf3de25bec87d48dc5c09 100644
--- a/src/console.c
+++ b/src/console.c
@@ -34,6 +34,7 @@
 #include "m_menu.h"
 #include "filesrch.h"
 #include "m_misc.h"
+#include "lua_libs.h"
 
 #ifdef _WINDOWS
 #include "win32/win_main.h"
@@ -925,7 +926,7 @@ boolean CON_PreResponder(event_t *ev)
 {
 	if (ev->type == ev_keydown && shiftdown == 1 && ev->key == KEY_ESCAPE)
 	{
-		I_SetTextInputMode(con_destlines == 0); // inverse, since this is changed next tic.
+		I_SetTextInputMode(con_destlines == 0 ? true : textinputmodeenabledbylua); // inverse, since this is changed next tic.
 		consoletoggle = true;
 		return true;
 	}
@@ -973,7 +974,7 @@ boolean CON_Responder(event_t *ev)
 			if (con_destlines == 0 && I_GetTextInputMode())
 				return false; // some other component is holding keyboard input, don't hijack it!
 
-			I_SetTextInputMode(con_destlines == 0); // inverse, since this is changed next tic.
+			I_SetTextInputMode(con_destlines == 0 ? true : textinputmodeenabledbylua); // inverse, since this is changed next tic.
 			consoletoggle = true;
 			return true;
 		}
@@ -993,7 +994,7 @@ boolean CON_Responder(event_t *ev)
 		// escape key toggle off console
 		if (key == KEY_ESCAPE)
 		{
-			I_SetTextInputMode(false);
+			I_SetTextInputMode(textinputmodeenabledbylua);
 			consoletoggle = true;
 			return true;
 		}
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 91a0d352be532674df980200bf308330186978b0..e8796286660188ba70eef269de751a1f0437bb1e 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -52,6 +52,7 @@
 #include "lua_hud.h"
 #include "lua_hudlib_drawlist.h"
 #include "lua_hook.h"
+#include "lua_libs.h"
 
 // coords are scaled
 #define HU_INPUTX 0
@@ -1016,7 +1017,7 @@ static void HU_sendChatMessage(void)
 void HU_clearChatChars(void)
 {
 	memset(w_chat, '\0', sizeof(w_chat));
-	I_SetTextInputMode(false);
+	I_SetTextInputMode(textinputmodeenabledbylua);
 	chat_on = false;
 	c_input = 0;
 
@@ -1153,7 +1154,7 @@ boolean HU_Responder(event_t *ev)
 			if (!CHAT_MUTE)
 				HU_sendChatMessage();
 
-			I_SetTextInputMode(false);
+			I_SetTextInputMode(textinputmodeenabledbylua);
 			chat_on = false;
 			c_input = 0; // reset input cursor
 			chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
@@ -1164,7 +1165,7 @@ boolean HU_Responder(event_t *ev)
 			|| c == gamecontrol[GC_TEAMKEY][0] || c == gamecontrol[GC_TEAMKEY][1])
 			&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
 		{
-			I_SetTextInputMode(false);
+			I_SetTextInputMode(textinputmodeenabledbylua);
 			chat_on = false;
 			c_input = 0; // reset input cursor
 			I_UpdateMouseGrab();
diff --git a/src/lua_inputlib.c b/src/lua_inputlib.c
index eb9fe7dc55a5947b6d5594f01fcda962ccfa0178..d4e327c7bba3aae6a5b13bf7265104307613df05 100644
--- a/src/lua_inputlib.c
+++ b/src/lua_inputlib.c
@@ -10,16 +10,19 @@
 /// \brief input library for Lua scripting
 
 #include "doomdef.h"
+#include "doomstat.h"
 #include "fastcmp.h"
 #include "g_input.h"
 #include "g_game.h"
 #include "hu_stuff.h"
 #include "i_system.h"
+#include "console.h"
 
 #include "lua_script.h"
 #include "lua_libs.h"
 
 boolean mousegrabbedbylua = true;
+boolean textinputmodeenabledbylua = false;
 boolean ignoregameinputs = false;
 
 ///////////////
@@ -131,13 +134,15 @@ static int lib_getCursorPosition(lua_State *L)
 
 static int lib_setTextInputMode(lua_State *L)
 {
-	I_SetTextInputMode(luaL_checkboolean(L, 1));
+	textinputmodeenabledbylua = luaL_checkboolean(L, 1);
+	if (!(menuactive || CON_Ready() || chat_on))
+		I_SetTextInputMode(textinputmodeenabledbylua);
 	return 0;
 }
 
 static int lib_getTextInputMode(lua_State *L)
 {
-	lua_pushinteger(L, I_GetTextInputMode());
+	lua_pushinteger(L, textinputmodeenabledbylua);
 	return 1;
 }
 
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 592f46df560435b085b9fe025a263d6b1317e042..99a395c95eb3806644243d9e07af7e30fe919610 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -13,6 +13,7 @@
 extern lua_State *gL;
 
 extern boolean mousegrabbedbylua;
+extern boolean textinputmodeenabledbylua;
 extern boolean ignoregameinputs;
 
 #define MUTABLE_TAGS
diff --git a/src/m_menu.c b/src/m_menu.c
index be1b421f75c29a87c98b9e0ab3b97c6566f13038..8ffa05fff6b3a9a4ff6bda1f9837d8338014f4bd 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -48,6 +48,7 @@
 #include "p_setup.h"
 #include "f_finale.h"
 #include "lua_hook.h"
+#include "lua_libs.h"
 
 #ifdef HWRENDER
 #include "hardware/hw_main.h"
@@ -3793,6 +3794,7 @@ void M_ClearMenus(boolean callexitmenufunc)
 	hidetitlemap = false;
 
 	I_UpdateMouseGrab();
+	I_SetTextInputMode(textinputmodeenabledbylua);
 }
 
 //
diff --git a/src/netcode/d_clisrv.c b/src/netcode/d_clisrv.c
index 1cd26cd4f32ca9e239fd3f26a728e54629cc8ed2..92a4cd784e3cfc409cbdf2d78fd7ab4d090999a5 100644
--- a/src/netcode/d_clisrv.c
+++ b/src/netcode/d_clisrv.c
@@ -641,6 +641,7 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
 void D_QuitNetGame(void)
 {
 	mousegrabbedbylua = true;
+	textinputmodeenabledbylua = false;
 	I_UpdateMouseGrab();
 
 	if (!netgame || !netbuffer)
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 2d1029ed09e50dd3b1834e6f421868aef8d752c8..a1ff94480ecbfbfe37fa5337831c8245790cf556 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -1858,7 +1858,7 @@ void I_StartupGraphics(void)
 		SDLdoGrabMouse();
 
 	// disable text input right off the bat, since we don't need it at the start.
-	I_SetTextInputMode(false);
+	I_SetTextInputMode(textinputmodeenabledbylua);
 
 	graphics_started = true;
 }