diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index 049341c148fab9cf3353d26a1b5096a657c1bb65..79497dca1814ff35d59d4aab0504962fd2af1332 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "util/string.h"
 #include "util/numeric.h"
 #include "filesys.h"
+#include "gettime.h"
 
 #include "gettext.h"
 
@@ -81,6 +82,10 @@ GUIFormSpecMenu::GUIFormSpecMenu(irr::IrrlichtDevice* dev,
 	m_selected_item(NULL),
 	m_selected_amount(0),
 	m_selected_dragging(false),
+	m_listbox_click_fname(),
+	m_listbox_click_index(-1),
+	m_listbox_click_time(0),
+	m_listbox_doubleclick(false),
 	m_tooltip_element(NULL),
 	m_allowclose(true),
 	m_use_gettext(false),
@@ -143,6 +148,42 @@ int GUIFormSpecMenu::getListboxIndex(std::string listboxname) {
 	return -1;
 }
 
+bool GUIFormSpecMenu::checkListboxClick(std::wstring wlistboxname,
+		int eventtype)
+{
+	// WARNING: BLACK IRRLICHT MAGIC
+	// Used to fix Irrlicht's subpar reporting of single clicks and double
+	// clicks in listboxes (gui::EGET_LISTBOX_CHANGED,
+	// gui::EGET_LISTBOX_SELECTED_AGAIN):
+	// 1. IGUIListBox::setSelected() is counted as a click.
+	//    Including the initial setSelected() done by parseTextList().
+	// 2. Clicking on a the selected item and then dragging for less
+	//    than 500ms is counted as a doubleclick, no matter when the
+	//    item was previously selected (e.g. more than 500ms ago)
+
+	// So when Irrlicht reports a doubleclick, we need to check
+	// for ourselves if really was a doubleclick. Or just a fake.
+
+	for(unsigned int i=0; i < m_listboxes.size(); i++) {
+		std::wstring name(m_listboxes[i].first.fname.c_str());
+		int selected = m_listboxes[i].second->getSelected();
+		if (name == wlistboxname && selected >= 0) {
+			u32 now = getTimeMs();
+			bool doubleclick =
+				(eventtype == gui::EGET_LISTBOX_SELECTED_AGAIN)
+				&& (name == m_listbox_click_fname)
+				&& (selected == m_listbox_click_index)
+				&& (m_listbox_click_time >= now - 500);
+			m_listbox_click_fname = name;
+			m_listbox_click_index = selected;
+			m_listbox_click_time = now;
+			m_listbox_doubleclick = doubleclick;
+			return true;
+		}
+	}
+	return false;
+}
+
 std::vector<std::string> split(const std::string &s, char delim) {
 	std::vector<std::string> tokens;
 
@@ -1920,7 +1961,7 @@ ItemStack GUIFormSpecMenu::verifySelectedItem()
 	return ItemStack();
 }
 
-void GUIFormSpecMenu::acceptInput(int eventtype)
+void GUIFormSpecMenu::acceptInput()
 {
 	if(m_text_dst)
 	{
@@ -1957,11 +1998,12 @@ void GUIFormSpecMenu::acceptInput(int eventtype)
 				}
 				else if(s.ftype == f_ListBox) {
 					std::stringstream ss;
-					if (eventtype == gui::EGET_LISTBOX_CHANGED) {
-						ss << "CHG:";
+
+					if (m_listbox_doubleclick) {
+						ss << "DCL:";
 					}
 					else {
-						ss << "DCL:";
+						ss << "CHG:";
 					}
 					ss << (getListboxIndex(wide_to_narrow(s.fname.c_str()))+1);
 					fields[wide_to_narrow(s.fname.c_str())] = ss.str();
@@ -2459,12 +2501,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 				for(u32 i=0; i<m_fields.size(); i++)
 				{
 					FieldSpec &s = m_fields[i];
-					// if its a button, set the send field so
-					// lua knows which button was pressed
-					if ((s.ftype == f_ListBox) && (s.fid == current_id))
+					// if its a listbox, set the send field so
+					// lua knows which listbox was changed
+					// checkListboxClick() is black magic
+					// for properly handling double clicks
+					if ((s.ftype == f_ListBox) && (s.fid == current_id)
+							&& checkListboxClick(s.fname,
+								event.GUIEvent.EventType))
 					{
 						s.send = true;
-						acceptInput(event.GUIEvent.EventType);
+						acceptInput();
 						s.send=false;
 						// Restore focus to the full form
 						Environment->setFocus(this);
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 84124afc3fa60272a1752855a3594725e3584539..28f11d2e70390be6f000c227b7f2f5ba3b3c4d68 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -228,9 +228,9 @@ class GUIFormSpecMenu : public GUIModalMenu
 	void updateSelectedItem();
 	ItemStack verifySelectedItem();
 
-	void acceptInput(int evttype=-1);
+	void acceptInput();
 	bool OnEvent(const SEvent& event);
-	
+
 	int getListboxIndex(std::string listboxname);
 
 protected:
@@ -272,6 +272,12 @@ class GUIFormSpecMenu : public GUIModalMenu
 	ItemStack m_selected_content_guess;
 	InventoryLocation m_selected_content_guess_inventory;
 
+	// WARNING: BLACK IRRLICHT MAGIC, see checkListboxClick()
+	std::wstring m_listbox_click_fname;
+	int m_listbox_click_index;
+	u32 m_listbox_click_time;
+	bool m_listbox_doubleclick;
+
 	v2s32 m_pointer;
 	gui::IGUIStaticText *m_tooltip_element;
 
@@ -301,6 +307,10 @@ class GUIFormSpecMenu : public GUIModalMenu
 
 	fs_key_pendig current_keys_pending;
 
+	// Determine whether listbox click was double click
+	// (Using some black Irrlicht magic)
+	bool checkListboxClick(std::wstring wlistboxname, int eventtype);
+
 	void parseElement(parserData* data,std::string element);
 
 	void parseSize(parserData* data,std::string element);