diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index b0c1b41a3682e39758f4fcb11d0b6f1544a56052..94fc78b2e93777a901ac58dccbaab24069c72357 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -891,8 +891,10 @@ minetest.get_inventory(location) -> InvRef
 minetest.create_detached_inventory(name, callbacks) -> InvRef
 ^ callbacks: See "Detached inventory callbacks"
 ^ Creates a detached inventory. If it already exists, it is cleared.
-minetest.show_formspec(playername, formspec)
+minetest.show_formspec(playername, formname, formspec)
 ^ playername: name of player to show formspec
+^ formname: name passed to on_player_receive_fields callbacks
+^           should follow "modname:<whatever>" naming convention
 ^ formspec: formspec to display
 
 Item handling:
diff --git a/src/client.cpp b/src/client.cpp
index 216d86cd412c6d0ffa0e9ae3cd1d8593614887e5..9969ef538060bd20f30087ead7d1ee9117ae6a2e 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1906,12 +1906,14 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 		std::istringstream is(datastring, std::ios_base::binary);
 
 		std::string formspec = deSerializeLongString(is);
+		std::string formname = deSerializeString(is);
 
 		ClientEvent event;
 		event.type = CE_SHOW_FORMSPEC;
 		// pointer is required as event is a struct only!
 		// adding a std:string to a struct isn't possible
 		event.show_formspec.formspec = new std::string(formspec);
+		event.show_formspec.formname = new std::string(formname);
 		m_client_event_queue.push_back(event);
 	}
 	else
diff --git a/src/client.h b/src/client.h
index e46da6b0ec840fa168f7ab7f3e697bd289a5ebd3..7052e840ada92c0c6fd71a1a3823de4ab02dc878 100644
--- a/src/client.h
+++ b/src/client.h
@@ -179,6 +179,7 @@ struct ClientEvent
 		} deathscreen;
 		struct{
 			std::string* formspec;
+			std::string* formname;
 		} show_formspec;
 		struct{
 		} textures_updated;
diff --git a/src/clientserver.h b/src/clientserver.h
index bb7e1181efafbe16b688530de51b3962af922127..52b9dc7b044c6f7073261895762fdc8bad24a93d 100644
--- a/src/clientserver.h
+++ b/src/clientserver.h
@@ -359,8 +359,10 @@ enum ToClientCommand
 	TOCLIENT_SHOW_FORMSPEC = 0x44,
 	/*
 		[0] u16 command
-		u16 len
+		u32 len
 		u8[len] formspec
+		u16 len
+		u8[len] formname
 	*/
 };
 
diff --git a/src/game.cpp b/src/game.cpp
index ca992c05618cd00f898e71050b58b0727a7a68a5..c8f1d218786a1c50a17ec19f5db48d5e0f0f0ee1 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -118,13 +118,20 @@ struct TextDestPlayerInventory : public TextDest
 	TextDestPlayerInventory(Client *client)
 	{
 		m_client = client;
+		m_formname = "";
+	}
+	TextDestPlayerInventory(Client *client, std::string formname)
+	{
+		m_client = client;
+		m_formname = formname;
 	}
 	void gotText(std::map<std::string, std::string> fields)
 	{
-		m_client->sendInventoryFields("", fields);
+		m_client->sendInventoryFields(m_formname, fields);
 	}
 
 	Client *m_client;
+	std::string m_formname;
 };
 
 /* Respawn menu callback */
@@ -2154,6 +2161,7 @@ void the_game(
 										&g_menumgr,
 										&client, gamedef);
 						menu->setFormSource(current_formspec);
+						menu->setTextDest(new TextDestPlayerInventory(&client,*(event.show_formspec.formname)));
 						menu->drop();
 					}
 					else
@@ -2162,6 +2170,7 @@ void the_game(
 						current_formspec->setForm(*(event.show_formspec.formspec));
 					}
 					delete(event.show_formspec.formspec);
+					delete(event.show_formspec.formname);
 				}
 				else if(event.type == CE_TEXTURES_UPDATED)
 				{
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 60e5b55f4f998c32af4399975e23f2d036d76261..8e4a43266c645733a8ef6572fbfaacff8eb44be1 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -4921,13 +4921,14 @@ static int l_create_detached_inventory_raw(lua_State *L)
 	return 1;
 }
 
-// create_detached_formspec_raw(name)
+// show_formspec(playername,formname,formspec)
 static int l_show_formspec(lua_State *L)
 {
 	const char *playername = luaL_checkstring(L, 1);
-	const char *formspec = luaL_checkstring(L, 2);
+	const char *formname = luaL_checkstring(L, 2);
+	const char *formspec = luaL_checkstring(L, 3);
 
-	if(get_server(L)->showFormspec(playername,formspec))
+	if(get_server(L)->showFormspec(playername,formspec,formname))
 	{
 		lua_pushboolean(L, true);
 	}else{
diff --git a/src/server.cpp b/src/server.cpp
index f4b5ee872a80c5848ee86463039fe6fc4caca026..f635bc676c9a84f2ba4d4dd6229da58c298539c7 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3638,7 +3638,7 @@ void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
 	// Send as reliable
 	m_con.Send(peer_id, 0, data, true);
 }
-void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec)
+void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname)
 {
 	DSTACK(__FUNCTION_NAME);
 
@@ -3649,6 +3649,7 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec)
 	writeU16(buf, TOCLIENT_SHOW_FORMSPEC);
 	os.write((char*)buf, 2);
 	os<<serializeLongString(formspec);
+	os<<serializeString(formname);
 
 	// Make data buffer
 	std::string s = os.str();
@@ -4596,7 +4597,7 @@ void Server::notifyPlayer(const char *name, const std::wstring msg)
 	SendChatMessage(player->peer_id, std::wstring(L"Server: -!- ")+msg);
 }
 
-bool Server::showFormspec(const char *playername, const std::string &formspec)
+bool Server::showFormspec(const char *playername, const std::string &formspec, const std::string &formname)
 {
 	Player *player = m_env->getPlayer(playername);
 
@@ -4606,7 +4607,7 @@ bool Server::showFormspec(const char *playername, const std::string &formspec)
 		return false;
 	}
 
-	SendShowFormspecMessage(player->peer_id,formspec);
+	SendShowFormspecMessage(player->peer_id, formspec, formname);
 	return true;
 }
 
diff --git a/src/server.h b/src/server.h
index 19c29cbd711353518a832ae7815c8098e833027a..43beb167ae0a5b12c36db1b10763ec36443dfbc6 100644
--- a/src/server.h
+++ b/src/server.h
@@ -583,7 +583,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 		m_async_fatal_error.set(error);
 	}
 
-	bool showFormspec(const char *name, const std::string &formspec);
+	bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
 private:
 
 	// con::PeerHandler implementation.
@@ -621,7 +621,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
 	void SendMovePlayer(u16 peer_id);
 	void SendPlayerPrivileges(u16 peer_id);
 	void SendPlayerInventoryFormspec(u16 peer_id);
-	void SendShowFormspecMessage(u16 peer_id, const std::string formspec);
+	void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
 	/*
 		Send a node removal/addition event to all clients except ignore_id.
 		Additionally, if far_players!=NULL, players further away than