diff --git a/src/game.cpp b/src/game.cpp
index 5e4f4cacf2ec08ba7d281a38520f3df8a4203b55..f6d59e4e38ddce7b7f36e171ea91481e297d7a4d 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2569,7 +2569,17 @@ void Game::processUserInput(VolatileRunFlags *flags,
 			|| noMenuActive() == false
 			|| guienv->hasFocus(gui_chat_console)) {
 		input->clear();
+#ifdef HAVE_TOUCHSCREENGUI
+		g_touchscreengui->Hide();
+#endif
 	}
+#ifdef HAVE_TOUCHSCREENGUI
+	else if (g_touchscreengui) {
+		/* on touchscreengui step may generate own input events which ain't
+		 * what we want in case we just did clear them */
+		g_touchscreengui->step(dtime);
+	}
+#endif
 
 	if (!guienv->hasFocus(gui_chat_console) && gui_chat_console->isOpen()) {
 		gui_chat_console->closeConsoleAtOnce();
@@ -2578,13 +2588,6 @@ void Game::processUserInput(VolatileRunFlags *flags,
 	// Input handler step() (used by the random input generator)
 	input->step(dtime);
 
-#ifdef HAVE_TOUCHSCREENGUI
-
-	if (g_touchscreengui) {
-		g_touchscreengui->step(dtime);
-	}
-
-#endif
 #ifdef __ANDROID__
 
 	if (current_formspec != 0)
diff --git a/src/touchscreengui.cpp b/src/touchscreengui.cpp
index e4f785f60d4f4284893621e714cf328e3e22de36..f0ad002d6e11680b04a25b7ffb4d355f8a58ea67 100644
--- a/src/touchscreengui.cpp
+++ b/src/touchscreengui.cpp
@@ -417,6 +417,57 @@ void TouchScreenGUI::ButtonEvent(touch_gui_button_id button,
 	delete translated;
 }
 
+
+void TouchScreenGUI::handleReleaseEvent(int evt_id)
+{
+	touch_gui_button_id button = getButtonID(evt_id);
+
+	/* handle button events */
+	if (button != after_last_element_id) {
+		ButtonEvent(button, evt_id, false);
+	}
+	/* handle hud button events */
+	else if (isReleaseHUDButton(evt_id)) {
+		/* nothing to do here */
+	}
+	/* handle the point used for moving view */
+	else if (evt_id == m_move_id) {
+		m_move_id = -1;
+
+		/* if this pointer issued a mouse event issue symmetric release here */
+		if (m_move_sent_as_mouse_event) {
+			SEvent* translated = new SEvent;
+			memset(translated,0,sizeof(SEvent));
+			translated->EventType               = EET_MOUSE_INPUT_EVENT;
+			translated->MouseInput.X            = m_move_downlocation.X;
+			translated->MouseInput.Y            = m_move_downlocation.Y;
+			translated->MouseInput.Shift        = false;
+			translated->MouseInput.Control      = false;
+			translated->MouseInput.ButtonStates = 0;
+			translated->MouseInput.Event        = EMIE_LMOUSE_LEFT_UP;
+			m_receiver->OnEvent(*translated);
+			delete translated;
+		}
+		else {
+			/* do double tap detection */
+			doubleTapDetection();
+		}
+	}
+	else {
+		infostream
+			<< "TouchScreenGUI::translateEvent released unknown button: "
+			<< evt_id << std::endl;
+	}
+
+	for (std::vector<id_status>::iterator iter = m_known_ids.begin();
+			iter != m_known_ids.end(); ++iter) {
+		if (iter->id == evt_id) {
+			m_known_ids.erase(iter);
+			break;
+		}
+	}
+}
+
 void TouchScreenGUI::translateEvent(const SEvent &event)
 {
 	if (!m_visible) {
@@ -470,52 +521,7 @@ void TouchScreenGUI::translateEvent(const SEvent &event)
 	else if (event.TouchInput.Event == ETIE_LEFT_UP) {
 		verbosestream << "Up event for pointerid: " << event.TouchInput.ID << std::endl;
 
-		touch_gui_button_id button = getButtonID(event.TouchInput.ID);
-
-		/* handle button events */
-		if (button != after_last_element_id) {
-			ButtonEvent(button,event.TouchInput.ID,false);
-		}
-		/* handle hud button events */
-		else if (isReleaseHUDButton(event.TouchInput.ID)) {
-			/* nothing to do here */
-		}
-		/* handle the point used for moving view */
-		else if (event.TouchInput.ID == m_move_id) {
-			m_move_id = -1;
-
-			/* if this pointer issued a mouse event issue symmetric release here */
-			if (m_move_sent_as_mouse_event) {
-				SEvent* translated = new SEvent;
-				memset(translated,0,sizeof(SEvent));
-				translated->EventType               = EET_MOUSE_INPUT_EVENT;
-				translated->MouseInput.X            = m_move_downlocation.X;
-				translated->MouseInput.Y            = m_move_downlocation.Y;
-				translated->MouseInput.Shift        = false;
-				translated->MouseInput.Control      = false;
-				translated->MouseInput.ButtonStates = 0;
-				translated->MouseInput.Event        = EMIE_LMOUSE_LEFT_UP;
-				m_receiver->OnEvent(*translated);
-				delete translated;
-			}
-			else {
-				/* do double tap detection */
-				doubleTapDetection();
-			}
-		}
-		else {
-			infostream
-				<< "TouchScreenGUI::translateEvent released unknown button: "
-				<< event.TouchInput.ID << std::endl;
-		}
-
-		for (std::vector<id_status>::iterator iter = m_known_ids.begin();
-				iter != m_known_ids.end(); ++iter) {
-			if (iter->id == event.TouchInput.ID) {
-				m_known_ids.erase(iter);
-				break;
-			}
-		}
+		handleReleaseEvent(event.TouchInput.ID);
 	}
 	else {
 		assert(event.TouchInput.Event == ETIE_MOVED);
@@ -765,14 +771,27 @@ void TouchScreenGUI::Toggle(bool visible)
 			btn->guibutton->setVisible(visible);
 		}
 	}
+
+	/* clear all active buttons */
+	if (!visible) {
+		while (m_known_ids.size() > 0) {
+			handleReleaseEvent(m_known_ids.begin()->id);
+		}
+	}
 }
 
 void TouchScreenGUI::Hide()
 {
+	if (!m_visible)
+		return;
+
 	Toggle(false);
 }
 
 void TouchScreenGUI::Show()
 {
+	if (m_visible)
+		return;
+
 	Toggle(true);
 }
diff --git a/src/touchscreengui.h b/src/touchscreengui.h
index bb32317932acbd0c7efa3d0401f827f137b808e9..1e69a41e9cd13d82465f45a81f259026bb80733d 100644
--- a/src/touchscreengui.h
+++ b/src/touchscreengui.h
@@ -153,6 +153,9 @@ class TouchScreenGUI
 	/* handle double taps */
 	bool doubleTapDetection();
 
+	/* handle release event */
+	void handleReleaseEvent(int evt_id);
+
 	/* doubleclick detection variables */
 	struct key_event {
 		unsigned int down_time;