diff --git a/src/client.cpp b/src/client.cpp
index 30280369f81f539c56ae5a56f5b858da0d093819..accff4b01c024d69567adaae08425ce771b26f80 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -2538,16 +2538,14 @@ void Client::typeChatMessage(const std::wstring &message)
 	// Show locally
 	if (message[0] == L'/')
 	{
-		m_chat_queue.push_back(
-				(std::wstring)L"issued command: "+message);
+		m_chat_queue.push_back((std::wstring)L"issued command: " + message);
 	}
 	else
 	{
 		LocalPlayer *player = m_env.getLocalPlayer();
 		assert(player != NULL);
 		std::wstring name = narrow_to_wide(player->getName());
-		m_chat_queue.push_back(
-				(std::wstring)L"<"+name+L"> "+message);
+		m_chat_queue.push_back((std::wstring)L"<" + name + L"> " + message);
 	}
 }
 
@@ -2732,6 +2730,34 @@ float Client::getAvgRate(void)
 			m_con.getLocalStat(con::AVG_DL_RATE));
 }
 
+void Client::makeScreenshot(IrrlichtDevice *device)
+{
+	irr::video::IVideoDriver *driver = device->getVideoDriver();
+	irr::video::IImage* const raw_image = driver->createScreenShot();
+	if (raw_image) {
+		irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8, 
+			raw_image->getDimension());
+
+		if (image) {
+			raw_image->copyTo(image);
+			irr::c8 filename[256];
+			snprintf(filename, sizeof(filename), "%s" DIR_DELIM "screenshot_%u.png",
+				 g_settings->get("screenshot_path").c_str(),
+				 device->getTimer()->getRealTime());
+			std::stringstream sstr;
+			if (driver->writeImageToFile(image, filename)) {
+				sstr << "Saved screenshot to '" << filename << "'";
+			} else {
+				sstr << "Failed to save screenshot '" << filename << "'";
+			}
+			m_chat_queue.push_back(narrow_to_wide(sstr.str()));
+			infostream << sstr << std::endl;
+			image->drop();
+		}
+		raw_image->drop();
+	}
+}
+
 // IGameDef interface
 // Under envlock
 IItemDefManager* Client::getItemDefManager()
diff --git a/src/client.h b/src/client.h
index 8bffbd1db9e1c0ada2ab5bb040c6dc95b90da706..e3b425a32d0d3bdf2c8b42dfa53ccb44ceebc88a 100644
--- a/src/client.h
+++ b/src/client.h
@@ -464,6 +464,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
 
 	LocalClientState getState() { return m_state; }
 
+	void makeScreenshot(IrrlichtDevice *device);
+
 private:
 
 	// Virtual methods from con::PeerHandler
diff --git a/src/game.cpp b/src/game.cpp
index bae946f28eaa70a3751901b5e25dd18bc5fc5fb2..45b879ff23517dd898ffafcb7687e3ebd5790368 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -933,12 +933,12 @@ bool nodePlacementPrediction(Client &client,
 static inline void create_formspec_menu(GUIFormSpecMenu** cur_formspec,
 		InventoryManager *invmgr, IGameDef *gamedef,
 		IWritableTextureSource* tsrc, IrrlichtDevice * device,
-		IFormSource* fs_src, TextDest* txt_dest
+		IFormSource* fs_src, TextDest* txt_dest, Client* client
 		) {
 
 	if (*cur_formspec == 0) {
 		*cur_formspec = new GUIFormSpecMenu(device, guiroot, -1, &g_menumgr,
-				invmgr, gamedef, tsrc, fs_src, txt_dest, cur_formspec );
+				invmgr, gamedef, tsrc, fs_src, txt_dest, cur_formspec, client);
 		(*cur_formspec)->doPause = false;
 		(*cur_formspec)->drop();
 	}
@@ -972,7 +972,7 @@ static void show_chat_menu(GUIFormSpecMenu** cur_formspec,
 	FormspecFormSource* fs_src = new FormspecFormSource(formspec);
 	LocalFormspecHandler* txt_dst = new LocalFormspecHandler("MT_CHAT_MENU", client);
 
-	create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst);
+	create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device, fs_src, txt_dst, NULL);
 }
 
 static void show_deathscreen(GUIFormSpecMenu** cur_formspec,
@@ -993,7 +993,7 @@ static void show_deathscreen(GUIFormSpecMenu** cur_formspec,
 	FormspecFormSource* fs_src = new FormspecFormSource(formspec);
 	LocalFormspecHandler* txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
 
-	create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device,  fs_src, txt_dst);
+	create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device,  fs_src, txt_dst, NULL);
 }
 
 /******************************************************************************/
@@ -1060,7 +1060,7 @@ static void show_pause_menu(GUIFormSpecMenu** cur_formspec,
 	FormspecFormSource* fs_src = new FormspecFormSource(os.str());
 	LocalFormspecHandler* txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
 
-	create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device,  fs_src, txt_dst);
+	create_formspec_menu(cur_formspec, invmgr, gamedef, tsrc, device,  fs_src, txt_dst, NULL);
 
 	(*cur_formspec)->doPause = true;
 }
@@ -1966,7 +1966,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 			PlayerInventoryFormSource* fs_src = new PlayerInventoryFormSource(&client);
 			TextDest* txt_dst = new TextDestPlayerInventory(&client);
 
-			create_formspec_menu(&current_formspec, &client, gamedef, tsrc, device, fs_src, txt_dst);
+			create_formspec_menu(&current_formspec, &client, gamedef, tsrc, device, fs_src, txt_dst, &client);
 
 			InventoryLocation inventoryloc;
 			inventoryloc.setCurrentPlayer();
