diff --git a/src/android/i_system.c b/src/android/i_system.c
index 58fca7c1943448ff81ede9a67854f3791c93bc00..752e9f6c6bb4138caaf17004cbcc0fcaa6b66cee 100644
--- a/src/android/i_system.c
+++ b/src/android/i_system.c
@@ -245,6 +245,8 @@ void I_GetJoystick2Events(void){}
 
 void I_GetMouseEvents(void){}
 
+void I_UpdateMouseGrab(void){}
+
 char *I_GetEnv(const char *name)
 {
   LOGW("I_GetEnv() called?!");
diff --git a/src/console.c b/src/console.c
index 6549370eeda227a1dc48b0ff062261115277f3cd..01d1ddaa25f1b275b3e5e27ab3d3389736af98c9 100644
--- a/src/console.c
+++ b/src/console.c
@@ -592,6 +592,8 @@ void CON_ToggleOff(void)
 	CON_ClearHUD();
 	con_forcepic = 0;
 	con_clipviewtop = -1; // remove console clipping of view
+
+	I_UpdateMouseGrab();
 }
 
 boolean CON_Ready(void)
@@ -616,6 +618,7 @@ void CON_Ticker(void)
 		consoletoggle = false;
 		con_destlines = 0;
 		CON_ClearHUD();
+		I_UpdateMouseGrab();
 	}
 
 	// console key was pushed
@@ -628,6 +631,7 @@ void CON_Ticker(void)
 		{
 			con_destlines = 0;
 			CON_ClearHUD();
+			I_UpdateMouseGrab();
 		}
 		else
 			CON_ChangeHeight();
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 28843c0d7be6dd09ee3c60531223f97e2b34a139..0cd0ae20a03db3852b6bc9339ca0661d9534d09e 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -2203,6 +2203,8 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
 		else
 			S_ResumeAudio();
 	}
+
+	I_UpdateMouseGrab();
 }
 
 // Command for stuck characters in netgames, griefing, etc.
diff --git a/src/dehacked.c b/src/dehacked.c
index c9e10c06495b41f9c11a682623f47d91fe58ec69..78be8b0b3cd7be63a0dcf8d5ae8ee851570ea375 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -4539,11 +4539,13 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile)
 		if (introchanged)
 		{
 			menuactive = false;
+			I_UpdateMouseGrab();
 			COM_BufAddText("playintro");
 		}
 		else if (titlechanged)
 		{
 			menuactive = false;
+			I_UpdateMouseGrab();
 			COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed
 		}
 	}
diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c
index a3fe3077c2a46f6956a5723eb1de40127da7e798..5c0f7eb99ed6ab0d41fc93bcfd87fc89ab8d044b 100644
--- a/src/dummy/i_system.c
+++ b/src/dummy/i_system.c
@@ -150,6 +150,8 @@ void I_GetJoystick2Events(void){}
 
 void I_GetMouseEvents(void){}
 
+void I_UpdateMouseGrab(void){}
+
 char *I_GetEnv(const char *name)
 {
 	(void)name;
diff --git a/src/g_game.c b/src/g_game.c
index e4caa3a36aa4c373880985ade533bf1b50def01a..354d75e82e09d007ed9b5d234a52c1e568f6b1e6 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -1832,6 +1832,7 @@ void G_DoLoadLevel(boolean resetplayer)
 		titlemapinaction = TITLEMAP_OFF;
 
 	G_SetGamestate(GS_LEVEL);
+	I_UpdateMouseGrab();
 
 	for (i = 0; i < MAXPLAYERS; i++)
 	{
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 07eb5d24e95a2fe3f5d630b51510ac210adcf703..772d1cd587c425da163d1ea57a130e94245a9fd2 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -1173,6 +1173,8 @@ void HU_clearChatChars(void)
 		w_chat[i] = 0; // reset this.
 	chat_on = false;
 	c_input = 0;
+
+	I_UpdateMouseGrab();
 }
 
 #ifndef NONET
@@ -1323,6 +1325,7 @@ boolean HU_Responder(event_t *ev)
 			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. :)
+			I_UpdateMouseGrab();
 		}
 		else if (c == KEY_ESCAPE
 			|| ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1]
@@ -1331,6 +1334,7 @@ boolean HU_Responder(event_t *ev)
 		{
 			chat_on = false;
 			c_input = 0; // reset input cursor
+			I_UpdateMouseGrab();
 		}
 		else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
 		{
diff --git a/src/i_system.h b/src/i_system.h
index 2532ba0ee3827f5d089bfced6ea84852e242f814..a60b56310dcc4cfe651dcd53677c732a5cb7ceca 100644
--- a/src/i_system.h
+++ b/src/i_system.h
@@ -288,6 +288,10 @@ void I_GetJoystick2Events(void);
 */
 void I_GetMouseEvents(void);
 
+/**	\brief Checks if the mouse needs to be grabbed
+*/
+void I_UpdateMouseGrab(void);
+
 char *I_GetEnv(const char *name);
 
 INT32 I_PutEnv(char *variable);
diff --git a/src/m_menu.c b/src/m_menu.c
index ae00c80628eaabffc2bc400efca1bad4329f15f4..1a3c43b75506d244dd0d4cf1b55e54cc5d966a63 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -2867,6 +2867,7 @@ static void M_GoBack(INT32 choice)
 
 			menuactive = false;
 			wipetypepre = menupres[M_GetYoungestChildMenu()].exitwipe;
+			I_UpdateMouseGrab();
 			D_StartTitle();
 		}
 		else
@@ -3592,6 +3593,8 @@ void M_ClearMenus(boolean callexitmenufunc)
 		currentMenu = &MainDef; // Not like it matters
 	menuactive = false;
 	hidetitlemap = false;
+
+	I_UpdateMouseGrab();
 }
 
 //
diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c
index 645b65e846ce814bd4c48b2aaf76dd2f1791317b..553ce36767a2969479bff37079efb3f18fe51ec5 100644
--- a/src/sdl/i_video.c
+++ b/src/sdl/i_video.c
@@ -388,6 +388,14 @@ void SDLforceUngrabMouse(void)
 	}
 }
 
+void I_UpdateMouseGrab(void)
+{
+	if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL
+	&& SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window
+	&& !IGNORE_MOUSE)
+		SDLdoGrabMouse();
+}
+
 static void VID_Command_NumModes_f (void)
 {
 	CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes());
diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c
index c9fdb1c9742fa87a803aed9e88fb1578aceac904..42733c30909897d2437387dbe3b6365a096b40d8 100644
--- a/src/win32/win_sys.c
+++ b/src/win32/win_sys.c
@@ -1354,6 +1354,8 @@ getBufferedData:
 	}
 }
 
+void I_UpdateMouseGrab(void) {}
+
 // ===========================================================================================
 //                                                                       DIRECT INPUT JOYSTICK
 // ===========================================================================================