@@ -2070,30 +2070,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 		}
 		else if(input->wasKeyDown(getKeySetting("keymap_screenshot")))
 		{
-			irr::video::IImage* const raw_image = driver->createScreenShot();
-			if (raw_image) {
-				irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8, 
-					raw_image->getDimension());
-
-				if (image) {
-					raw_image->copyTo(image);
-					irr::c8 filename[256];
-					snprintf(filename, sizeof(filename), "%s" DIR_DELIM "screenshot_%u.png",
-						 g_settings->get("screenshot_path").c_str(),
-						 device->getTimer()->getRealTime());
-					if (driver->writeImageToFile(image, filename)) {
-						std::wstringstream sstr;
-						sstr << "Saved screenshot to '" << filename << "'";
-						infostream << "Saved screenshot to '" << filename << "'" << std::endl;
-						statustext = sstr.str();
-						statustext_time = 0;
-					} else {
-						infostream << "Failed to save screenshot '" << filename << "'" << std::endl;
-					}
-					image->drop();
-				}
-				raw_image->drop();
-			}
+			client.makeScreenshot(device);
 		}
 		else if(input->wasKeyDown(getKeySetting("keymap_toggle_hud")))
 		{
@@ -2483,7 +2460,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 							new TextDestPlayerInventory(&client,*(event.show_formspec.formname));
 
 					create_formspec_menu(&current_formspec, &client, gamedef,
-							tsrc, device, fs_src, txt_dst);
+							tsrc, device, fs_src, txt_dst, &client);
 
 					delete(event.show_formspec.formspec);
 					delete(event.show_formspec.formname);
@@ -3033,7 +3010,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
 					TextDest* txt_dst = new TextDestNodeMetadata(nodepos, &client);
 
 					create_formspec_menu(&current_formspec, &client, gamedef,
-							tsrc, device, fs_src, txt_dst);
+							tsrc, device, fs_src, txt_dst, &client);
 
 					current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
 				}
diff --git a/src/guiEngine.cpp b/src/guiEngine.cpp
index 03b2766d86ab4148fc04aab81a5ad2644fa72de1..e2f1a0aad516a0567c38300f097aab5b5c230a89 100644
--- a/src/guiEngine.cpp
+++ b/src/guiEngine.cpp
@@ -189,7 +189,7 @@ GUIEngine::GUIEngine(	irr::IrrlichtDevice* dev,
 			m_texture_source,
 			m_formspecgui,
 			m_buttonhandler,
-			NULL);
+			NULL, NULL);
 
 	m_menu->allowClose(false);
 	m_menu->lockSize(true,v2u32(800,600));
diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index d6ca12b707ef23e256de7e5b030bf805fa6cd086..3fdb5bd26e7397b4ca2bee4303f0177f7b8cda6d 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -49,6 +49,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "porting.h"
 #include "main.h"
 #include "settings.h"
+#include "client.h"
 
 #define MY_CHECKPOS(a,b)													\
 	if (v_pos.size() != 2) {												\
@@ -71,7 +72,7 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
 		gui::IGUIElement* parent, s32 id, IMenuManager *menumgr,
 		InventoryManager *invmgr, IGameDef *gamedef,
 		ISimpleTextureSource *tsrc, IFormSource* fsrc, TextDest* tdst,
-		GUIFormSpecMenu** ext_ptr) :
+		GUIFormSpecMenu** ext_ptr, Client* client) :
 	GUIModalMenu(dev->getGUIEnvironment(), parent, id, menumgr),
 	m_device(dev),
 	m_invmgr(invmgr),
@@ -88,7 +89,8 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
 	m_text_dst(tdst),
 	m_ext_ptr(ext_ptr),
 	m_font(dev->getGUIEnvironment()->getSkin()->getFont()),
-	m_formspec_version(0)
+	m_formspec_version(0),
+	m_client(client)
 #ifdef __ANDROID__
 	,m_JavaDialogFieldName(L"")
 #endif
@@ -2912,6 +2914,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 				m_text_dst->gotText(narrow_to_wide("MenuQuit"));
 			}
 			return true;
+		} else if (m_client != NULL && event.KeyInput.PressedDown &&
+			(kp == getKeySetting("keymap_screenshot"))) {
+				m_client->makeScreenshot(m_device);
 		}
 		if (event.KeyInput.PressedDown &&
 			(event.KeyInput.Key==KEY_RETURN ||
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 15bc628d17296f869b40145111cf9b7f30e03346..583cad4a27da64ba29a273d5d05ab2d3ad5d671d 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 class IGameDef;
 class InventoryManager;
 class ISimpleTextureSource;
+class Client;
 
 typedef enum {
 	f_Button,
@@ -209,7 +210,8 @@ class GUIFormSpecMenu : public GUIModalMenu
 			ISimpleTextureSource *tsrc,
 			IFormSource* fs_src,
 			TextDest* txt_dst,
-			GUIFormSpecMenu** ext_ptr
+			GUIFormSpecMenu** ext_ptr,
+			Client* client
 			);
 
 	~GUIFormSpecMenu();
@@ -294,6 +296,7 @@ class GUIFormSpecMenu : public GUIModalMenu
 	InventoryManager *m_invmgr;
 	IGameDef *m_gamedef;
 	ISimpleTextureSource *m_tsrc;
+	Client *m_client;
 
 	std::string m_formspec_string;
 	InventoryLocation m_current_inventory_location;